Discovery
Before you send leads in, you need to know what your company's account actually accepts: which custom fields exist, which automations a lead can be subscribed to, and which tags are already in use. The discovery endpoints return exactly that, scoped to the company that owns your API key.
These are read-only GET endpoints and take no parameters.
POST /v1/webhooks/leads is strict about custom_fields (an unknown key rejects the whole request) and silent about automations (an unknown slug is ignored, and you still get a 202). Looking values up here first is the difference between a lead landing correctly and a lead landing incomplete without telling you.
Custom fields
curl "https://api.abcsalesbot.com/v1/custom-fields" \
-H "Authorization: Bearer $ABC_API_KEY"
{
"data": [
{
"json_key": "plan_interest",
"name": "Plan interest",
"type": "text",
"required": false
},
{
"json_key": "candidate_resume",
"name": "Resume",
"type": "file",
"required": true
}
]
}
| Field | Description |
|---|---|
json_key | The key to use inside the custom_fields object when creating a lead. |
name | Human-readable label as configured in the app. |
type | One of text, number, timestamp, file. |
required | Whether the field is mandatory for your company. |
Type rules
The lead webhook validates every custom_fields entry against this list and returns 400 on the first violation, rejecting the entire lead. It does not partially accept a payload.
type | Accepted JSON value |
|---|---|
text | A string. |
number | A JSON number, or a string that parses as one (42 or "42"). |
timestamp | A string in an accepted date format. |
file | A string holding the S3 path of a confirmed upload. See Attachments. |
A key whose value is null is skipped rather than rejected. A key not in this list is rejected.
Automations
curl "https://api.abcsalesbot.com/v1/automations" \
-H "Authorization: Bearer $ABC_API_KEY"
{
"data": [
{
"slug_id": "welcome-sequence",
"name": "Welcome sequence",
"enabled": true,
"status": "ACTIVE"
}
]
}
Use slug_id under automations.subscribe, automations.unsubscribe, or automations.replace when creating a lead.
| Field | Description |
|---|---|
slug_id | The identifier to send in the lead payload. |
name | Human-readable name as configured in the app. |
enabled | Whether the automation is switched on. |
status | One of ACTIVE, DISABLED, CANCELLED, FINISHED. |
An automation can be enabled: true and still be inert because its status is FINISHED or CANCELLED. Check status when you want to know whether subscribing a lead will actually do something.
Unknown slug ids are silently ignored by the lead webhook: the request still succeeds with 202 and the lead is created, just without that subscription. There is no error to catch, which is why looking slugs up here is worth doing.
Tags
curl "https://api.abcsalesbot.com/v1/tags" \
-H "Authorization: Bearer $ABC_API_KEY"
{
"data": ["pricing-page", "webinar-q3", "inbound-call"]
}
A flat list of the lead tags your company already uses. Tags are free-text, so passing a value that is not on this list simply creates it. This endpoint exists so you can reuse an existing tag instead of introducing a near-duplicate (webinar-q3 alongside Webinar Q3).
Putting it together
A typical integration calls these three endpoints once at setup (or caches them and refreshes periodically), then builds its lead payload from the result:
curl -X POST "https://api.abcsalesbot.com/v1/webhooks/leads" \
-H "Authorization: Bearer $ABC_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Doe",
"phone": "+60123456789",
"tags": ["pricing-page"],
"custom_fields": { "plan_interest": "scale" },
"automations": { "subscribe": ["welcome-sequence"] }
}'
See Sending Leads In for the full lead payload, and the API Reference for the complete response schemas.