Skip to main content

The inbound lead webhook

What this page is — the API contract for creating leads from outside the application: the endpoint, the payload, and what happens after a lead arrives.

What it is for — wiring a website form, a landing page or a partner feed into Pulse so enquiries become leads without anybody typing them in.

The problem it solves — knowing which fields matter. A minimal request works, but omitting the source or the pipeline changes where the lead lands and whether reports can attribute it. This page says what to send and what happens to what you leave out.

Endpoint: POST /api/v1/webhooks/leads Authentication: an API key created on the Webhooks tab Permission to manage keys: Create/delete API keys · to view keys and logs: View API keys and logs


1. What it is, and what it is not​

Inbound webhookMarketing formCSV import
CallerAny system with an API keyThe Orbit form builderA person with a file
AuthAPI keyNone — public formSession
De-duplicatesYesYesNo
Runs assignmentYesYesYes
Runs scoringNoNoNo
Sets pipeline and statusIf suppliedFrom the form's defaultsNo
This is the only write path with working de-duplication

The webhook looks up an existing lead by email, phone or external_id before creating one, and increments submission_count on a repeat instead of inserting a duplicate. Neither the CSV import nor POST /leads does this — see lead import.


2. The request​

{
"full_name": "Marion Ashgrove",
"email": "[email protected]",
"phone": "+44 7700 900118",
"company_name":"Ashgrove Diagnostics",
"job_title": "Director of Operations",
"source_id": "8479ad7a-bc44-4a02-97c6-9ebdfc24b32d",
"pipeline_id": "22222222-2222-2222-2222-222222222222",
"status_id": "a7e3e5c1-441b-488f-9192-bd386024b573",
"custom_fields": { "industry": "Healthcare", "is_decision_maker": true },
"utm_source": "google",
"utm_campaign":"q3-diagnostics",
"consent_email": true,
"external_id": "crm-9912",
"update_if_exists": true
}

Required​

A name (full_name, or first_name and last_name), and either an email or a phone. A request with neither contact handle is rejected.

Worth setting explicitly​

FieldWhy
source_idOtherwise the lead has no source and Acquisition reports cannot attribute it
pipeline_id and status_idOptional. Omit them and the project's default pipeline is used
custom_fieldsMust be a JSON object, see the danger below
external_idLets you reconcile and de-duplicate against your own record id
update_if_existsOn a duplicate, updates the existing lead rather than only counting the submission

Stamped server-side, never accepted from the caller​

consent_timestamp is set by the server when any consent flag arrives. A compliance record must not depend on the caller's clock, so sending it has no effect.

custom_fields must be a JSON object, not text containing JSON

Many integration platforms stringify nested JSON by default. Send the object:

"custom_fields": { "industry": "Healthcare" }

not

"custom_fields": "{\"industry\":\"Healthcare\"}"

The second form is rejected with "custom_fields must be a JSON object", so you will see the problem straight away rather than discovering later that no rule matches.


FieldType
consent_emailboolean
consent_smsboolean
consent_whatsappboolean
consent_sourcefree text — where consent was captured

These are pointers server-side, so an explicit false is distinguishable from an omitted field. Send false when consent was refused; omit when it was never asked.


4. What happens on arrival​

Note what is absent from that diagram: scoring. A lead arriving by webhook has a score of 0 until somebody runs a recalculate. See status, grade and score.

Send a pipeline and status, or accept the default

Omit them and the lead is given the project's default pipeline and its first status, so it still appears on the board. Send them explicitly when the lead belongs somewhere other than the default.


5. The admin contract​

Must exist firstOr else
An API keyEvery request is rejected
A lead source you can name in source_idThe lead has no attribution
A pipeline and a statusNot required — the project default is used
Custom field definitions matching the keys you sendRequests naming an unknown key are rejected
Assignment rules, if you want automatic routingThe lead arrives unowned

6. Downstream​

A webhook lead reachesHow
The leads list and boardImmediately
An ownerAutomatically, if an assignment rule matches
A queueIf a rule routes it to one
Acquisition reportsThrough the lead's source and its UTM fields
A contact or dealOnly through conversion

7. Don't confuse this with…​

ThisNot this
POST /api/v1/webhooks/leads — inbound, API keyPOST /api/v1/org/marketing/leads — session, no de-duplication
The Webhooks tab's Test buttonThe webhook logs, which record what actually arrived
Webhook logsThe lead's activity timeline

8. Troubleshooting​

SymptomCause
401 or 403API key missing, revoked or inactive
Rejected with a validation errorNo name, or neither email nor phone
Lead is on an unexpected pipelineNone was sent, so the project default was used. Section 4
Request rejected, custom_fieldsSent as text containing JSON rather than an object. Section 2
Score lower than expectedA rule may have changed since the lead arrived — run Recalculate
Repeat submissions create no new leadCorrect — de-duplication is working. Check submission_count
Score lower than expected after a rule changeRun Recalculate to apply new rules to existing leads