Menu

Reference

Leads

Leads: 9 operations (leads.list, leads.upsert, leads.get, leads.update, leads.delete, leads.tags.add, leads.tags.remove, leads.lookup, tags.list).

Every lead carries custom_fields, one entry per field the workspace defines, and GET /v1/leads filters on them with cf.<key> query keys. See Custom fields for reading, writing and filtering.

MethodPathOperation
GET/v1/leadsleads.list
POST/v1/leadsleads.upsert
GET/v1/leads/{lead_id}leads.get
PATCH/v1/leads/{lead_id}leads.update
DELETE/v1/leads/{lead_id}leads.delete
POST/v1/leads/{lead_id}/tagsleads.tags.add
DELETE/v1/leads/{lead_id}/tags/{tag}leads.tags.remove
GET/v1/leads/lookupleads.lookup
GET/v1/tagstags.list

leads.list

GET/v1/leads

List the workspace's leads, newest first, with filters.

Keyset pagination: pass next_cursor as cursor with the same filters and order. order=updated_at_asc with updated_after is the incremental sync. Custom fields filter with query keys that start with cf.: cf.<key>=<text> (equals, trimmed, ignoring case), cf.<key>.contains=<text> (substring, ignoring case, every character literal), cf.<key>.present=true (has a non-blank value), cf.<key>.missing=true (no value or a blank one). Conditions AND together with each other and every other filter; at most 5; each key must be one the workspace defines (GET /v1/custom-fields), else 400 CUSTOM_FIELD_UNKNOWN_400; a value is at most 500 characters.

Operation idleads.list
Scopesleads:read
Rate class`read`
IdempotencyNot applicable
KeysDeveloper keys

Query parameters

NameTypeRequiredDescription
limitintegerno1 to 200, default 50
cursorstringno1 to 2048 characters
status"new" | "contacted" | "replied" | "converted" | "not_interested" | "not_found"no
tagstringno1 to 100 characters
nichestringno1 to 200 characters
folder_idstringnoA folder id, or none for leads in no folder.. 1 to 200 characters
searchstringnoCase-insensitive match on name, handles and notes.. 1 to 200 characters
external_idstringno1 to 255 characters
ig_handlestringnoMatched case-insensitively, a leading @ ignored.. 1 to 100 characters
created_afterdate-timeno
created_beforedate-timeno
updated_afterdate-timeno
exclude_inboundbooleanno
campaign_idstringnoLeads enrolled in this campaign.. 1 to 200 characters
enrollment"any" | "none"noLeads in at least one campaign (any) or in none.
order"created_at" | "updated_at" | "updated_at_asc"nodefault "created_at"
cf.{key}stringno

Response 200

FieldTypeRequiredDescription
dataobject[]yes
has_morebooleanyes
next_cursorstring | nullyes

Errors

StatusCodeWhen
400`CUSTOM_FIELD_UNKNOWN_400`A cf.<key> condition names a key this workspace has not defined.
404`CAMPAIGN_NOT_FOUND_404`campaign_id names no campaign of this workspace.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/leads" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "type": "object",
  "properties": {
    "data": {
      "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
      }
    },
    "has_more": {
      "type": "boolean"
    },
    "next_cursor": {
      "type": [
        "string",
        "null"
      ]
    }
  },
  "required": [
    "data",
    "has_more",
    "next_cursor"
  ],
  "additionalProperties": false
}

leads.upsert

POST/v1/leads

Create or update one lead, or a batch of up to 100.

Matches on external_id, then the Instagram handle. on_conflict decides what a match does: merge (default), skip, or error (409 LEAD_EXISTS_409, a create-only call). A batch runs one lead per transaction and reports each item in place.

Operation idleads.upsert
Scopesleads:write
Rate class`write`, plus leads_created_day
Idempotency`Idempotency-Key` accepted
KeysDeveloper keys and Clay compatible keys

Request body

