CRM Callback
Endpoint: POST /lead.capture/crm-callback
Used by Make.com (or similar) to send back the CRM lead ID after creating a lead in the external CRM. Stores the ID in our Leads table (primary lead) or LeadSubmissions table (follow-up submission) so we can match incoming CRM webhooks and show a "View in CRM" link in the dashboard.
Authentication
Requires the CRM callback secret (not the lead capture API key from Forms config). Configure it in Settings → CRM callback secret or via CRM_CALLBACK_SECRET in wrangler vars. Send via:
Authorization: Bearer <secret>, orX-API-Key: <secret>
Requests without a valid secret receive 401 Unauthorized. If the secret is not configured, the endpoint returns 503 Service Unavailable.
Request
- Method:
POST - Content-Type:
application/json - Body: Provide at least one of (lead identifier) or (submission identifier), plus
crm_lead_id. You can send both lead and submission IDs in the same request; we update bothLeadsandLeadSubmissionsso you don't need to know whether the webhook was primary or follow-up. Prefer UUIDs (lead_public_id,lead_submission_public_id); integer IDs remain supported.
Primary lead — by UUID (recommended):
{
"lead_public_id": "550e8400-e29b-41d4-a716-446655440000",
"crm_lead_id": "crm-abc-456"
}Primary lead — by integer (legacy):
{
"lead_id": 123,
"crm_lead_id": "crm-abc-456"
}Follow-up submission — by UUID (recommended):
{
"lead_submission_public_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"crm_lead_id": "crm-xyz-789"
}Follow-up submission — by integer (legacy):
{
"lead_submission_id": 501,
"crm_lead_id": "crm-xyz-789"
}| Field | Type | Required | Description |
|---|---|---|---|
lead_public_id | string | One of | Public UUID for the lead (from webhook payload). Prefer over lead_id. |
lead_id | number | One of | Internal lead row ID (legacy). Use lead_public_id for new integrations. |
lead_submission_public_id | string | One of | Public UUID for the submission (from webhook payload). Prefer over lead_submission_id. |
lead_submission_id | number | One of | Internal submission row ID (legacy). Use lead_submission_public_id for new integrations. |
crm_lead_id | string | Yes | The lead ID returned by the CRM (non-empty). |
You can send both lead and submission identifiers in one request; we update both tables. Within each (lead vs submission), use either the public UUID or the integer ID, not both.
Where we store the CRM ID
| You send in the callback | We update |
|---|---|
lead_public_id or lead_id | Leads table → CrmLeadId (used for "View in CRM" on lead detail). |
lead_submission_public_id or lead_submission_id | LeadSubmissions table → CrmLeadId. |
Recommended: Send both lead and submission IDs (from the webhook payload) in every callback. We update both tables so you don't need to know if the submission was primary or follow-up. The webhook also includes is_follow_up: true/false so you can branch in Make.com if needed.
Make.com mapping (quick reference)
Use the IDs from the lead webhook trigger (module 1) and the CRM create/update step (e.g. module 2). The webhook includes is_follow_up: true/false; for the callback you can always send both lead and submission IDs and we update both.
| Source in Make.com | Map to callback field |
|---|---|
{{1.lead_public_id}} | lead_public_id |
{{1.lead_submission_public_id}} | lead_submission_public_id |
{{2.id}} (or your CRM module’s lead ID output) | crm_lead_id |
Recommended: send both (no need to know primary vs follow-up):
{
"lead_public_id": "{{1.lead_public_id}}",
"lead_submission_public_id": "{{1.lead_submission_public_id}}",
"crm_lead_id": "{{2.id}}"
}Response
200 OK — One or both of Lead and LeadSubmission updated:
{
"ok": true,
"crm_lead_id": "crm-abc-456",
"updated_lead": true,
"updated_submission": true,
"lead_public_id": "550e8400-e29b-41d4-a716-446655440000",
"lead_submission_public_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8"
}400 Bad Request — Invalid or missing body (e.g. missing crm_lead_id, or no lead/submission identifier), or invalid JSON.
401 Unauthorized — Missing or invalid secret.
404 Not Found — No lead or lead submission with the given ID.
503 Service Unavailable — CRM_CALLBACK_SECRET not configured.
Make.com setup
- In your scenario, after the module that creates the lead in the CRM, add an HTTP – Make a request (or similar) step.
- URL:
https://<your-worker>/lead.capture/crm-callback - Method: POST
- Headers:
Authorization: Bearer <CRM_CALLBACK_SECRET>orX-API-Key: <CRM_CALLBACK_SECRET> - Body (JSON):
- Send both
lead_public_idandlead_submission_public_idfrom the webhook payload, pluscrm_lead_idfrom the CRM step. We update both Lead and LeadSubmission so you don't need to know if it was primary or follow-up. The webhook also sendsis_follow_up: true/falseif you need to branch.
- Send both