Reference
Idempotency
A network timeout should never launch the same ads twice. Send an Idempotency-Key with every write: retrying it with the same key returns the first answer instead of doing the work again.
How it works
- The key: 1 to 255 visible ASCII characters, unique per request (a UUID is ideal), in the
Idempotency-Keyheader. Keys are per API key: two keys never share one. - Same key, same request (method, path and JSON body, whatever the order of its fields) within 24 hours: the first successful answer comes back as it was, with
Idempotent-Replayed: true. A replayed answer costs no credits. - Same key, another request:
422 idempotency_key_reused. Use a new key for a new request. - While the first request still runs:
409 idempotency_in_progresswithRetry-After: retry the same request a few seconds later. - A request that failed (any
4xxor5xx) frees its key: the retry runs again, so a fixed request goes through. - Without the header, a write that requires it answers
400 idempotency_key_required.
On top of the key, a launch plan and an action run once whatever happens: confirming one twice answers 409 (plan_already_launched, action_already_ran).
Which operations
| Operation | Endpoint | Idempotency-Key |
|---|---|---|
| Create import | POST /imports | Required |
| Create uploads | POST /uploads | Accepted, never replayed |
| Create launch plan | POST /launch-plans | Required |
| Confirm launch plan | POST /launch-plans/{id}/confirm | Required |
| Create action | POST /actions | Required |
| Confirm action | POST /actions/{id}/confirm | Required |
| Create bridge transfer | POST /bridge-transfers | Required |
| Confirm bridge transfer | POST /bridge-transfers/{id}/confirm | Required |
"Accepted": send one to be safe, it is checked and replayed the same way. Signed upload URLs are never stored, so their request is checked but not replayed.
Retrying safely
KEY=$(uuidgen) # one key per request, kept for its retries
curl -X POST https://api.apogee.ad/api/v1/launch-plans/7b0f3c52-4d1e-4c8a-9f61-2a5e8d3c1b90/confirm \
-H "Authorization: Bearer $APOGEE_API_KEY" \
-H "Idempotency-Key: $KEY" \
-H "Content-Type: application/json" \
-d '{"confirm": true}'
# A timeout? Send the very same request with the same key:
# the launch runs once, and you get its first answer (Idempotent-Replayed: true). The MCP server needs none of this: launch, bridge_transfer and execute_action run a plan or an action once, by its id.