Sending Leads In
Push leads into ABC Sales AI from your own systems (forms, CRMs, landing pages) with the lead intake endpoint:
POST /v1/webhooks/leads
This is the inbound path: you send leads to ABC Sales AI. It is different from Webhooks, which is the outbound path where ABC Sales AI notifies your system about events.
To send a form on your website straight to ABC Sales AI without a backend of your own, use Website Forms. This endpoint needs your API key, which must never be put in page source.
custom_fields, automations, and tags all reference things configured on your company account. Use the Discovery endpoints to list valid custom-field keys, automation slugs, and existing tags before you build your payload.
Request
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",
"email": "jane@example.com",
"phone": "+60123456789",
"id": "your-external-id-123",
"source": "landing-page",
"tags": ["pricing-page"],
"timezone": "Asia/Kuala_Lumpur",
"locale": "en",
"currency": "MYR",
"custom_fields": { "plan_interest": "scale" }
}'
Fields
| Field | Required | Notes |
|---|---|---|
name | Yes | 2 to 100 characters. |
email | No | |
phone | No | Up to 50 characters. Unparseable numbers are kept raw and tagged for review rather than rejected. |
id | No | Your external lead ID (up to 50 chars). Used as the upsert key, so resending the same id updates the existing lead instead of creating a duplicate. |
naver_line_id | No | LINE user ID, used as a lookup/upsert identifier for LINE-channel leads. Takes precedence over phone when both are supplied. |
source | No | Free-text source label. |
tags | No | Array of strings. Free-text: an unknown tag is created on the fly. List existing ones with Discovery. To remove tags later, see Managing Leads. |
timezone, locale, currency | No | |
handled_by_ai | No | Boolean. Whether the AI replies to the lead. Applies only when this call creates the lead (omitted means true); an existing lead keeps its setting. To change it later, use PUT /v1/leads/{leadID}/ai-handling. |
custom_fields | No | Object keyed by the json_key of a custom field configured on your account. See below. |
automations | No | subscribe / unsubscribe / replace, each an array of automation slug_ids. replace cannot be combined with the other two. |
user_assignments | No | assign / unassign / replace. replace cannot be combined with the other two. See the API Reference. |
Custom fields
Every key must match a json_key from GET /v1/custom-fields, and its value must match that field's declared type. An unknown key, or a value of the wrong type, returns 400 and rejects the whole lead, so nothing is partially saved. A key with a null value is skipped rather than rejected.
For a custom field of type file, the value is the s3_path of a file you uploaded first. See Attachments.
Automations
Automation slug_ids that don't exist are silently ignored: the request still returns 202 and the lead is still created, just without the subscription. Nothing surfaces the mismatch, so verify slugs against GET /v1/automations rather than relying on the response.
The same applies to user_assignments: user IDs that don't resolve to a user in your company are dropped rather than failing the request, so one bad ID can't lose an otherwise valid lead.
Response
The endpoint processes leads asynchronously and returns 202 Accepted once the payload is queued (it may return 200/201 when processed synchronously). The lead is created or updated out of band.
The 202 body returns the lead's external ID in data.id: the id you sent, or one we generate when you omit it.
{"data": {"id": "your-external-id-123", "status": "accepted"}}
Use that data.id straight away as {leadID} on the lead endpoints, for example to remove tags or turn AI replies off. Because the lead is created a moment after the 202, a follow-up call made immediately may return 404 for a few seconds; retry with a short backoff. See Managing Leads.
Because id is an upsert key, sending the same external id again is safe and idempotent.
Rate limit
This endpoint is rate limited to 300 requests per minute per company. On exceed it returns 429 with a Retry-After header.
The request body is also capped at 4 MB; a larger payload is rejected with 413 before the lead is queued. See Rate Limits.