Skip to content

Idempotency

Networks time out. A request can succeed on our side while your side never hears the answer. Idempotency means you can send the same request again and get the same result — one lead, not two.

On every write to the intake endpoints, send a header with a value that is unique per logical submission — a UUID generated when the customer submits the form is ideal:

POST /api/integrations/leads
Authorization: Bearer bp_…
Content-Type: application/json
Idempotency-Key: 8f4c1e2a-6b3d-4f5e-9a7c-2d1b0e9f8a7b

The key is remembered against your integration. If a later request arrives with the same Idempotency-Key, BytePhase does not process it again: it returns the original outcome with 200 OK, "status": "duplicate", the original request_id, and the record that was created the first time.

{
"status": "duplicate",
"request_id": "01K4R4Z2N7Q9X0F3M6C8V1B5D2",
"data": { "id": 10421, "object": "lead", "…": "" }
}

Rules of thumb:

  • One key per submission, reused on every retry of that submission. Generate it once, store it with the queued item, send it each time.
  • A retry after a timeout is safe. That is exactly what the header is for.
  • Do not reuse a key for a different submission. You would get the first submission’s record back and the second would never be created.
  • Keys are compared exactly. Keep them under 191 characters; a UUID is 36.
Endpoint Idempotency-Key
POST /api/integrations/leads Honoured
POST /api/integrations/self-checkin Honoured
POST /api/integrations/submit Honoured
POST /api/integrations/ingest/{adapter} Honoured; derived automatically when the provider sends none
GET endpoints Not applicable

Form builders and marketplaces do not send an Idempotency-Key, but they do retry webhooks. So the receivers derive a key when none is sent:

Receiver Derived from
typeform The response token Typeform assigns to each submission
jotform JotForm’s submission id
tally-so Tally’s submission id
indiamart IndiaMART’s unique query id
justdial Justdial’s lead id, or a fingerprint of the enquiry when no id is present
form, canonical A hash of the whole payload plus the current date

The last row matters: with form and canonical, an identical payload sent twice on the same day is a replay, but the same payload on two different days is two submissions. That is deliberate — a customer legitimately submitting the same form a week apart should get two leads — and it is also why callers who control their own requests should send an explicit key instead of relying on the fallback. An explicit key is always stronger.

The duplicate status is returned in two situations, and both are success:

  1. Idempotent replay — the same Idempotency-Key was seen before. The original record and original request_id come back.
  2. Duplicate-record rule — a new submission matched an existing record by the workspace’s duplicate rule (for leads, by default: same mobile number and country code, or same email). The existing record comes back with a new request_id.

Either way you get 200 OK, "status": "duplicate", and the record in data. Treat it as “the record exists” and move on. See Submissions & Troubleshooting for how the duplicate rule is configured.

Reusing an Idempotency-Key with a different body is not currently detected: you get the original response back, not a 409. The idempotency_conflict code is reserved for when it is. Until then, never reuse a key across submissions.

The Zapier app handles its own retries. When you use a Zapier-typed key with a Code by Zapier step or a Webhooks by Zapier POST to the intake endpoints, set the Idempotency-Key header yourself from something stable in the trigger data.