Skip to main content
Network calls fail in ambiguous ways: a request times out, but you don’t know whether the server processed it. Send an Idempotency-Key header to retry with the same request. Trackly caches successful responses and designated saved outcomes for 24 hours and replays matching retries while that result remains cached. See Limits for cases where duplicate protection is unavailable.

Where it applies

Idempotency is supported on selected write endpoints, including: If you omit the header, the request runs normally with no idempotency protection. For each variable-resource Number Request mutation above, the replay fingerprint includes the concrete path as well as the body and query. Within that operation, an exact retry to the same request id replays, while the same key and payload sent to another request id returns 409 idempotency_conflict. Existing idempotent endpoints retain their established body-and-query fingerprint behavior.

How it behaves

The first successful (2xx) response is cached for 24 hours and returned verbatim — same body, same status code — on every retry. The handler does not run again.
Reusing a key with a different request body or query returns 409 idempotency_conflict. Path-bound operations also conflict when the concrete resource path changes. An idempotency key must identify one exact operation.
If a retry arrives before the original finishes, it returns 409 idempotency_in_progress with a Retry-After: 5 header. Wait and retry.
Ordinary non-2xx results release the key, so a validation failure before work is saved can be corrected and retried with the same key. Endpoints may retain errors that identify saved work.
For POST /v2/number-requests, an error containing requestId means the request was saved. That error is cached for 24 hours, including its original status, body, and request ID. The same key and payload replay it even after the underlying issue is resolved; changing the payload returns 409 idempotency_conflict. Read and resume requestId through the draft update, business confirmation, and submit endpoints. A pre-save error without requestId releases the key. When a response includes retryable: false, follow that response’s recovery instructions before submitting anything again. For example, 409 schedule_write_outcome_unknown includes schedule_id; inspect that schedule because the server could not confirm whether it committed. That 409 is cached for 24 hours; the same key and payload replay it rather than attempting schedule creation again. The release of an idempotency key does not establish that no record was created.

Schedule creation with optional creatives

When creating a blast, save_as_creative: true requests an additional asset save after the schedule is created. If that save fails, the response is still HTTP 201 with success: true, schedule.id, and an entry in creative_save_errors. This is a successful, cacheable schedule creation. Within the cache window, retrying the identical body with the same key returns the original saved_creatives and creative_save_errors; it does not retry failed asset saves. Retain the schedule ID and inspect both arrays. Do not create the schedule again with a new key to retry an asset save: it would create another blast. Schedule PUT does not support save_as_creative or creative_name. Use the asset-only recovery example to create the failed creative separately, without recreating the blast. The dedicated POST /v2/creatives endpoint does not support this idempotency header.

Limits

Idempotency uses a cache. Some endpoints, including schedule creation, allow execution when the cache is unavailable or corrupt. Child-account creation instead returns 503 idempotency_unavailable if it cannot reserve the key. If execution is allowed without protection, or the cache cannot store the result, a later retry may repeat the request’s effects. Protection also ends when the cached result expires after 24 hours. Keep returned IDs and check existing records before retrying an uncertain request outside the cache window or after a known cache failure. The header is not an unconditional at-most-once guarantee.

Choosing a key

  • Use a value unique to the operation — a UUID, or a deterministic ID from your own system (e.g. create-child:loc_west).
  • Keys are ≤255 characters, printable ASCII. Longer or non-printable keys return 400 idempotency_key_too_long / idempotency_key_invalid.
Test and live keys are isolated. The idempotency namespace is separated by mode, so a sandbox key and a live key can use the same Idempotency-Key value without ever colliding.

Example

Retrying a child creation with the same key returns the original child, not a second account:
cURL
Run it twice with the same Idempotency-Key and you get the same 201 response both times — one child is created.
Idempotency protects against duplicate requests, while externalIds.locationId uniqueness protects against duplicate businesses created by different requests. Together they make child provisioning safe to retry from anywhere.