Send in a lead
const url = 'https://api.threadkite.app/v1/leads';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"contact":{"contactId":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","externalId":{"integration":"my-dms","externalId":"CUST-10442"},"name":"Sarah Turner","email":"sarah.turner@example.co.uk","phone":"07911 123456","company":{"id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","name":"Acme Fleet Services","domain":"acme.co.uk","companyNumber":"01234567","externalId":{"integration":"my-dms","externalId":"CUST-10442"},"jobTitle":"Head of Transport","role":"Director"}},"source":"website-form","sourceId":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","channel":"form","inboxId":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","locationId":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","items":[{"id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","source":"my-dms","externalId":"example","identifier":"SKU-1042","label":"Tow bar","quantity":1,"addOns":[{"id":"2489E9AD-2EE2-8E00-8EC9-32D5F69181C0","source":"my-dms","externalId":"example","identifier":"SKU-1042","label":"Tow bar","quantity":1}]}],"leadType":"finance","subject":"example","message":"","consent":{"channels":{"email":"opted_in","sms":"opted_in","whatsapp":"opted_in","phone":"opted_in"},"categories":["marketing_email"],"version":"example"},"tracking":{"landingPageUrl":"example","referrer":"example","utmSource":"google","utmMedium":"cpc","utmCampaign":"example","utmTerm":"example","utmContent":"example","utmId":"example","clickId":"gclid:Cj0KCQjw","analyticsCorrelation":"example"},"fields":{"additionalProperty":"example"},"externalId":"example","receivedAt":"2026-04-15T12:00:00Z"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.threadkite.app/v1/leads \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "contact": { "contactId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "externalId": { "integration": "my-dms", "externalId": "CUST-10442" }, "name": "Sarah Turner", "email": "sarah.turner@example.co.uk", "phone": "07911 123456", "company": { "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "name": "Acme Fleet Services", "domain": "acme.co.uk", "companyNumber": "01234567", "externalId": { "integration": "my-dms", "externalId": "CUST-10442" }, "jobTitle": "Head of Transport", "role": "Director" } }, "source": "website-form", "sourceId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "channel": "form", "inboxId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "locationId": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "items": [ { "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "source": "my-dms", "externalId": "example", "identifier": "SKU-1042", "label": "Tow bar", "quantity": 1, "addOns": [ { "id": "2489E9AD-2EE2-8E00-8EC9-32D5F69181C0", "source": "my-dms", "externalId": "example", "identifier": "SKU-1042", "label": "Tow bar", "quantity": 1 } ] } ], "leadType": "finance", "subject": "example", "message": "", "consent": { "channels": { "email": "opted_in", "sms": "opted_in", "whatsapp": "opted_in", "phone": "opted_in" }, "categories": [ "marketing_email" ], "version": "example" }, "tracking": { "landingPageUrl": "example", "referrer": "example", "utmSource": "google", "utmMedium": "cpc", "utmCampaign": "example", "utmTerm": "example", "utmContent": "example", "utmId": "example", "clickId": "gclid:Cj0KCQjw", "analyticsCorrelation": "example" }, "fields": { "additionalProperty": "example" }, "externalId": "example", "receivedAt": "2026-04-15T12:00:00Z" }'Finds the contact (your id, then email, then phone) or adds one, adds the message to their thread in the inbox you name (inboxId, else the default inbox) and applies the lead rule: it is a new lead unless the same contact, source and item sent one to that inbox within your lead period. Send an Idempotency-Key header, or an externalId, so retries never create a second lead.
Authorizations
Section titled “Authorizations”Request Bodyrequired
Section titled “Request Bodyrequired”object
object
A Threadkite contact id, if you have it
The contact’s id in your system
object
The other system, e.g. my-dms
Example
my-dmsThe contact’s id there
Example
CUST-10442Example
Sarah TurnerExample
sarah.turner@example.co.ukExample
07911 123456The company they work for, found or made (see CompanyCaptureDto): linked as their primary company when they have none
object
One of your companies
Its name: the company with that name, or a new one when nothing else finds one
Example
Acme Fleet ServicesIts web domain (or website address): finds the company with it
Example
acme.co.ukIts registered number (Companies House)
Example
01234567The company’s id in your system
object
The other system, e.g. my-dms
Example
my-dmsThe contact’s id there
Example
CUST-10442Their job title there
Example
Head of TransportWhat they do for the company, in your words
Example
DirectorSource key; created if new, e.g. website-form or google-ads
Example
website-formOr a source id
The inbox the lead goes to (Sales, Service…). The default inbox when left out; a key limited to inboxes must name one of them, or its first when the default is not one
What the lead is about, main item first: catalogue items or free-text lines, each with its add-ons
object
A Threadkite item id
The item’s source, with externalId
Example
my-dmsThe item’s id in that source
An identifier on the item, matched exactly (a SKU or a pack identifier)
Example
SKU-1042A free-text line, when it is not in the catalogue
Example
Tow barAdded to this item (a warranty, delivery, build options)
object
A Threadkite item id
The item’s source, with externalId
Example
my-dmsThe item’s id in that source
An identifier on the item, matched exactly (a SKU or a pack identifier)
Example
SKU-1042A free-text line, when it is not in the catalogue
Example
Tow barExample
financeExample
Is this still available?object
object
Example
[ "marketing_email"]The wording version shown
object
Example
googleExample
cpcThe ad platform’s campaign id (utm_id)
The ad click id as kind:value, where kind is gclid, gbraid, wbraid, msclkid, fbclid or ttclid
Example
gclid:Cj0KCQjwAnalytics visitor id
object
The question, as the form asks it
Example
Annual incomeThe answer
Example
£32,000The part of the form it was in
Example
Employmentobject
Your id for the lead; repeats are ignored
When it was received (defaults to now)
Responses
Section titled “Responses”object
The inbox it went to
Counted as a new lead (false when the same contact, source and item already sent one to the same inbox within the lead period)
The externalId was already received; nothing new was stored
How the contact was matched; null for a new contact
object
The phone number is also on this contact
Example
{ "matchedBy": "id"}object
Stable machine-readable reason
With code invalid: every problem with the request, by field (message is the first)
object
Dotted path inside the item, e.g. attributes.price.amountMinor
Example
{ "statusCode": 403, "code": "forbidden", "message": "You do not have permission to do that.", "errors": [ { "message": "Enter the make" } ]}Missing or invalid API key
object
Stable machine-readable reason
With code invalid: every problem with the request, by field (message is the first)
object
Dotted path inside the item, e.g. attributes.price.amountMinor
Example
{ "statusCode": 403, "code": "forbidden", "message": "You do not have permission to do that.", "errors": [ { "message": "Enter the make" } ]}The organisation is on the Free plan (code upgrade_required)
object
Stable machine-readable reason
The feature that needs Pro
Where to upgrade or pay, in the web app
Example
{ "statusCode": 402, "code": "upgrade_required", "message": "Connections are part of Pro. Upgrade to connect texts, calls and more.", "feature": "extraSeats", "upgradePath": "/settings/billing"}The key does not have the scope (or the person the permission)
object
Stable machine-readable reason
With code invalid: every problem with the request, by field (message is the first)
object
Dotted path inside the item, e.g. attributes.price.amountMinor
Example
{ "statusCode": 403, "code": "forbidden", "message": "You do not have permission to do that.", "errors": [ { "message": "Enter the make" } ]}Rate limit reached
object
Stable machine-readable reason
Seconds until another request will be accepted
Example
{ "statusCode": 429, "code": "rate_limited", "message": "Too many requests. Each key can make 120 requests a minute; try again in 12 seconds.", "retryAfter": 12}