FieldTypeRequiredDescription
custom_fieldsanyno{ key: value } of the workspace's custom fields.
emailanyno
external_idanyno
fb_handleanyno
first_nameanyno
folderanynoFolder NAME, created when missing.
followersanynoA number, or a numeric string.
ig_handleanynoRequired for every lead: the matching key.
last_nameanyno
leadsanynoA batch: an array of 1 to 100 lead objects. Omit for one lead.
mergeanynofill_empty (default) or overwrite.
nameanyno
nicheanyno
notesanyno
on_conflict"merge" | "skip" | "error"no
phoneanyno
profile_urlanyno
tagsanynoAn array of tags or one comma-separated string, at most 20.

Response 200

JSON of type object.

Errors

StatusCodeWhen
400`CUSTOM_FIELD_UNKNOWN_400`custom_fields names a key this workspace has not defined. Create it with POST /v1/custom-fields first.
400`LEADS_BATCH_TOO_LARGE_400`The batch holds more than 100 leads.
409`LEAD_AMBIGUOUS_409`More than one lead in this workspace has that Instagram handle.
409`LEAD_EXISTS_409`on_conflict is error and the lead already exists.
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

bash
curl -X POST "https://api.dmhero.ai/v1/leads" \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "ig_handle": "jane.doe",
  "first_name": "Jane",
  "last_name": "Doe",
  "external_id": "crm-1042",
  "tags": [
    "webinar"
  ]
}'
JSON Schema
Request body
{
  "type": "object",
  "properties": {
    "ig_handle": {
      "description": "Required for every lead: the matching key."
    },
    "name": {},
    "first_name": {},
    "last_name": {},
    "fb_handle": {},
    "profile_url": {},
    "niche": {},
    "followers": {
      "description": "A number, or a numeric string."
    },
    "notes": {},
    "tags": {
      "description": "An array of tags or one comma-separated string, at most 20."
    },
    "folder": {
      "description": "Folder NAME, created when missing."
    },
    "custom_fields": {
      "description": "{ key: value } of the workspace's custom fields."
    },
    "external_id": {},
    "email": {},
    "phone": {},
    "merge": {
      "description": "fill_empty (default) or overwrite."
    },
    "leads": {
      "description": "A batch: an array of 1 to 100 lead objects. Omit for one lead."
    },
    "on_conflict": {
      "type": "string",
      "enum": [
        "merge",
        "skip",
        "error"
      ]
    }
  }
}
Response 200
{
  "anyOf": [
    {
      "type": "object",
      "properties": {
        "lead_id": {
          "type": "string"
        },
        "result": {
          "type": "string",
          "enum": [
            "created",
            "updated",
            "unchanged",
            "skipped"
          ]
        },
        "updated_fields": {
          "type": "array",
          "items": {
            "type": "string"
          }
        },
        "lead_status": {
          "type": "string"
        }
      },
      "required": [
        "lead_id",
        "result",
        "updated_fields",
        "lead_status"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "results": {
          "type": "array",
          "items": {
            "anyOf": [
              {
                "type": "object",
                "properties": {
                  "lead_id": {
                    "type": "string"
                  },
                  "result": {
                    "type": "string",
                    "enum": [
                      "created",
                      "updated",
                      "unchanged",
                      "skipped"
                    ]
                  },
                  "updated_fields": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "lead_status": {
                    "type": "string"
                  },
                  "index": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  }
                },
                "required": [
                  "lead_id",
                  "result",
                  "updated_fields",
                  "lead_status",
                  "index"
                ],
                "additionalProperties": false
              },
              {
                "type": "object",
                "properties": {
                  "index": {
                    "type": "integer",
                    "minimum": -9007199254740991,
                    "maximum": 9007199254740991
                  },
                  "error": {
                    "type": "string"
                  },
                  "message": {
                    "type": "string"
                  },
                  "code": {
                    "type": "string"
                  },
                  "lead_id": {
                    "type": "string"
                  },
                  "fields": {
                    "type": "object",
                    "propertyNames": {
                      "type": "string"
                    },
                    "additionalProperties": {
                      "type": "string"
                    }
                  }
                },
                "required": [
                  "index",
                  "error",
                  "message",
                  "code"
                ],
                "additionalProperties": false
              }
            ]
          }
        }
      },
      "required": [
        "results"
      ],
      "additionalProperties": false
    },
    {
      "type": "object",
      "properties": {
        "replayed": {
          "type": "boolean",
          "const": true
        },
        "status": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "ids": {
          "type": "object",
          "propertyNames": {
            "type": "string"
          },
          "additionalProperties": {
            "type": "string"
          }
        }
      },
      "required": [
        "replayed",
        "status",
        "ids"
      ],
      "additionalProperties": false
    }
  ]
}

