Reference
Conversations
Conversations: 12 operations (conversations.list, conversations.get, conversations.archive, conversations.drafts.list, conversations.drafts.approve, conversations.drafts.dismiss, conversations.mark_read, conversations.setter.hand, conversations.setter.resume, conversations.star, conversations.unarchive, conversations.unstar).
| Method | Path | Operation |
|---|---|---|
GET | /v1/conversations | conversations.list |
GET | /v1/conversations/{conversation_id} | conversations.get |
POST | /v1/conversations/{conversation_id}/archive | conversations.archive |
GET | /v1/conversations/{conversation_id}/drafts | conversations.drafts.list |
POST | /v1/conversations/{conversation_id}/drafts/{draft_id}/approve | conversations.drafts.approve |
POST | /v1/conversations/{conversation_id}/drafts/{draft_id}/dismiss | conversations.drafts.dismiss |
POST | /v1/conversations/{conversation_id}/read | conversations.mark_read |
POST | /v1/conversations/{conversation_id}/setter/hand | conversations.setter.hand |
POST | /v1/conversations/{conversation_id}/setter/resume | conversations.setter.resume |
POST | /v1/conversations/{conversation_id}/star | conversations.star |
POST | /v1/conversations/{conversation_id}/unarchive | conversations.unarchive |
POST | /v1/conversations/{conversation_id}/unstar | conversations.unstar |
conversations.list
GET/v1/conversations
List conversations, newest activity first.
Ordered by last_message_at (threads with no message last), then id. Never marks a thread read. Carries thread metadata only.
| Operation id | conversations.list |
| Scopes | conversations:read |
| Rate class | `read` |
| Idempotency | Not applicable |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
rep_id | string | no | at most 100 characters |
lead_id | uuid | no | |
status | "active" | "archived" | "spam" | no | |
folder | "primary" | "general" | "requests" | no | |
needs_human | boolean | no | |
unread | boolean | no | |
updated_after | date-time | no | |
limit | integer | no | 1 to 200, default 50 |
cursor | string | no | 1 to 2048 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
data | object[] | yes | |
has_more | boolean | yes | |
next_cursor | string | null | yes |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `REP_NOT_FOUND_404` | rep_id names no rep this key may see. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl "https://api.dmhero.ai/v1/conversations" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rep_id": {
"type": "string"
},
"lead_id": {
"type": [
"string",
"null"
]
},
"participant_username": {
"type": [
"string",
"null"
]
},
"participant_name": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"active",
"archived",
"spam"
]
},
"folder": {
"type": "string",
"enum": [
"primary",
"general",
"requests"
]
},
"is_starred": {
"type": "boolean"
},
"unread_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reply_intent": {
"description": "Null when there is none, or when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_state": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"needs_human": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"boolean",
"null"
]
},
"last_message_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"reply_window_closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"rep_id",
"lead_id",
"participant_username",
"participant_name",
"status",
"folder",
"is_starred",
"unread_count",
"reply_intent",
"setter_state",
"setter_stage",
"needs_human",
"last_message_at",
"reply_window_closes_at",
"created_at"
],
"additionalProperties": false
}
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"has_more",
"next_cursor"
],
"additionalProperties": false
}conversations.get
GET/v1/conversations/{conversation_id}
Read one conversation.
Never marks the thread read and never changes unread_count.
| Operation id | conversations.get |
| Scopes | conversations:read |
| Rate class | `read` |
| Idempotency | Not applicable |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
created_at | date-time | yes | |
folder | "primary" | "general" | "requests" | yes | |
id | string | yes | |
is_starred | boolean | yes | |
last_message_at | date-time | null | yes | |
lead_id | string | null | yes | |
needs_human | boolean | null | yes | Null when the plan does not include the AI Setter. |
participant_name | string | null | yes | |
participant_username | string | null | yes | |
rep_id | string | yes | |
reply_intent | string | null | yes | Null when there is none, or when the plan does not include the AI Setter. |
reply_window_closes_at | date-time | null | yes | |
setter_stage | string | null | yes | Null when the plan does not include the AI Setter. |
setter_state | string | null | yes | Null when the plan does not include the AI Setter. |
status | "active" | "archived" | "spam" | yes | |
unread_count | integer | yes | -9007199254740991 to 9007199254740991 |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl "https://api.dmhero.ai/v1/conversations/string" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rep_id": {
"type": "string"
},
"lead_id": {
"type": [
"string",
"null"
]
},
"participant_username": {
"type": [
"string",
"null"
]
},
"participant_name": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"active",
"archived",
"spam"
]
},
"folder": {
"type": "string",
"enum": [
"primary",
"general",
"requests"
]
},
"is_starred": {
"type": "boolean"
},
"unread_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reply_intent": {
"description": "Null when there is none, or when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_state": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"needs_human": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"boolean",
"null"
]
},
"last_message_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"reply_window_closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"rep_id",
"lead_id",
"participant_username",
"participant_name",
"status",
"folder",
"is_starred",
"unread_count",
"reply_intent",
"setter_state",
"setter_stage",
"needs_human",
"last_message_at",
"reply_window_closes_at",
"created_at"
],
"additionalProperties": false
}conversations.archive
POST/v1/conversations/{conversation_id}/archive
Archive a conversation.
Sets status to archived. Idempotent.
| Operation id | conversations.archive |
| Scopes | conversations:state |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
created_at | date-time | yes | |
folder | "primary" | "general" | "requests" | yes | |
id | string | yes | |
is_starred | boolean | yes | |
last_message_at | date-time | null | yes | |
lead_id | string | null | yes | |
needs_human | boolean | null | yes | Null when the plan does not include the AI Setter. |
participant_name | string | null | yes | |
participant_username | string | null | yes | |
rep_id | string | yes | |
reply_intent | string | null | yes | Null when there is none, or when the plan does not include the AI Setter. |
reply_window_closes_at | date-time | null | yes | |
setter_stage | string | null | yes | Null when the plan does not include the AI Setter. |
setter_state | string | null | yes | Null when the plan does not include the AI Setter. |
status | "active" | "archived" | "spam" | yes | |
unread_count | integer | yes | -9007199254740991 to 9007199254740991 |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/archive" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rep_id": {
"type": "string"
},
"lead_id": {
"type": [
"string",
"null"
]
},
"participant_username": {
"type": [
"string",
"null"
]
},
"participant_name": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"active",
"archived",
"spam"
]
},
"folder": {
"type": "string",
"enum": [
"primary",
"general",
"requests"
]
},
"is_starred": {
"type": "boolean"
},
"unread_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reply_intent": {
"description": "Null when there is none, or when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_state": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"needs_human": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"boolean",
"null"
]
},
"last_message_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"reply_window_closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"rep_id",
"lead_id",
"participant_username",
"participant_name",
"status",
"folder",
"is_starred",
"unread_count",
"reply_intent",
"setter_state",
"setter_stage",
"needs_human",
"last_message_at",
"reply_window_closes_at",
"created_at"
],
"additionalProperties": false
}conversations.drafts.list
GET/v1/conversations/{conversation_id}/drafts
List the AI Setter's pending draft of a conversation.
At most one draft: the newest pending one, as the DM Hero inbox shows it. Empty when the setter is waiting for nothing. Never marks the thread read.
| Operation id | conversations.drafts.list |
| Scopes | setter:read |
| Rate class | `read` |
| Idempotency | Not applicable |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
data | object[] | yes |
Errors
| Status | Code | When |
|---|---|---|
| 403 | `API_SETTER_NOT_IN_PLAN_403` | The organization's plan does not include the AI Setter. |
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl "https://api.dmhero.ai/v1/conversations/string/drafts" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"conversation_id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"suggestion",
"escalation"
]
},
"text": {
"type": "string"
},
"booking": {
"anyOf": [
{
"type": "object",
"properties": {
"starts_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
"timezone": {
"type": "string"
}
},
"required": [
"starts_at",
"timezone"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"conversation_id",
"kind",
"text",
"booking",
"created_at"
],
"additionalProperties": false
}
}
},
"required": [
"data"
],
"additionalProperties": false
}conversations.drafts.approve
POST/v1/conversations/{conversation_id}/drafts/{draft_id}/approve
Approve the AI Setter's draft: send it unchanged.
Sends the draft exactly as the AI Setter wrote it, through the Instagram Graph API, inside the 24 h window after the lead's last message. Takes no text: a request carrying text is refused; to say something else, dismiss the draft. A draft that books a Google Calendar slot books it before the DM goes out, and the booking is undone if Instagram refuses the DM. If the send breaks off so that nobody can tell whether the DM went out (CONVERSATION_SEND_OUTCOME_UNKNOWN_502), the draft counts as handled and its booking stands; check the thread in the DM Hero inbox. Approving a suggestion keeps the setter on the thread; approving an escalation's draft answers it, and a person then owns the thread. Idempotency-Key is required; a retry with the same key never sends a second DM.
| Operation id | conversations.drafts.approve |
| Scopes | setter:write |
| Rate class | `send`, plus conversation_send |
| Idempotency | `Idempotency-Key` required |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
draft_id | string | yes | 1 to 100 characters |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
text | any | no |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
booked | boolean | yes | |
conversation_id | string | yes | |
draft_id | string | yes | |
ig_message_id | string | yes | |
message_id | string | null | yes | |
recorded | boolean | yes | |
taken_over | boolean | yes |
Errors
| Status | Code | When |
|---|---|---|
| 400 | `API_IDEMPOTENCY_KEY_REQUIRED_400` | The request carries no Idempotency-Key header. |
| 403 | `API_SETTER_NOT_IN_PLAN_403` | The organization's plan does not include the AI Setter. |
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
| 404 | `SETTER_DRAFT_NOT_FOUND_404` | No draft with this id belongs to this conversation on a rep the key may see. |
| 409 | `CALENDAR_INVALID_EMAIL_409` | The draft books a meeting and the prospect's email address cannot receive an invitation. Nothing was sent. |
| 409 | `CALENDAR_SLOT_TAKEN_409` | The draft books a time that is no longer free in the calendar. Nothing was sent. |
| 409 | `CALENDAR_UNAVAILABLE_409` | The draft books a meeting and Google Calendar is not connected or lost access. Nothing was sent. |
| 409 | `CONVERSATION_WINDOW_CLOSED_409` | More than 24 hours passed since the lead's last message, or the lead never wrote. The body carries reply_window_closes_at. |
| 409 | `REP_ARCHIVED_409` | The rep is archived. Nothing was sent. |
| 409 | `REP_NOT_CONNECTED_409` | The rep has no usable Instagram connection. Nothing was sent. |
| 409 | `SETTER_DRAFT_HANDLED_409` | The draft was already approved or dismissed, here or in the DM Hero inbox, or a newer draft replaced it. List the drafts again. |
| 409 | `SETTER_DRAFT_IN_PROGRESS_409` | Another approval of this draft is being sent right now. |
| 409 | `SETTER_DRAFT_UNSENDABLE_409` | The draft cannot be sent as it is (too long for Instagram). Dismiss it, or edit it in the DM Hero inbox. |
| 429 | `CONVERSATION_RATE_LIMITED_429` | More than 10 replies were sent to this conversation in the last hour. |
| 502 | `CALENDAR_ERROR_502` | Google Calendar did not create the event the draft books. Nothing was sent; the Idempotency-Key may be reused. |
| 502 | `CONVERSATION_SEND_FAILED_502` | Instagram refused the message; nothing was sent, the draft stays pending and the Idempotency-Key may be reused. |
| 502 | `CONVERSATION_SEND_OUTCOME_UNKNOWN_502` | The connection to Instagram failed mid-send, so the message may have been delivered. The draft is marked as handled and cannot be approved again; any booking it carried stands. |
| 503 | `API_SEND_DISABLED_503` | Sending through the API is switched off for now. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/drafts/string/approve" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{}'JSON Schema
{
"type": "object",
"properties": {
"text": {
"not": {}
}
}
}{
"type": "object",
"properties": {
"conversation_id": {
"type": "string"
},
"draft_id": {
"type": "string"
},
"message_id": {
"type": [
"string",
"null"
]
},
"ig_message_id": {
"type": "string"
},
"recorded": {
"type": "boolean"
},
"booked": {
"type": "boolean"
},
"taken_over": {
"type": "boolean"
}
},
"required": [
"conversation_id",
"draft_id",
"message_id",
"ig_message_id",
"recorded",
"booked",
"taken_over"
],
"additionalProperties": false
}conversations.drafts.dismiss
POST/v1/conversations/{conversation_id}/drafts/{draft_id}/dismiss
Dismiss the AI Setter's draft without sending it.
Discards the conversation's pending draft. A Google Calendar slot it held is freed. The setter is not paused: it answers the prospect's next message as usual.
| Operation id | conversations.drafts.dismiss |
| Scopes | setter:write |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
draft_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | |
dismissed | true | yes | |
draft_id | string | yes |
Errors
| Status | Code | When |
|---|---|---|
| 403 | `API_SETTER_NOT_IN_PLAN_403` | The organization's plan does not include the AI Setter. |
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
| 404 | `SETTER_DRAFT_NOT_FOUND_404` | No draft with this id belongs to this conversation on a rep the key may see. |
| 409 | `SETTER_DRAFT_HANDLED_409` | The draft was already approved or dismissed, here or in the DM Hero inbox, or a newer draft replaced it. List the drafts again. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/drafts/string/dismiss" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"conversation_id": {
"type": "string"
},
"draft_id": {
"type": "string"
},
"dismissed": {
"type": "boolean",
"const": true
}
},
"required": [
"conversation_id",
"draft_id",
"dismissed"
],
"additionalProperties": false
}conversations.mark_read
POST/v1/conversations/{conversation_id}/read
Mark a conversation read.
Clears the operator's unread badge (unread_count = 0). The explicit way for an agent that handled a thread to say so; reads never do it.
| Operation id | conversations.mark_read |
| Scopes | conversations:state |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
created_at | date-time | yes | |
folder | "primary" | "general" | "requests" | yes | |
id | string | yes | |
is_starred | boolean | yes | |
last_message_at | date-time | null | yes | |
lead_id | string | null | yes | |
needs_human | boolean | null | yes | Null when the plan does not include the AI Setter. |
participant_name | string | null | yes | |
participant_username | string | null | yes | |
rep_id | string | yes | |
reply_intent | string | null | yes | Null when there is none, or when the plan does not include the AI Setter. |
reply_window_closes_at | date-time | null | yes | |
setter_stage | string | null | yes | Null when the plan does not include the AI Setter. |
setter_state | string | null | yes | Null when the plan does not include the AI Setter. |
status | "active" | "archived" | "spam" | yes | |
unread_count | integer | yes | -9007199254740991 to 9007199254740991 |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/read" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rep_id": {
"type": "string"
},
"lead_id": {
"type": [
"string",
"null"
]
},
"participant_username": {
"type": [
"string",
"null"
]
},
"participant_name": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"active",
"archived",
"spam"
]
},
"folder": {
"type": "string",
"enum": [
"primary",
"general",
"requests"
]
},
"is_starred": {
"type": "boolean"
},
"unread_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reply_intent": {
"description": "Null when there is none, or when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_state": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"needs_human": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"boolean",
"null"
]
},
"last_message_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"reply_window_closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"rep_id",
"lead_id",
"participant_username",
"participant_name",
"status",
"folder",
"is_starred",
"unread_count",
"reply_intent",
"setter_state",
"setter_stage",
"needs_human",
"last_message_at",
"reply_window_closes_at",
"created_at"
],
"additionalProperties": false
}conversations.setter.hand
POST/v1/conversations/{conversation_id}/setter/hand
Hand a conversation to the AI Setter.
For a thread the setter never drove, or stopped driving. The thread becomes the AI Setter's: any handoff and stale follow-up are cleared, the thread is linked to a lead of this workspace (created when there is none), and a pending draft is dismissed. When the prospect wrote last, inside the reply window, the setter replies now; otherwise it answers their next message. Sending a reply never resumes the setter; this call does. Idempotent: a thread the setter already drives is answered as it is.
| Operation id | conversations.setter.hand |
| Scopes | setter:write |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | |
lead_created | boolean | yes | |
lead_id | string | yes | |
reply_queued | boolean | yes | |
setter_state | "setter" | "booked" | yes |
Errors
| Status | Code | When |
|---|---|---|
| 403 | `API_SETTER_NOT_IN_PLAN_403` | The organization's plan does not include the AI Setter. |
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
| 409 | `SETTER_CAMPAIGN_ACTIVE_409` | The lead is still in an active campaign sequence; the AI Setter takes over by itself when they reply. |
| 409 | `SETTER_DISABLED_409` | The AI Setter is off for this thread's channel (inbound or outbound) on its rep. |
| 409 | `SETTER_HANDLE_EXCLUDED_409` | The thread has no lead and its participant is on the rep's excluded accounts. |
| 409 | `SETTER_LEAD_OPTED_OUT_409` | The thread's lead is marked not interested, so the AI Setter does not write to them. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/setter/hand" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"conversation_id": {
"type": "string"
},
"setter_state": {
"type": "string",
"enum": [
"setter",
"booked"
]
},
"reply_queued": {
"type": "boolean"
},
"lead_id": {
"type": "string"
},
"lead_created": {
"type": "boolean"
}
},
"required": [
"conversation_id",
"setter_state",
"reply_queued",
"lead_id",
"lead_created"
],
"additionalProperties": false
}conversations.setter.resume
POST/v1/conversations/{conversation_id}/setter/resume
Resume the AI Setter on a conversation handed to a person.
For a thread with needs_human: an escalation or a person's takeover. The thread becomes the AI Setter's: any handoff and stale follow-up are cleared, the thread is linked to a lead of this workspace (created when there is none), and a pending draft is dismissed. When the prospect wrote last, inside the reply window, the setter replies now; otherwise it answers their next message. Sending a reply never resumes the setter; this call does. The same effect as conversations.setter.hand, under the name the inbox button has.
| Operation id | conversations.setter.resume |
| Scopes | setter:write |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | |
lead_created | boolean | yes | |
lead_id | string | yes | |
reply_queued | boolean | yes | |
setter_state | "setter" | "booked" | yes |
Errors
| Status | Code | When |
|---|---|---|
| 403 | `API_SETTER_NOT_IN_PLAN_403` | The organization's plan does not include the AI Setter. |
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
| 409 | `SETTER_CAMPAIGN_ACTIVE_409` | The lead is still in an active campaign sequence; the AI Setter takes over by itself when they reply. |
| 409 | `SETTER_DISABLED_409` | The AI Setter is off for this thread's channel (inbound or outbound) on its rep. |
| 409 | `SETTER_HANDLE_EXCLUDED_409` | The thread has no lead and its participant is on the rep's excluded accounts. |
| 409 | `SETTER_LEAD_OPTED_OUT_409` | The thread's lead is marked not interested, so the AI Setter does not write to them. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/setter/resume" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"conversation_id": {
"type": "string"
},
"setter_state": {
"type": "string",
"enum": [
"setter",
"booked"
]
},
"reply_queued": {
"type": "boolean"
},
"lead_id": {
"type": "string"
},
"lead_created": {
"type": "boolean"
}
},
"required": [
"conversation_id",
"setter_state",
"reply_queued",
"lead_id",
"lead_created"
],
"additionalProperties": false
}conversations.star
POST/v1/conversations/{conversation_id}/star
Star a conversation.
Idempotent: starring a starred thread changes nothing.
| Operation id | conversations.star |
| Scopes | conversations:state |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
created_at | date-time | yes | |
folder | "primary" | "general" | "requests" | yes | |
id | string | yes | |
is_starred | boolean | yes | |
last_message_at | date-time | null | yes | |
lead_id | string | null | yes | |
needs_human | boolean | null | yes | Null when the plan does not include the AI Setter. |
participant_name | string | null | yes | |
participant_username | string | null | yes | |
rep_id | string | yes | |
reply_intent | string | null | yes | Null when there is none, or when the plan does not include the AI Setter. |
reply_window_closes_at | date-time | null | yes | |
setter_stage | string | null | yes | Null when the plan does not include the AI Setter. |
setter_state | string | null | yes | Null when the plan does not include the AI Setter. |
status | "active" | "archived" | "spam" | yes | |
unread_count | integer | yes | -9007199254740991 to 9007199254740991 |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/star" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rep_id": {
"type": "string"
},
"lead_id": {
"type": [
"string",
"null"
]
},
"participant_username": {
"type": [
"string",
"null"
]
},
"participant_name": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"active",
"archived",
"spam"
]
},
"folder": {
"type": "string",
"enum": [
"primary",
"general",
"requests"
]
},
"is_starred": {
"type": "boolean"
},
"unread_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reply_intent": {
"description": "Null when there is none, or when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_state": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"needs_human": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"boolean",
"null"
]
},
"last_message_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"reply_window_closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"rep_id",
"lead_id",
"participant_username",
"participant_name",
"status",
"folder",
"is_starred",
"unread_count",
"reply_intent",
"setter_state",
"setter_stage",
"needs_human",
"last_message_at",
"reply_window_closes_at",
"created_at"
],
"additionalProperties": false
}conversations.unarchive
POST/v1/conversations/{conversation_id}/unarchive
Move a conversation back to active.
Sets status to active (also from spam). Idempotent.
| Operation id | conversations.unarchive |
| Scopes | conversations:state |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
created_at | date-time | yes | |
folder | "primary" | "general" | "requests" | yes | |
id | string | yes | |
is_starred | boolean | yes | |
last_message_at | date-time | null | yes | |
lead_id | string | null | yes | |
needs_human | boolean | null | yes | Null when the plan does not include the AI Setter. |
participant_name | string | null | yes | |
participant_username | string | null | yes | |
rep_id | string | yes | |
reply_intent | string | null | yes | Null when there is none, or when the plan does not include the AI Setter. |
reply_window_closes_at | date-time | null | yes | |
setter_stage | string | null | yes | Null when the plan does not include the AI Setter. |
setter_state | string | null | yes | Null when the plan does not include the AI Setter. |
status | "active" | "archived" | "spam" | yes | |
unread_count | integer | yes | -9007199254740991 to 9007199254740991 |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/unarchive" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rep_id": {
"type": "string"
},
"lead_id": {
"type": [
"string",
"null"
]
},
"participant_username": {
"type": [
"string",
"null"
]
},
"participant_name": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"active",
"archived",
"spam"
]
},
"folder": {
"type": "string",
"enum": [
"primary",
"general",
"requests"
]
},
"is_starred": {
"type": "boolean"
},
"unread_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reply_intent": {
"description": "Null when there is none, or when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_state": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"needs_human": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"boolean",
"null"
]
},
"last_message_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"reply_window_closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"rep_id",
"lead_id",
"participant_username",
"participant_name",
"status",
"folder",
"is_starred",
"unread_count",
"reply_intent",
"setter_state",
"setter_stage",
"needs_human",
"last_message_at",
"reply_window_closes_at",
"created_at"
],
"additionalProperties": false
}conversations.unstar
POST/v1/conversations/{conversation_id}/unstar
Remove the star from a conversation.
Idempotent: unstarring a thread without a star changes nothing.
| Operation id | conversations.unstar |
| Scopes | conversations:state |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
| Reps | A key restricted to reps sees only data of its own reps |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
conversation_id | string | yes | 1 to 100 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
created_at | date-time | yes | |
folder | "primary" | "general" | "requests" | yes | |
id | string | yes | |
is_starred | boolean | yes | |
last_message_at | date-time | null | yes | |
lead_id | string | null | yes | |
needs_human | boolean | null | yes | Null when the plan does not include the AI Setter. |
participant_name | string | null | yes | |
participant_username | string | null | yes | |
rep_id | string | yes | |
reply_intent | string | null | yes | Null when there is none, or when the plan does not include the AI Setter. |
reply_window_closes_at | date-time | null | yes | |
setter_stage | string | null | yes | Null when the plan does not include the AI Setter. |
setter_state | string | null | yes | Null when the plan does not include the AI Setter. |
status | "active" | "archived" | "spam" | yes | |
unread_count | integer | yes | -9007199254740991 to 9007199254740991 |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `CONVERSATION_NOT_FOUND_404` | No conversation with this id is visible to this key: missing, in another workspace, or on a rep the key is not restricted to. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/conversations/string/unstar" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"rep_id": {
"type": "string"
},
"lead_id": {
"type": [
"string",
"null"
]
},
"participant_username": {
"type": [
"string",
"null"
]
},
"participant_name": {
"type": [
"string",
"null"
]
},
"status": {
"type": "string",
"enum": [
"active",
"archived",
"spam"
]
},
"folder": {
"type": "string",
"enum": [
"primary",
"general",
"requests"
]
},
"is_starred": {
"type": "boolean"
},
"unread_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"reply_intent": {
"description": "Null when there is none, or when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_state": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"needs_human": {
"description": "Null when the plan does not include the AI Setter.",
"type": [
"boolean",
"null"
]
},
"last_message_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"reply_window_closes_at": {
"anyOf": [
{
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
},
{
"type": "null"
}
]
},
"created_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"id",
"rep_id",
"lead_id",
"participant_username",
"participant_name",
"status",
"folder",
"is_starred",
"unread_count",
"reply_intent",
"setter_state",
"setter_stage",
"needs_human",
"last_message_at",
"reply_window_closes_at",
"created_at"
],
"additionalProperties": false
}