Leads API
POST /api/v1/leads
Push a single lead into the CRM. This is the server-side counterpart of the embeddable lead form — use it from your own website backend, a landing-page service, or an ad-platform webhook relay.
Requires the write:leads scope (or a full-access key).
Request
POST /api/v1/leads HTTP/1.1
Host: agentlyleads.com
Authorization: Bearer alk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json
{
"name": "Jane Buyer",
"email": "jane@acme.com",
"phone": "+1 555 0100",
"company": "Acme Inc.",
"source": "Landing page",
"sourceDetail": "https://acme.com/pricing",
"message": "Do you ship to Canada?"
}| Field | Required | Notes |
|---|---|---|
name | Yes | Full name, 1–200 chars. |
email | No | Valid email, max 254 chars. Dedupe key — see below. |
phone | No | Any format, max 50 chars. |
company | No | Free text, max 200 chars. Matched to a CRM Company at conversion. |
source | No | Attribution label, max 200 chars (e.g. "Landing page"). |
sourceDetail | No | Attribution detail, max 500 chars (e.g. the page URL). Stored on the lead's notes as Source detail: …. |
message | No | Max 10,000 chars. Logged as a Communication NOTE on the lead's activity timeline, attributed to the workspace owner. |
Dedupe: create vs. update
Leads are matched by email, case-insensitively:
- No
email, or no existing lead with that email → a new lead is created with statusNEW. - A lead with that email already exists → the non-empty incoming fields are merged onto it. Empty or omitted fields never overwrite existing values, so repeat captures enrich a lead instead of clobbering it.
Creating a lead fires your workspace's LEAD / CREATED workflows — round-robin assignment, auto-tagging, and notify-on-new-lead rules apply to API-captured leads automatically.
Response — 201 (created)
{
"lead": {
"id": "cmq5lead0alk34567890",
"name": "Jane Buyer",
"email": "jane@acme.com",
"phone": "+1 555 0100",
"company": "Acme Inc.",
"source": "Landing page",
"status": "NEW",
"estimatedInterest": "MEDIUM",
"notes": "Source detail: https://acme.com/pricing",
"createdAt": "2026-07-22T09:30:00.000Z",
"updatedAt": "2026-07-22T09:30:00.000Z"
}
}Response — 200 (updated)
When the email matched an existing lead:
{
"lead": { "id": "cmq5lead0alk34567890", "name": "Jane Buyer", "...": "..." },
"updated": true
}Errors
| Status | Meaning |
|---|---|
400 | Missing/invalid body — e.g. {"error": "name is required."}. |
401 | Missing, invalid, or expired API key. |
403 | Key lacks the write:leads scope. |
429 | Rate limited (per-key limit, plus a per key + IP limit on this endpoint). Retry after the Retry-After header value in seconds. |
Example: cURL
curl -X POST https://agentlyleads.com/api/v1/leads \
-H "Authorization: Bearer $AGENTLYLEADS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Jane Buyer", "email": "jane@acme.com", "source": "Landing page"}'