leads.get

GET/v1/leads/{lead_id}

One lead. The ETag header is the version PATCH accepts as If-Match.

Operation idleads.get
Scopesleads:read
Rate class`read`
IdempotencyNot applicable
KeysDeveloper keys

Path parameters

NameTypeRequiredDescription
lead_idstringyesThe lead id.. 1 to 200 characters

Response 200

FieldTypeRequiredDescription
assigned_rep_idstring | nullyes
biostring | nullyes
campaignobject | nullyesList only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in.
company_namestring | nullyes
created_atdate-timeyes
custom_fieldsobjectyesEvery 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).
emailstring | nullyes
external_idstring | nullyes
fb_handlestring | nullyes
first_namestring | nullyes
folder_idstring | nullyes
followersinteger | nullyes
icp_verdictstring | nullyes
idstringyes
ig_handlestring | nullyes
is_inboundbooleanyes
last_contacted_atdate-time | nullyes
last_namestring | nullyes
namestringyes
nichestring | nullyes
notesstring | nullyes
phonestring | nullyes
profile_urlstring | nullyes
setter_stagestring | nullyesList 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.
setter_stall_reasonstring | nullyesList only, under the same condition as setter_stage; null when the plan does not include the AI Setter.
status"new" | "contacted" | "replied" | "converted" | "not_interested" | "not_found"yes
tagsstring[]yes
updated_atdate-timeyes
websitestring | nullyes
workspace_idstringyes

Errors

StatusCodeWhen
404`LEAD_NOT_FOUND_404`No lead with this id exists in this workspace.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/leads/string" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "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
}

leads.update

PATCH/v1/leads/{lead_id}

Change a lead's fields. Send If-Match with the ETag you read to refuse a concurrent change.

Operation idleads.update
Scopesleads:write
Rate class`write`
IdempotencyNot applicable
KeysDeveloper keys

Path parameters

NameTypeRequiredDescription
lead_idstringyesThe lead id.. 1 to 200 characters

Request body

FieldTypeRequiredDescription
assigned_rep_idstring | nullnoA rep this key may use, or null.
custom_fieldsobjectno{ key: value | null }; null removes the value. Keys the request does not name are left alone.
emailstring | nullno
fb_handlestring | nullno
folder_idstring | nullnonull leaves the lead in no folder.
followersinteger | nullno
ig_handlestring | nullno
namestringno
nichestring | nullno
notesstring | nullno
phonestring | nullno
profile_urlstring | nullno
status"new" | "contacted" | "replied" | "converted" | "not_interested" | "not_found"no

Response 200

FieldTypeRequiredDescription
assigned_rep_idstring | nullyes
biostring | nullyes
campaignobject | nullyesList only: the campaign that matters (a live enrollment first, then the newest) and how many the lead is in.
company_namestring | nullyes
created_atdate-timeyes
custom_fieldsobjectyesEvery 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).
emailstring | nullyes
external_idstring | nullyes
fb_handlestring | nullyes
first_namestring | nullyes
folder_idstring | nullyes
followersinteger | nullyes
icp_verdictstring | nullyes
idstringyes
ig_handlestring | nullyes
is_inboundbooleanyes
last_contacted_atdate-time | nullyes
last_namestring | nullyes
namestringyes
nichestring | nullyes
notesstring | nullyes
phonestring | nullyes
profile_urlstring | nullyes
setter_stagestring | nullyesList 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.
setter_stall_reasonstring | nullyesList only, under the same condition as setter_stage; null when the plan does not include the AI Setter.
status"new" | "contacted" | "replied" | "converted" | "not_interested" | "not_found"yes
tagsstring[]yes
updated_atdate-timeyes
websitestring | nullyes
workspace_idstringyes

