Reference
Jobs
Jobs: 8 operations (jobs.list, jobs.get, jobs.cancel, jobs.result, leads.bulk.preview, leads.bulk.confirm, leads.exports.create, leads.imports.create).
A lead filter in a bulk action or an export takes custom field conditions under filter.custom_fields; the bulk action set_custom_fields writes values; an export has one custom_fields.<key> column per field. See Custom fields.
| Method | Path | Operation |
|---|---|---|
GET | /v1/jobs | jobs.list |
GET | /v1/jobs/{job_id} | jobs.get |
POST | /v1/jobs/{job_id}/cancel | jobs.cancel |
GET | /v1/jobs/{job_id}/result | jobs.result |
POST | /v1/leads/bulk-actions | leads.bulk.preview |
POST | /v1/leads/bulk-actions/{job_id}/confirm | leads.bulk.confirm |
POST | /v1/leads/exports | leads.exports.create |
POST | /v1/leads/imports | leads.imports.create |
jobs.list
GET/v1/jobs
The workspace's jobs, newest first.
| Operation id | jobs.list |
| Scopes | leads:read |
| Rate class | `read` |
| Idempotency | Not applicable |
| Keys | Developer keys |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
limit | integer | no | 1 to 200, default 50 |
cursor | string | no | 1 to 2048 characters |
kind | "leads_import" | "leads_export" | "leads_bulk" | no | |
status | "awaiting_confirmation" | "queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired" | no |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
data | object[] | yes | |
has_more | boolean | yes | |
next_cursor | string | null | yes |
Errors
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl "https://api.dmhero.ai/v1/jobs" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema
{
"type": "object",
"properties": {
"data": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"leads_import",
"leads_export",
"leads_bulk"
]
},
"action": {
"anyOf": [
{
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"awaiting_confirmation",
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"expired"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"done",
"total"
],
"additionalProperties": false
},
"queue_position": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise."
},
"preview": {
"anyOf": [
{
"type": "object",
"properties": {
"matched_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"sample": {
"description": "In the preview response only, never stored.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"last_name": {
"type": [
"string",
"null"
]
},
"ig_handle": {
"type": [
"string",
"null"
]
},
"fb_handle": {
"type": [
"string",
"null"
]
},
"profile_url": {
"type": [
"string",
"null"
]
},
"niche": {
"type": [
"string",
"null"
]
},
"followers": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"bio": {
"type": [
"string",
"null"
]
},
"company_name": {
"type": [
"string",
"null"
]
},
"last_contacted_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"type": [
"string",
"null"
]
},
"custom_fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Every custom field the workspace defines, in its order, null when the lead has no value for it; then any other key stored on the lead, as stored (an integrations key may write keys the workspace never defined)."
},
"external_id": {
"type": [
"string",
"null"
]
},
"assigned_rep_id": {
"type": [
"string",
"null"
]
},
"is_inbound": {
"type": "boolean"
},
"icp_verdict": {
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "List only: the newest thread's stage, when the key holds conversations:read and may see that thread's rep; null otherwise, and null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stall_reason": {
"description": "List only, under the same condition as setter_stage; null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"campaign": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"count"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "List only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in."
},
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"workspace_id",
"name",
"first_name",
"last_name",
"ig_handle",
"fb_handle",
"profile_url",
"niche",
"followers",
"status",
"notes",
"email",
"phone",
"website",
"bio",
"company_name",
"last_contacted_at",
"tags",
"folder_id",
"custom_fields",
"external_id",
"assigned_rep_id",
"is_inbound",
"icp_verdict",
"setter_stage",
"setter_stall_reason",
"campaign",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"matched_count",
"warnings"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"result": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
},
{
"type": "array",
"items": {
"type": "object",
"properties": {
"row": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"code": {
"type": "string"
}
},
"required": [
"row",
"code"
],
"additionalProperties": false
}
}
]
}
},
{
"type": "null"
}
],
"description": "Counts and short codes only, never lead data. errors_sample names row numbers and codes."
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"started_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"finished_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"confirm_expires_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"result_url": {
"description": "The export's CSV, once the job succeeded.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"kind",
"action",
"status",
"progress",
"queue_position",
"preview",
"result",
"error",
"created_at",
"started_at",
"finished_at",
"confirm_expires_at",
"result_url"
],
"additionalProperties": false
}
},
"has_more": {
"type": "boolean"
},
"next_cursor": {
"type": [
"string",
"null"
]
}
},
"required": [
"data",
"has_more",
"next_cursor"
],
"additionalProperties": false
}jobs.get
GET/v1/jobs/{job_id}
One job: its status, progress and result counts.
| Operation id | jobs.get |
| Scopes | leads:read |
| Rate class | `read` |
| Idempotency | Not applicable |
| Keys | Developer keys |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string | yes | The job id.. 1 to 200 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
action | "update_status" | "add_tags" | "remove_tags" | "set_folder" | "delete" | "enroll" | "unenroll" | "set_custom_fields" | null | yes | |
confirm_expires_at | date-time | null | yes | |
created_at | date-time | yes | |
error | object | null | yes | |
finished_at | date-time | null | yes | |
id | string | yes | |
kind | "leads_import" | "leads_export" | "leads_bulk" | yes | |
preview | object | null | yes | |
progress | object | yes | |
queue_position | integer | null | yes | For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise. |
result | object | null | yes | Counts and short codes only, never lead data. errors_sample names row numbers and codes. |
result_url | string | null | yes | The export's CSV, once the job succeeded. |
started_at | date-time | null | yes | |
status | "awaiting_confirmation" | "queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired" | yes |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `JOB_NOT_FOUND_404` | No job with this id exists in this workspace. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl "https://api.dmhero.ai/v1/jobs/string" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"leads_import",
"leads_export",
"leads_bulk"
]
},
"action": {
"anyOf": [
{
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"awaiting_confirmation",
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"expired"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"done",
"total"
],
"additionalProperties": false
},
"queue_position": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise."
},
"preview": {
"anyOf": [
{
"type": "object",
"properties": {
"matched_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"sample": {
"description": "In the preview response only, never stored.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"last_name": {
"type": [
"string",
"null"
]
},
"ig_handle": {
"type": [
"string",
"null"
]
},
"fb_handle": {
"type": [
"string",
"null"
]
},
"profile_url": {
"type": [
"string",
"null"
]
},
"niche": {
"type": [
"string",
"null"
]
},
"followers": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"bio": {
"type": [
"string",
"null"
]
},
"company_name": {
"type": [
"string",
"null"
]
},
"last_contacted_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"type": [
"string",
"null"
]
},
"custom_fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Every custom field the workspace defines, in its order, null when the lead has no value for it; then any other key stored on the lead, as stored (an integrations key may write keys the workspace never defined)."
},
"external_id": {
"type": [
"string",
"null"
]
},
"assigned_rep_id": {
"type": [
"string",
"null"
]
},
"is_inbound": {
"type": "boolean"
},
"icp_verdict": {
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "List only: the newest thread's stage, when the key holds conversations:read and may see that thread's rep; null otherwise, and null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stall_reason": {
"description": "List only, under the same condition as setter_stage; null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"campaign": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"count"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "List only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in."
},
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"workspace_id",
"name",
"first_name",
"last_name",
"ig_handle",
"fb_handle",
"profile_url",
"niche",
"followers",
"status",
"notes",
"email",
"phone",
"website",
"bio",
"company_name",
"last_contacted_at",
"tags",
"folder_id",
"custom_fields",
"external_id",
"assigned_rep_id",
"is_inbound",
"icp_verdict",
"setter_stage",
"setter_stall_reason",
"campaign",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"matched_count",
"warnings"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"result": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
},
{
"type": "array",
"items": {
"type": "object",
"properties": {
"row": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"code": {
"type": "string"
}
},
"required": [
"row",
"code"
],
"additionalProperties": false
}
}
]
}
},
{
"type": "null"
}
],
"description": "Counts and short codes only, never lead data. errors_sample names row numbers and codes."
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"started_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"finished_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"confirm_expires_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"result_url": {
"description": "The export's CSV, once the job succeeded.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"kind",
"action",
"status",
"progress",
"queue_position",
"preview",
"result",
"error",
"created_at",
"started_at",
"finished_at",
"confirm_expires_at",
"result_url"
],
"additionalProperties": false
}jobs.cancel
POST/v1/jobs/{job_id}/cancel
Cancel a job. A running job stops at its next slice; work already done stays done.
| Operation id | jobs.cancel |
| Scopes | leads:write |
| Rate class | `write` |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string | yes | The job id.. 1 to 200 characters |
Response 200
| Field | Type | Required | Description |
|---|---|---|---|
action | "update_status" | "add_tags" | "remove_tags" | "set_folder" | "delete" | "enroll" | "unenroll" | "set_custom_fields" | null | yes | |
confirm_expires_at | date-time | null | yes | |
created_at | date-time | yes | |
error | object | null | yes | |
finished_at | date-time | null | yes | |
id | string | yes | |
kind | "leads_import" | "leads_export" | "leads_bulk" | yes | |
preview | object | null | yes | |
progress | object | yes | |
queue_position | integer | null | yes | For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise. |
result | object | null | yes | Counts and short codes only, never lead data. errors_sample names row numbers and codes. |
result_url | string | null | yes | The export's CSV, once the job succeeded. |
started_at | date-time | null | yes | |
status | "awaiting_confirmation" | "queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired" | yes |
Errors
| Status | Code | When |
|---|---|---|
| 404 | `JOB_NOT_FOUND_404` | No job with this id exists in this workspace. |
| 409 | `JOB_NOT_CANCELLABLE_409` | The job has already ended. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/jobs/string/cancel" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"JSON Schema
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"leads_import",
"leads_export",
"leads_bulk"
]
},
"action": {
"anyOf": [
{
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"awaiting_confirmation",
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"expired"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"done",
"total"
],
"additionalProperties": false
},
"queue_position": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise."
},
"preview": {
"anyOf": [
{
"type": "object",
"properties": {
"matched_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"sample": {
"description": "In the preview response only, never stored.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"last_name": {
"type": [
"string",
"null"
]
},
"ig_handle": {
"type": [
"string",
"null"
]
},
"fb_handle": {
"type": [
"string",
"null"
]
},
"profile_url": {
"type": [
"string",
"null"
]
},
"niche": {
"type": [
"string",
"null"
]
},
"followers": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"bio": {
"type": [
"string",
"null"
]
},
"company_name": {
"type": [
"string",
"null"
]
},
"last_contacted_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"type": [
"string",
"null"
]
},
"custom_fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Every custom field the workspace defines, in its order, null when the lead has no value for it; then any other key stored on the lead, as stored (an integrations key may write keys the workspace never defined)."
},
"external_id": {
"type": [
"string",
"null"
]
},
"assigned_rep_id": {
"type": [
"string",
"null"
]
},
"is_inbound": {
"type": "boolean"
},
"icp_verdict": {
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "List only: the newest thread's stage, when the key holds conversations:read and may see that thread's rep; null otherwise, and null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stall_reason": {
"description": "List only, under the same condition as setter_stage; null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"campaign": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"count"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "List only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in."
},
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"workspace_id",
"name",
"first_name",
"last_name",
"ig_handle",
"fb_handle",
"profile_url",
"niche",
"followers",
"status",
"notes",
"email",
"phone",
"website",
"bio",
"company_name",
"last_contacted_at",
"tags",
"folder_id",
"custom_fields",
"external_id",
"assigned_rep_id",
"is_inbound",
"icp_verdict",
"setter_stage",
"setter_stall_reason",
"campaign",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"matched_count",
"warnings"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"result": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
},
{
"type": "array",
"items": {
"type": "object",
"properties": {
"row": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"code": {
"type": "string"
}
},
"required": [
"row",
"code"
],
"additionalProperties": false
}
}
]
}
},
{
"type": "null"
}
],
"description": "Counts and short codes only, never lead data. errors_sample names row numbers and codes."
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"started_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"finished_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"confirm_expires_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"result_url": {
"description": "The export's CSV, once the job succeeded.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"kind",
"action",
"status",
"progress",
"queue_position",
"preview",
"result",
"error",
"created_at",
"started_at",
"finished_at",
"confirm_expires_at",
"result_url"
],
"additionalProperties": false
}jobs.result
GET/v1/jobs/{job_id}/result
The CSV file an export job built (text/csv), for 24 hours after it finished.
| Operation id | jobs.result |
| Scopes | leads:read |
| Rate class | `heavy` |
| Idempotency | Not applicable |
| Keys | Developer keys |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string | yes | The job id.. 1 to 200 characters |
Response 200
JSON of type string.
Errors
| Status | Code | When |
|---|---|---|
| 404 | `JOB_NOT_FOUND_404` | No job with this id exists in this workspace. |
| 404 | `JOB_RESULT_NOT_FOUND_404` | The job is not an export, or ended without a file. |
| 409 | `JOB_RESULT_NOT_READY_409` | The export has not finished yet. |
| 410 | `JOB_RESULT_EXPIRED_410` | The file was deleted 24 hours after the job finished. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl "https://api.dmhero.ai/v1/jobs/string/result" \
-H "Authorization: Bearer $DMHERO_API_KEY"JSON Schema
{
"type": "string",
"description": "text/csv: the file, BOM and header row included."
}leads.bulk.preview
POST/v1/leads/bulk-actions
Preview a bulk action on up to 30 000 leads; the target is frozen until you confirm.
Resolves the target (lead ids, or a filter) in this workspace and freezes it. Answers 201 with the job awaiting confirmation, the matched count, a sample of 10 leads and a confirm_token valid for 15 minutes. delete, update_status and remove_tags also need leads:delete; enroll and unenroll need enrollments:write. set_custom_fields overwrites custom field values (params.values; null clears one): it also needs leads:delete, cannot be auto-confirmed, and a lead whose values would pass 4 KB is left unchanged and counted as failed. auto_confirm: true queues a non-destructive action (add_tags, set_folder, enroll) at once (202).
| Operation id | leads.bulk.preview |
| Scopes | leads:write |
| Rate class | `heavy`, plus payload_day |
| Idempotency | `Idempotency-Key` accepted |
| Keys | Developer keys |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
action | "update_status" | "add_tags" | "remove_tags" | "set_folder" | "delete" | "enroll" | "unenroll" | "set_custom_fields" | yes | |
target | object | yes | Exactly one of lead_ids (1 to 30 000) and filter. |
auto_confirm | boolean | no | default false |
params | object | no | default {} |
Response 201
| Field | Type | Required | Description |
|---|---|---|---|
action | "update_status" | "add_tags" | "remove_tags" | "set_folder" | "delete" | "enroll" | "unenroll" | "set_custom_fields" | null | yes | |
confirm_expires_at | date-time | null | yes | |
created_at | date-time | yes | |
error | object | null | yes | |
finished_at | date-time | null | yes | |
id | string | yes | |
kind | "leads_import" | "leads_export" | "leads_bulk" | yes | |
preview | object | null | yes | |
progress | object | yes | |
queue_position | integer | null | yes | For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise. |
result | object | null | yes | Counts and short codes only, never lead data. errors_sample names row numbers and codes. |
result_url | string | null | yes | The export's CSV, once the job succeeded. |
started_at | date-time | null | yes | |
status | "awaiting_confirmation" | "queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired" | yes | |
confirm_token | string | no | Shown once, in the preview response. Send it to the confirm operation before confirm_expires_at. |
Errors
| Status | Code | When |
|---|---|---|
| 400 | `BULK_AUTO_CONFIRM_NOT_ALLOWED_400` | auto_confirm on a destructive action. |
| 400 | `BULK_TOO_MANY_400` | The target holds more than 30 000 leads. |
| 400 | `CUSTOM_FIELD_UNKNOWN_400` | A custom field key in the filter or in set_custom_fields' values is not one this workspace defines. |
| 400 | `TAG_INVALID_400` | A tag is empty or longer than the tag limit. |
| 404 | `CAMPAIGN_NOT_FOUND_404` | No campaign with this id exists in this workspace. |
| 404 | `FOLDER_NOT_FOUND_404` | No folder with this id exists in this workspace. |
| 404 | `LEAD_NOT_FOUND_404` | None of lead_ids is a lead of this workspace. |
| 404 | `REP_NOT_FOUND_404` | rep_id names no rep this API key may use. |
| 409 | `JOB_QUEUE_FULL_409` | The organization already has 3 jobs waiting for confirmation, queued or running. |
| 413 | `JOB_PAYLOAD_QUOTA_413` | The organization reached its daily quota of job payload bytes. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/leads/bulk-actions" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"action": "add_tags",
"target": {
"filter": {
"tag": "webinar"
}
},
"params": {
"tags": [
"follow-up"
]
}
}'JSON Schema
{
"type": "object",
"properties": {
"action": {
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
"target": {
"type": "object",
"properties": {
"lead_ids": {
"minItems": 1,
"type": "array",
"items": {
"type": "string",
"minLength": 1,
"maxLength": 200
}
},
"filter": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"tag": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"niche": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"folder_id": {
"description": "A folder id, or none for leads in no folder.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"search": {
"description": "Case-insensitive match on name, handles and notes.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"external_id": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"ig_handle": {
"description": "Matched case-insensitively, a leading @ ignored.",
"type": "string",
"minLength": 1,
"maxLength": 100
},
"created_after": {
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"created_before": {
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_after": {
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"exclude_inbound": {
"type": "boolean"
},
"campaign_id": {
"description": "Leads enrolled in this campaign.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"enrollment": {
"description": "Leads in at least one campaign (any) or in none.",
"type": "string",
"enum": [
"any",
"none"
]
},
"custom_fields": {
"description": "Custom field conditions, ANDed with each other and the filters above (at most 5): { key, op: equals | contains | present | missing, value? }. Each key must be one the workspace defines (GET /v1/custom-fields), else 400 CUSTOM_FIELD_UNKNOWN_400.",
"maxItems": 5,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "equals"
},
"value": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"description": "Compared trimmed and ignoring case, as a whole value."
}
},
"required": [
"key",
"op",
"value"
]
},
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "contains"
},
"value": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"description": "A substring, ignoring case. Every character is literal (% and _ included)."
}
},
"required": [
"key",
"op",
"value"
]
},
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "present"
}
},
"required": [
"key",
"op"
]
},
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "missing"
}
},
"required": [
"key",
"op"
]
}
],
"description": "equals: the value, trimmed, equals this text ignoring case. contains: the value holds this text ignoring case. present: the lead has a non-blank value. missing: the lead has no value or a blank one."
}
}
},
"additionalProperties": false,
"description": "Lead filter. An empty filter selects every lead of the workspace. A member not named here is refused (400 VALIDATION_FAILED_400 naming filter.<member>), never ignored: a misspelt member would otherwise widen the filter to every lead."
}
},
"description": "Exactly one of lead_ids (1 to 30 000) and filter."
},
"params": {
"default": {},
"type": "object",
"properties": {
"status": {
"description": "update_status: the new status.",
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"tags": {
"description": "add_tags, remove_tags: the tags.",
"minItems": 1,
"maxItems": 20,
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"description": "set_folder: the folder, or null for no folder.",
"anyOf": [
{
"type": "string",
"minLength": 1,
"maxLength": 200
},
{
"type": "null"
}
]
},
"campaign_id": {
"description": "enroll, unenroll: the campaign.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"rep_id": {
"description": "enroll: the one rep to assign; default every rep the key may use.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"values": {
"description": "set_custom_fields: { <key>: text | null } for custom fields the workspace defines. A text overwrites the lead's value (trimmed, at most 500 characters); null or an empty text clears it. Keys not named are left alone.",
"type": "object",
"propertyNames": {
"type": "string",
"minLength": 1,
"maxLength": 64
},
"additionalProperties": {
"anyOf": [
{
"type": "string",
"maxLength": 2000
},
{
"type": "null"
}
]
}
}
}
},
"auto_confirm": {
"default": false,
"type": "boolean"
}
},
"required": [
"action",
"target"
]
}{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"leads_import",
"leads_export",
"leads_bulk"
]
},
"action": {
"anyOf": [
{
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"awaiting_confirmation",
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"expired"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"done",
"total"
],
"additionalProperties": false
},
"queue_position": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise."
},
"preview": {
"anyOf": [
{
"type": "object",
"properties": {
"matched_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"sample": {
"description": "In the preview response only, never stored.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"last_name": {
"type": [
"string",
"null"
]
},
"ig_handle": {
"type": [
"string",
"null"
]
},
"fb_handle": {
"type": [
"string",
"null"
]
},
"profile_url": {
"type": [
"string",
"null"
]
},
"niche": {
"type": [
"string",
"null"
]
},
"followers": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"bio": {
"type": [
"string",
"null"
]
},
"company_name": {
"type": [
"string",
"null"
]
},
"last_contacted_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"type": [
"string",
"null"
]
},
"custom_fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Every custom field the workspace defines, in its order, null when the lead has no value for it; then any other key stored on the lead, as stored (an integrations key may write keys the workspace never defined)."
},
"external_id": {
"type": [
"string",
"null"
]
},
"assigned_rep_id": {
"type": [
"string",
"null"
]
},
"is_inbound": {
"type": "boolean"
},
"icp_verdict": {
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "List only: the newest thread's stage, when the key holds conversations:read and may see that thread's rep; null otherwise, and null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stall_reason": {
"description": "List only, under the same condition as setter_stage; null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"campaign": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"count"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "List only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in."
},
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"workspace_id",
"name",
"first_name",
"last_name",
"ig_handle",
"fb_handle",
"profile_url",
"niche",
"followers",
"status",
"notes",
"email",
"phone",
"website",
"bio",
"company_name",
"last_contacted_at",
"tags",
"folder_id",
"custom_fields",
"external_id",
"assigned_rep_id",
"is_inbound",
"icp_verdict",
"setter_stage",
"setter_stall_reason",
"campaign",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"matched_count",
"warnings"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"result": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
},
{
"type": "array",
"items": {
"type": "object",
"properties": {
"row": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"code": {
"type": "string"
}
},
"required": [
"row",
"code"
],
"additionalProperties": false
}
}
]
}
},
{
"type": "null"
}
],
"description": "Counts and short codes only, never lead data. errors_sample names row numbers and codes."
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"started_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"finished_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"confirm_expires_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"result_url": {
"description": "The export's CSV, once the job succeeded.",
"type": [
"string",
"null"
]
},
"confirm_token": {
"description": "Shown once, in the preview response. Send it to the confirm operation before confirm_expires_at.",
"type": "string"
}
},
"required": [
"id",
"kind",
"action",
"status",
"progress",
"queue_position",
"preview",
"result",
"error",
"created_at",
"started_at",
"finished_at",
"confirm_expires_at",
"result_url"
],
"additionalProperties": false
}leads.bulk.confirm
POST/v1/leads/bulk-actions/{job_id}/confirm
Confirm a previewed bulk action: the job is queued and runs on the frozen target.
| Operation id | leads.bulk.confirm |
| Scopes | leads:write |
| Rate class | `heavy` |
| Idempotency | `Idempotency-Key` required |
| Keys | Developer keys |
| Destructive | Yes: it removes or stops something that cannot be restored by repeating the call |
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
job_id | string | yes | The job id.. 1 to 200 characters |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
confirm_token | string | yes | 1 to 200 characters |
expected_count | integer | yes | The preview's matched_count, as you read it.. 0 to 9007199254740991 |
Response 202
| Field | Type | Required | Description |
|---|---|---|---|
action | "update_status" | "add_tags" | "remove_tags" | "set_folder" | "delete" | "enroll" | "unenroll" | "set_custom_fields" | null | yes | |
confirm_expires_at | date-time | null | yes | |
created_at | date-time | yes | |
error | object | null | yes | |
finished_at | date-time | null | yes | |
id | string | yes | |
kind | "leads_import" | "leads_export" | "leads_bulk" | yes | |
preview | object | null | yes | |
progress | object | yes | |
queue_position | integer | null | yes | For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise. |
result | object | null | yes | Counts and short codes only, never lead data. errors_sample names row numbers and codes. |
result_url | string | null | yes | The export's CSV, once the job succeeded. |
started_at | date-time | null | yes | |
status | "awaiting_confirmation" | "queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired" | yes |
Errors
| Status | Code | When |
|---|---|---|
| 400 | `API_IDEMPOTENCY_KEY_REQUIRED_400` | The request carries no Idempotency-Key header. |
| 403 | `JOB_CONFIRM_TOKEN_INVALID_403` | The confirmation token is not this job's. |
| 404 | `JOB_NOT_FOUND_404` | No job with this id exists in this workspace. |
| 409 | `BULK_COUNT_CHANGED_409` | expected_count differs from the preview's matched_count. |
| 409 | `JOB_CONFIRMATION_EXPIRED_409` | The 15 minute confirmation window has passed. |
| 409 | `JOB_NOT_AWAITING_CONFIRMATION_409` | The job is not awaiting confirmation. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/leads/bulk-actions/string/confirm" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"confirm_token": "string",
"expected_count": 0
}'JSON Schema
{
"type": "object",
"properties": {
"confirm_token": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"expected_count": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991,
"description": "The preview's matched_count, as you read it."
}
},
"required": [
"confirm_token",
"expected_count"
]
}{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"leads_import",
"leads_export",
"leads_bulk"
]
},
"action": {
"anyOf": [
{
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"awaiting_confirmation",
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"expired"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"done",
"total"
],
"additionalProperties": false
},
"queue_position": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise."
},
"preview": {
"anyOf": [
{
"type": "object",
"properties": {
"matched_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"sample": {
"description": "In the preview response only, never stored.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"last_name": {
"type": [
"string",
"null"
]
},
"ig_handle": {
"type": [
"string",
"null"
]
},
"fb_handle": {
"type": [
"string",
"null"
]
},
"profile_url": {
"type": [
"string",
"null"
]
},
"niche": {
"type": [
"string",
"null"
]
},
"followers": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"bio": {
"type": [
"string",
"null"
]
},
"company_name": {
"type": [
"string",
"null"
]
},
"last_contacted_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"type": [
"string",
"null"
]
},
"custom_fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Every custom field the workspace defines, in its order, null when the lead has no value for it; then any other key stored on the lead, as stored (an integrations key may write keys the workspace never defined)."
},
"external_id": {
"type": [
"string",
"null"
]
},
"assigned_rep_id": {
"type": [
"string",
"null"
]
},
"is_inbound": {
"type": "boolean"
},
"icp_verdict": {
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "List only: the newest thread's stage, when the key holds conversations:read and may see that thread's rep; null otherwise, and null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stall_reason": {
"description": "List only, under the same condition as setter_stage; null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"campaign": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"count"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "List only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in."
},
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"workspace_id",
"name",
"first_name",
"last_name",
"ig_handle",
"fb_handle",
"profile_url",
"niche",
"followers",
"status",
"notes",
"email",
"phone",
"website",
"bio",
"company_name",
"last_contacted_at",
"tags",
"folder_id",
"custom_fields",
"external_id",
"assigned_rep_id",
"is_inbound",
"icp_verdict",
"setter_stage",
"setter_stall_reason",
"campaign",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"matched_count",
"warnings"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"result": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
},
{
"type": "array",
"items": {
"type": "object",
"properties": {
"row": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"code": {
"type": "string"
}
},
"required": [
"row",
"code"
],
"additionalProperties": false
}
}
]
}
},
{
"type": "null"
}
],
"description": "Counts and short codes only, never lead data. errors_sample names row numbers and codes."
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"started_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"finished_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"confirm_expires_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"result_url": {
"description": "The export's CSV, once the job succeeded.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"kind",
"action",
"status",
"progress",
"queue_position",
"preview",
"result",
"error",
"created_at",
"started_at",
"finished_at",
"confirm_expires_at",
"result_url"
],
"additionalProperties": false
}leads.exports.create
POST/v1/leads/exports
Export the leads a filter selects as a CSV file, built by a job.
The same file the app's CRM export writes for the same leads, plus one column per custom field the workspace defines, in their display order, headed custom_fields.<key>, so the file imports back through POST /v1/leads/imports unchanged. Poll GET /v1/jobs/{job_id}; once it succeeded, download result_url within 24 hours.
| Operation id | leads.exports.create |
| Scopes | leads:read |
| Rate class | `heavy`, plus payload_day |
| Idempotency | `Idempotency-Key` required |
| Keys | Developer keys |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
filter | object | no | Lead filter. An empty filter selects every lead of the workspace. A member not named here is refused (400 VALIDATION_FAILED_400 naming filter.<member>), never ignored: a misspelt member would otherwise widen the filter to every lead. |
format | "csv" | no | default "csv" |
Response 202
| Field | Type | Required | Description |
|---|---|---|---|
action | "update_status" | "add_tags" | "remove_tags" | "set_folder" | "delete" | "enroll" | "unenroll" | "set_custom_fields" | null | yes | |
confirm_expires_at | date-time | null | yes | |
created_at | date-time | yes | |
error | object | null | yes | |
finished_at | date-time | null | yes | |
id | string | yes | |
kind | "leads_import" | "leads_export" | "leads_bulk" | yes | |
preview | object | null | yes | |
progress | object | yes | |
queue_position | integer | null | yes | For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise. |
result | object | null | yes | Counts and short codes only, never lead data. errors_sample names row numbers and codes. |
result_url | string | null | yes | The export's CSV, once the job succeeded. |
started_at | date-time | null | yes | |
status | "awaiting_confirmation" | "queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired" | yes |
Errors
| Status | Code | When |
|---|---|---|
| 400 | `API_IDEMPOTENCY_KEY_REQUIRED_400` | The request carries no Idempotency-Key header. |
| 400 | `CUSTOM_FIELD_UNKNOWN_400` | A custom field key in the filter or in set_custom_fields' values is not one this workspace defines. |
| 400 | `EXPORT_TOO_MANY_ROWS_400` | The filter selects more than 30 000 leads. Narrow it. |
| 404 | `CAMPAIGN_NOT_FOUND_404` | No campaign with this id exists in this workspace. |
| 409 | `JOB_QUEUE_FULL_409` | The organization already has 3 jobs waiting for confirmation, queued or running. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/leads/exports" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"filter": {
"status": "new",
"tag": "string",
"niche": "string",
"folder_id": "string",
"search": "string",
"external_id": "string",
"ig_handle": "string",
"created_after": "2026-10-21T09:30:00.000Z",
"created_before": "2026-10-21T09:30:00.000Z",
"updated_after": "2026-10-21T09:30:00.000Z",
"exclude_inbound": true,
"campaign_id": "string",
"enrollment": "any",
"custom_fields": [
{
"key": "string",
"op": "equals",
"value": "string"
}
]
},
"format": "csv"
}'JSON Schema
{
"type": "object",
"properties": {
"filter": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"tag": {
"type": "string",
"minLength": 1,
"maxLength": 100
},
"niche": {
"type": "string",
"minLength": 1,
"maxLength": 200
},
"folder_id": {
"description": "A folder id, or none for leads in no folder.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"search": {
"description": "Case-insensitive match on name, handles and notes.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"external_id": {
"type": "string",
"minLength": 1,
"maxLength": 255
},
"ig_handle": {
"description": "Matched case-insensitively, a leading @ ignored.",
"type": "string",
"minLength": 1,
"maxLength": 100
},
"created_after": {
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"created_before": {
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_after": {
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"exclude_inbound": {
"type": "boolean"
},
"campaign_id": {
"description": "Leads enrolled in this campaign.",
"type": "string",
"minLength": 1,
"maxLength": 200
},
"enrollment": {
"description": "Leads in at least one campaign (any) or in none.",
"type": "string",
"enum": [
"any",
"none"
]
},
"custom_fields": {
"description": "Custom field conditions, ANDed with each other and the filters above (at most 5): { key, op: equals | contains | present | missing, value? }. Each key must be one the workspace defines (GET /v1/custom-fields), else 400 CUSTOM_FIELD_UNKNOWN_400.",
"maxItems": 5,
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "equals"
},
"value": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"description": "Compared trimmed and ignoring case, as a whole value."
}
},
"required": [
"key",
"op",
"value"
]
},
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "contains"
},
"value": {
"type": "string",
"minLength": 1,
"maxLength": 500,
"description": "A substring, ignoring case. Every character is literal (% and _ included)."
}
},
"required": [
"key",
"op",
"value"
]
},
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "present"
}
},
"required": [
"key",
"op"
]
},
{
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "A custom field key the workspace defines (GET /v1/custom-fields)."
},
"op": {
"type": "string",
"const": "missing"
}
},
"required": [
"key",
"op"
]
}
],
"description": "equals: the value, trimmed, equals this text ignoring case. contains: the value holds this text ignoring case. present: the lead has a non-blank value. missing: the lead has no value or a blank one."
}
}
},
"additionalProperties": false,
"description": "Lead filter. An empty filter selects every lead of the workspace. A member not named here is refused (400 VALIDATION_FAILED_400 naming filter.<member>), never ignored: a misspelt member would otherwise widen the filter to every lead."
},
"format": {
"default": "csv",
"type": "string",
"enum": [
"csv"
]
}
}
}{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"leads_import",
"leads_export",
"leads_bulk"
]
},
"action": {
"anyOf": [
{
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"awaiting_confirmation",
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"expired"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"done",
"total"
],
"additionalProperties": false
},
"queue_position": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise."
},
"preview": {
"anyOf": [
{
"type": "object",
"properties": {
"matched_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"sample": {
"description": "In the preview response only, never stored.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"last_name": {
"type": [
"string",
"null"
]
},
"ig_handle": {
"type": [
"string",
"null"
]
},
"fb_handle": {
"type": [
"string",
"null"
]
},
"profile_url": {
"type": [
"string",
"null"
]
},
"niche": {
"type": [
"string",
"null"
]
},
"followers": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"bio": {
"type": [
"string",
"null"
]
},
"company_name": {
"type": [
"string",
"null"
]
},
"last_contacted_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"type": [
"string",
"null"
]
},
"custom_fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Every custom field the workspace defines, in its order, null when the lead has no value for it; then any other key stored on the lead, as stored (an integrations key may write keys the workspace never defined)."
},
"external_id": {
"type": [
"string",
"null"
]
},
"assigned_rep_id": {
"type": [
"string",
"null"
]
},
"is_inbound": {
"type": "boolean"
},
"icp_verdict": {
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "List only: the newest thread's stage, when the key holds conversations:read and may see that thread's rep; null otherwise, and null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stall_reason": {
"description": "List only, under the same condition as setter_stage; null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"campaign": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"count"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "List only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in."
},
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"workspace_id",
"name",
"first_name",
"last_name",
"ig_handle",
"fb_handle",
"profile_url",
"niche",
"followers",
"status",
"notes",
"email",
"phone",
"website",
"bio",
"company_name",
"last_contacted_at",
"tags",
"folder_id",
"custom_fields",
"external_id",
"assigned_rep_id",
"is_inbound",
"icp_verdict",
"setter_stage",
"setter_stall_reason",
"campaign",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"matched_count",
"warnings"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"result": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
},
{
"type": "array",
"items": {
"type": "object",
"properties": {
"row": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"code": {
"type": "string"
}
},
"required": [
"row",
"code"
],
"additionalProperties": false
}
}
]
}
},
{
"type": "null"
}
],
"description": "Counts and short codes only, never lead data. errors_sample names row numbers and codes."
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"started_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"finished_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"confirm_expires_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"result_url": {
"description": "The export's CSV, once the job succeeded.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"kind",
"action",
"status",
"progress",
"queue_position",
"preview",
"result",
"error",
"created_at",
"started_at",
"finished_at",
"confirm_expires_at",
"result_url"
],
"additionalProperties": false
}leads.imports.create
POST/v1/leads/imports
Import up to 30 000 leads as a job, from JSON or a CSV body.
JSON: { leads: [...] } with the fields of POST /v1/leads (ig_handle required on every lead). CSV: send Content-Type: text/csv with on_conflict, folder and tags in the query; headers are the JSON field names, custom_fields.<key> for a custom field, or the headers of DM Hero's own lead export. A header that names no field is refused, except the export's derived columns, which are ignored. Every row is matched on external_id, then the Instagram handle; on_conflict says what a match does (skip, the default, or merge). Poll GET /v1/jobs/{job_id}.
| Operation id | leads.imports.create |
| Scopes | leads:write |
| Rate class | `heavy`, plus leads_created_day, payload_day |
| Idempotency | `Idempotency-Key` required |
| Keys | Developer keys |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
on_conflict | "skip" | "merge" | no | What a row matching an existing lead does.. default "skip" |
folder | string | no | Folder NAME for every row without one, created when missing.. 1 to 80 characters |
tags | string | string[] | no | Tags added to every row: an array, or one comma-separated string. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
leads | object[] | no | JSON import: 1 to 30 000 lead objects, the fields of POST /v1/leads. |
Response 202
| Field | Type | Required | Description |
|---|---|---|---|
action | "update_status" | "add_tags" | "remove_tags" | "set_folder" | "delete" | "enroll" | "unenroll" | "set_custom_fields" | null | yes | |
confirm_expires_at | date-time | null | yes | |
created_at | date-time | yes | |
error | object | null | yes | |
finished_at | date-time | null | yes | |
id | string | yes | |
kind | "leads_import" | "leads_export" | "leads_bulk" | yes | |
preview | object | null | yes | |
progress | object | yes | |
queue_position | integer | null | yes | For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise. |
result | object | null | yes | Counts and short codes only, never lead data. errors_sample names row numbers and codes. |
result_url | string | null | yes | The export's CSV, once the job succeeded. |
started_at | date-time | null | yes | |
status | "awaiting_confirmation" | "queued" | "running" | "succeeded" | "failed" | "cancelled" | "expired" | yes |
Errors
| Status | Code | When |
|---|---|---|
| 400 | `API_IDEMPOTENCY_KEY_REQUIRED_400` | The request carries no Idempotency-Key header. |
| 400 | `IMPORT_CSV_COLUMN_UNSUPPORTED_400` | A CSV header names no lead field; the column is named in the body. |
| 400 | `IMPORT_CSV_INVALID_400` | The CSV cannot be read whole, or has no Instagram handle column. |
| 400 | `IMPORT_EMPTY_400` | The import holds no rows, or both or neither of leads and a CSV body. |
| 400 | `IMPORT_TOO_MANY_ROWS_400` | The import holds more rows than one job takes (30 000; 5 000 for a new organization). |
| 400 | `TAG_INVALID_400` | A tag in the tags parameter is empty or longer than the tag limit. |
| 409 | `JOB_QUEUE_FULL_409` | The organization already has 3 jobs waiting for confirmation, queued or running. |
| 413 | `JOB_PAYLOAD_QUOTA_413` | The organization reached its daily quota of job payload bytes. |
| 429 | `LEADS_DAILY_LIMIT_429` | The organization reached its daily limit of leads created through the API. |
Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.
Example
curl -X POST "https://api.dmhero.ai/v1/leads/imports" \
-H "Authorization: Bearer $DMHERO_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"leads": [
{
"ig_handle": "jane.doe",
"first_name": "Jane",
"external_id": "crm-1042"
},
{
"ig_handle": "john.roe",
"first_name": "John",
"external_id": "crm-1043"
}
]
}'JSON Schema
{
"type": "object",
"properties": {
"leads": {
"description": "JSON import: 1 to 30 000 lead objects, the fields of POST /v1/leads.",
"type": "array",
"items": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
}
}
}{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"leads_import",
"leads_export",
"leads_bulk"
]
},
"action": {
"anyOf": [
{
"type": "string",
"enum": [
"update_status",
"add_tags",
"remove_tags",
"set_folder",
"delete",
"enroll",
"unenroll",
"set_custom_fields"
]
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"awaiting_confirmation",
"queued",
"running",
"succeeded",
"failed",
"cancelled",
"expired"
]
},
"progress": {
"type": "object",
"properties": {
"done": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"total": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"done",
"total"
],
"additionalProperties": false
},
"queue_position": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
],
"description": "For a queued job, its place among this organization's queued jobs (1 runs next); null otherwise."
},
"preview": {
"anyOf": [
{
"type": "object",
"properties": {
"matched_count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"warnings": {
"type": "array",
"items": {
"type": "string"
}
},
"sample": {
"description": "In the preview response only, never stored.",
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"workspace_id": {
"type": "string"
},
"name": {
"type": "string"
},
"first_name": {
"type": [
"string",
"null"
]
},
"last_name": {
"type": [
"string",
"null"
]
},
"ig_handle": {
"type": [
"string",
"null"
]
},
"fb_handle": {
"type": [
"string",
"null"
]
},
"profile_url": {
"type": [
"string",
"null"
]
},
"niche": {
"type": [
"string",
"null"
]
},
"followers": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
},
"status": {
"type": "string",
"enum": [
"new",
"contacted",
"replied",
"converted",
"not_interested",
"not_found"
]
},
"notes": {
"type": [
"string",
"null"
]
},
"email": {
"type": [
"string",
"null"
]
},
"phone": {
"type": [
"string",
"null"
]
},
"website": {
"type": [
"string",
"null"
]
},
"bio": {
"type": [
"string",
"null"
]
},
"company_name": {
"type": [
"string",
"null"
]
},
"last_contacted_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"tags": {
"type": "array",
"items": {
"type": "string"
}
},
"folder_id": {
"type": [
"string",
"null"
]
},
"custom_fields": {
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"type": [
"string",
"null"
]
},
"description": "Every custom field the workspace defines, in its order, null when the lead has no value for it; then any other key stored on the lead, as stored (an integrations key may write keys the workspace never defined)."
},
"external_id": {
"type": [
"string",
"null"
]
},
"assigned_rep_id": {
"type": [
"string",
"null"
]
},
"is_inbound": {
"type": "boolean"
},
"icp_verdict": {
"type": [
"string",
"null"
]
},
"setter_stage": {
"description": "List only: the newest thread's stage, when the key holds conversations:read and may see that thread's rep; null otherwise, and null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"setter_stall_reason": {
"description": "List only, under the same condition as setter_stage; null when the plan does not include the AI Setter.",
"type": [
"string",
"null"
]
},
"campaign": {
"anyOf": [
{
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"count": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
}
},
"required": [
"id",
"name",
"count"
],
"additionalProperties": false
},
{
"type": "null"
}
],
"description": "List only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in."
},
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"updated_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
},
"required": [
"id",
"workspace_id",
"name",
"first_name",
"last_name",
"ig_handle",
"fb_handle",
"profile_url",
"niche",
"followers",
"status",
"notes",
"email",
"phone",
"website",
"bio",
"company_name",
"last_contacted_at",
"tags",
"folder_id",
"custom_fields",
"external_id",
"assigned_rep_id",
"is_inbound",
"icp_verdict",
"setter_stage",
"setter_stall_reason",
"campaign",
"created_at",
"updated_at"
],
"additionalProperties": false
}
}
},
"required": [
"matched_count",
"warnings"
],
"additionalProperties": false
},
{
"type": "null"
}
]
},
"result": {
"anyOf": [
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {
"anyOf": [
{
"type": "number"
},
{
"type": "string"
},
{
"type": "null"
},
{
"type": "array",
"items": {
"type": "object",
"properties": {
"row": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"code": {
"type": "string"
}
},
"required": [
"row",
"code"
],
"additionalProperties": false
}
}
]
}
},
{
"type": "null"
}
],
"description": "Counts and short codes only, never lead data. errors_sample names row numbers and codes."
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": {
"type": "string"
},
"message": {
"type": "string"
}
},
"required": [
"code",
"message"
],
"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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"started_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"finished_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"confirm_expires_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|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
{
"type": "null"
}
]
},
"result_url": {
"description": "The export's CSV, once the job succeeded.",
"type": [
"string",
"null"
]
}
},
"required": [
"id",
"kind",
"action",
"status",
"progress",
"queue_position",
"preview",
"result",
"error",
"created_at",
"started_at",
"finished_at",
"confirm_expires_at",
"result_url"
],
"additionalProperties": false
}