docs
Dashboard

Guides / Idempotency

Idempotency.

Send an Idempotency-Key header on REST calls that use records or scrape units. A retry with the same key returns the first result and never counts anything twice.

Send a key

Make one key per logical operation, for example a UUID, and reuse it for every retry of that operation. The SDKs already send a key on every POST and reuse it across their own retries; pass your own to make a call safe to repeat across processes.

cURLTypeScriptPython
curl https://api.leadsets.ai/v1/people/enrich \
  -H "Authorization: Bearer $LEADSETS_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5d0c9a52-8a3e-4f0b-9b1e-2f6c1d7e8a90" \
  -d '{"linkedin_url": "https://www.linkedin.com/in/mayachen"}'

Rules

  • A key is any string up to 255 characters. Longer keys answer 400 invalid_request.
  • Keys are scoped to your workspace and the endpoint: the same key on two endpoints is two separate keys.
  • A successful result is kept for 24 hours. A retry in that time gets the same body back with the header Idempotent-Replayed: true, and nothing is counted: no records, no request, no scrape units.
  • Errors are not kept. After a 429, a 5xx or any other error, a retry with the same key runs the call again.
  • The same key with a different body answers 409 idempotency_conflict.
  • While the first call with a key is still running, another call with that key also answers 409 idempotency_conflict ("still running"). The hold lasts up to 120 seconds; wait a moment and retry with the same key.
  • GET /v1/usage ignores the header, since it costs nothing.
  • MCP tool calls don't take a key. Agents should retry by the error type, as Errors and retries describes.

A retry loop

Without an SDK, keep the key outside the loop and honour Retry-After:

cURLTypeScriptPython
# curl --retry resends the same headers, so the key stays the same,
# and waits for Retry-After on 429 and 503.
curl https://api.leadsets.ai/v1/people/enrich --retry 3 \
  -H "Authorization: Bearer $LEADSETS_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"linkedin_url": "https://www.linkedin.com/in/mayachen"}'

A full window can mean a long wait. When window_full says the window resets in hours, Retry-After says so too. Decide whether to wait or stop the run; the error body has resets_at.

Previous
← Pagination
Next
Webhooks →

Was this page useful? Tell us