Errors

StatusCodeWhen
400`CUSTOM_FIELD_UNKNOWN_400`custom_fields names a key this workspace has not defined. Create it with POST /v1/custom-fields first.
404`FOLDER_NOT_FOUND_404`No folder with this id exists in this workspace.
404`LEAD_NOT_FOUND_404`No lead with this id exists in this workspace.
404`REP_NOT_FOUND_404`No rep with this id or username that this API key may use.
412`LEAD_PRECONDITION_FAILED_412`If-Match does not match: the lead changed since you read it.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X PATCH "https://api.dmhero.ai/v1/leads/string" \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "ig_handle": "string",
  "fb_handle": "string",
  "profile_url": "string",
  "niche": "string",
  "followers": 0,
  "notes": "string",
  "status": "new",
  "email": "string",
  "phone": "string",
  "assigned_rep_id": "string",
  "folder_id": "string",
  "custom_fields": {}
}'
JSON Schema
Request body
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string"
    },
    "ig_handle": {
      "type": [
        "string",
        "null"
      ]
    },
    "fb_handle": {
      "type": [
        "string",
        "null"
      ]
    },
    "profile_url": {
      "type": [
        "string",
        "null"
      ]
    },
    "niche": {
      "type": [
        "string",
        "null"
      ]
    },
    "followers": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": 0,
          "maximum": 2147483647
        },
        {
          "type": "null"
        }
      ]
    },
    "notes": {
      "type": [
        "string",
        "null"
      ]
    },
    "status": {
      "type": "string",
      "enum": [
        "new",
        "contacted",
        "replied",
        "converted",
        "not_interested",
        "not_found"
      ]
    },
    "email": {
      "type": [
        "string",
        "null"
      ]
    },
    "phone": {
      "type": [
        "string",
        "null"
      ]
    },
    "assigned_rep_id": {
      "description": "A rep this key may use, or null.",
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        {
          "type": "null"
        }
      ]
    },
    "folder_id": {
      "description": "null leaves the lead in no folder.",
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        {
          "type": "null"
        }
      ]
    },
    "custom_fields": {
      "description": "{ key: value | null }; null removes the value. Keys the request does not name are left alone.",
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": [
          "string",
          "null"
        ]
      }
    }
  }
}
Response 200
{
  "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
}

leads.delete

DELETE/v1/leads/{lead_id}

Delete a lead, its tags and its enrollments.

Operation idleads.delete
Scopesleads:delete
Rate class`write`
IdempotencyNot applicable
KeysDeveloper keys
DestructiveYes: it removes or stops something that cannot be restored by repeating the call

Path parameters

NameTypeRequiredDescription
lead_idstringyesThe lead id.. 1 to 200 characters

Response 204

No body.

Errors

StatusCodeWhen
404`LEAD_NOT_FOUND_404`No lead with this id exists in this workspace.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X DELETE "https://api.dmhero.ai/v1/leads/string" \
  -H "Authorization: Bearer $DMHERO_API_KEY"

leads.tags.add

POST/v1/leads/{lead_id}/tags

Add tags to a lead. Tags it already has are left as they are.

Operation idleads.tags.add
Scopesleads:write
Rate class`write`
Idempotency`Idempotency-Key` accepted
KeysDeveloper keys

Path parameters

NameTypeRequiredDescription
lead_idstringyesThe lead id.. 1 to 200 characters

Request body

FieldTypeRequiredDescription
tagsstring[]yes1 to 20 items

Response 200

FieldTypeRequiredDescription
lead_idstringyes
tagsstring[]yes

Errors

