Skip to content

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>, or
  • X-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 both Leads and LeadSubmissions so 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):

json
{
  "lead_public_id": "550e8400-e29b-41d4-a716-446655440000",
  "crm_lead_id": "crm-abc-456"
}

Primary lead — by integer (legacy):

json
{
  "lead_id": 123,
  "crm_lead_id": "crm-abc-456"
}

Follow-up submission — by UUID (recommended):

json
{
  "lead_submission_public_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
  "crm_lead_id": "crm-xyz-789"
}

Follow-up submission — by integer (legacy):

json
{
  "lead_submission_id": 501,
  "crm_lead_id": "crm-xyz-789"
}
FieldTypeRequiredDescription
lead_public_idstringOne ofPublic UUID for the lead (from webhook payload). Prefer over lead_id.
lead_idnumberOne ofInternal lead row ID (legacy). Use lead_public_id for new integrations.
lead_submission_public_idstringOne ofPublic UUID for the submission (from webhook payload). Prefer over lead_submission_id.
lead_submission_idnumberOne ofInternal submission row ID (legacy). Use lead_submission_public_id for new integrations.
crm_lead_idstringYesThe 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 callbackWe update
lead_public_id or lead_idLeads table → CrmLeadId (used for "View in CRM" on lead detail).
lead_submission_public_id or lead_submission_idLeadSubmissions 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.comMap to callback field
&#123;&#123;1.lead_public_id&#125;&#125;lead_public_id
&#123;&#123;1.lead_submission_public_id&#125;&#125;lead_submission_public_id
&#123;&#123;2.id&#125;&#125; (or your CRM module’s lead ID output)crm_lead_id

Recommended: send both (no need to know primary vs follow-up):

json
{
  "lead_public_id": "&#123;&#123;1.lead_public_id&#125;&#125;",
  "lead_submission_public_id": "&#123;&#123;1.lead_submission_public_id&#125;&#125;",
  "crm_lead_id": "&#123;&#123;2.id&#125;&#125;"
}

Response

200 OK — One or both of Lead and LeadSubmission updated:

json
{
  "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 UnavailableCRM_CALLBACK_SECRET not configured.

Make.com setup

  1. In your scenario, after the module that creates the lead in the CRM, add an HTTP – Make a request (or similar) step.
  2. URL: https://<your-worker>/lead.capture/crm-callback
  3. Method: POST
  4. Headers: Authorization: Bearer <CRM_CALLBACK_SECRET> or X-API-Key: <CRM_CALLBACK_SECRET>
  5. Body (JSON):
    • Send both lead_public_id and lead_submission_public_id from the webhook payload, plus crm_lead_id from 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 sends is_follow_up: true/false if you need to branch.