Idempotency and retries
Every write takes an Idempotency-Key header, so you can repeat a request after a timeout without ordering twice or rebooting twice. This page says exactly what a repeat returns.
The header
Idempotency-Key: 5f0c2a8e-8a9b-4d7e-9c55-2f1d3b7a6e10
- 8 to 64 characters: letters, digits,
-and_. A UUID works. - Required on every POST and DELETE. The only exception is an order dry run (
POST /orders?dry_run=true), which changes nothing. - Missing or malformed:
400 idempotency_key_required. Nothing is done.
Make one new key for each thing you mean to do once: one order, one reboot, one rename. Keep it until you have the answer.
What a repeat returns
Idempotency keys belong to the API key that sent them. Two API keys can use the same Idempotency-Key without meeting.
| You send | You get |
|---|---|
| A new Idempotency-Key | The request runs. Its answer is stored. |
| The same Idempotency-Key, the same body, the same server, and the first request has finished | The stored answer again, with the same status code and body. Nothing runs twice. A stored refusal (for example 409 sold_out) comes back as the same error. |
| The same Idempotency-Key while the first request is still running | 409 in_progress with details.retry_after (seconds). Ask again with the same key after that. |
| The same Idempotency-Key with a different body, or for a different server | 422 idempotency_conflict. Nothing runs. Use a new key for a new request. |
The same Idempotency-Key after the first attempt ended 409 in_progress or 503 unavailable | The request runs again. Those two outcomes mean nothing was done, so a retry is allowed. |
Example: a reboot whose answer was lost on the way.
KEY=$(uuidgen)
curl -sS -X POST https://api.redswitches.com/v1/servers/srv_123/power \
-H "Authorization: Bearer $REDSWITCHES_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d '{"action":"reboot"}'
# the connection dropped: send exactly the same request again
curl -sS -X POST https://api.redswitches.com/v1/servers/srv_123/power \
-H "Authorization: Bearer $REDSWITCHES_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d '{"action":"reboot"}'import { randomUUID } from "node:crypto";
const idempotencyKey = randomUUID();
// the SDK retries with the same key on network errors, 429, 503 and in_progress
const action = await rs.power.run("srv_123", { action: "reboot" }, { idempotencyKey });import uuid
key = str(uuid.uuid4())
action = client.power.run("srv_123", action="reboot", idempotency_key=key)key := uuid.NewString()
action, err := client.Power.Run(ctx, "srv_123", "reboot", &redswitches.RequestOptions{IdempotencyKey: key}){
"id": "act_42",
"kind": "power",
"server_id": "srv_123",
"action": "reboot",
"state": "queued",
"poll_after": 10
}
Both calls return the same action. The server reboots once.
When to retry
Retry only when you do not know the outcome or the API asked you to wait. Always reuse the same Idempotency-Key and the same body.
| Situation | Retry? |
|---|---|
| Network error or timeout, no answer | Yes, same key. |
429 rate_limited | Yes, after the Retry-After header's seconds. |
409 in_progress | Yes, after details.retry_after seconds. |
503 unavailable | Yes, with a growing pause (for example 2, 4, 8 seconds). |
500 internal_error | Not blindly. For an order, read Orders first: list your orders to see what happened, then contact support with the request id. |
Any other 4xx | No. Fix the request. A repeat with the same key returns the same answer. |
409 order_under_review | No. Staff are checking the order. Do not place it again. |
The SDKs do this for you: each write gets a fresh Idempotency-Key unless you pass one, and they retry only on network errors, 429, 503 and in_progress, always with the same key.
Orders in particular
If an order request times out, send it again with the same Idempotency-Key and the same body. You get the order that was placed (201), the refusal that ended it, or 409 in_progress while it is still running. You never get a second order. See the Ordering guide.