StatusCodeWhen
400`TAG_INVALID_400`A tag is empty or longer than the tag limit.
404`LEAD_NOT_FOUND_404`No lead with this id exists in this workspace.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X POST "https://api.dmhero.ai/v1/leads/string/tags" \
  -H "Authorization: Bearer $DMHERO_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "tags": [
    "string"
  ]
}'
JSON Schema
Request body
{
  "type": "object",
  "properties": {
    "tags": {
      "minItems": 1,
      "maxItems": 20,
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": [
    "tags"
  ]
}
Response 200
{
  "type": "object",
  "properties": {
    "lead_id": {
      "type": "string"
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": [
    "lead_id",
    "tags"
  ],
  "additionalProperties": false
}

leads.tags.remove

DELETE/v1/leads/{lead_id}/tags/{tag}

Remove one tag from a lead (URL-encode the tag). Removing a tag the lead does not have is not an error.

Operation idleads.tags.remove
Scopesleads:write
Rate class`write`
IdempotencyNot applicable
KeysDeveloper keys

Path parameters

NameTypeRequiredDescription
lead_idstringyesThe lead id.. 1 to 200 characters
tagstringyes1 to 200 characters

Response 204

No body.

Errors

StatusCodeWhen
400`TAG_INVALID_400`A tag is empty or longer than the tag limit.
404`LEAD_NOT_FOUND_404`No lead with this id exists in this workspace.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl -X DELETE "https://api.dmhero.ai/v1/leads/string/tags/string" \
  -H "Authorization: Bearer $DMHERO_API_KEY"

leads.lookup

GET/v1/leads/lookup

Where the lead with this Instagram handle stands: status, setter stage, tags, campaign.

Operation idleads.lookup
Scopesleads:read
Rate class`read`
IdempotencyNot applicable
KeysDeveloper keys and Clay compatible keys

Query parameters

NameTypeRequiredDescription
ig_handleanynoRequired. At most 30 characters, a leading @ ignored.

Response 200

FieldTypeRequiredDescription
campaign_idstring | nullyes
campaign_statusstring | nullyes
current_stepinteger | nullyes
last_contacted_atdate-time | nullyes
lead_idstringyes
setter_stagestring | nullyesNull when the plan does not include the AI Setter.
setter_stall_reasonstring | nullyesNull when the plan does not include the AI Setter.
statusstringyes
tagsstring[]yes

Errors

StatusCodeWhen
404`LEAD_NOT_FOUND_404`No lead with that Instagram handle in this API key's workspace.
409`LEAD_AMBIGUOUS_409`More than one lead in this workspace has that Instagram handle.

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/leads/lookup?ig_handle=jane.doe" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "type": "object",
  "properties": {
    "lead_id": {
      "type": "string"
    },
    "status": {
      "type": "string"
    },
    "setter_stage": {
      "description": "Null when the plan does not include the AI Setter.",
      "type": [
        "string",
        "null"
      ]
    },
    "setter_stall_reason": {
      "description": "Null when the plan does not include the AI Setter.",
      "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"
      }
    },
    "campaign_id": {
      "type": [
        "string",
        "null"
      ]
    },
    "campaign_status": {
      "type": [
        "string",
        "null"
      ]
    },
    "current_step": {
      "anyOf": [
        {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        {
          "type": "null"
        }
      ]
    }
  },
  "required": [
    "lead_id",
    "status",
    "setter_stage",
    "setter_stall_reason",
    "last_contacted_at",
    "tags",
    "campaign_id",
    "campaign_status",
    "current_step"
  ],
  "additionalProperties": false
}

tags.list

GET/v1/tags

Every tag used on the workspace's leads, alphabetical.

Operation idtags.list
Scopesleads:read
Rate class`read`
IdempotencyNot applicable
KeysDeveloper keys

Response 200

FieldTypeRequiredDescription
datastring[]yes

Errors

Every operation can also answer the shared errors: authentication, scopes, rate limits and validation.

Example

bash
curl "https://api.dmhero.ai/v1/tags" \
  -H "Authorization: Bearer $DMHERO_API_KEY"
JSON Schema
Response 200
{
  "type": "object",
  "properties": {
    "data": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  },
  "required": [
    "data"
  ],
  "additionalProperties": false
}
Leads | DM Hero Developers