Idempotency
POST requests create resources or trigger actions (for example creating a task, or unlocking a door). If a request fails mid-flight, for example with a network timeout, you can’t tell whether it was applied, so retrying blindly risks doing it twice.
The Idempotency-Key header solves this: send the same key on a retry and the API returns the original response without running the operation again.
How to Use It
Section titled “How to Use It”Send Idempotency-Key on POST requests. The value is any non-blank string of up to 255 characters that you generate (a UUID v4 is a good choice):
curl -X POST https://api-us.suiteop.com/api/v1/tasks \ -H "Authorization: Bearer sk_live_your_key_here" \ -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \ -H "Content-Type: application/json" \ -d '{"name": "Deep clean unit 4B", "departmentId": "0b6f2c1e-…", "propertyId": "9a3d7e40-…"}'On a retry, send the exact same request with the exact same Idempotency-Key. If the first request succeeded, you get the original status and body back, with one additional header:
Idempotency-Replayed: trueThe replayed body keeps the original request’s meta.requestId. The X-Request-Id header carries the ID of the retry itself.
Replay Window
Section titled “Replay Window”A key is remembered for 24 hours after the original request completes. After that, the same key is treated as a fresh request.
Keys are private to the credential that sent them: the same key sent with two different API keys (or by two different OAuth app and user pairs) never collides.
What Is Remembered
Section titled “What Is Remembered”- Successful responses are stored and replayed.
- Errors are not stored. If the original request failed (validation error, permission error, not found, server error), the key is released and a retry with the same key runs the operation again. Fix the request and resend. A
500returned after the operation was applied is the exception: the key stays held (409for up to 60 seconds). Check the result with aGETbefore retrying under a new key. - Provider refusals are the exception. When a device command is refused by the device’s provider (
502 provider_error), the refusal is stored and replayed. Check the device in SuiteOp, then send a new key if you still want the command attempted. See Errors.
Error Cases
Section titled “Error Cases”| Scenario | Status | Error type / code |
|---|---|---|
| Same key, different request body | 422 | business_rule_error / PERMANENT_MUTATION_ERROR |
Same key, different operation (for example first createTask, then createReservation) | 422 | business_rule_error / PERMANENT_MUTATION_ERROR |
| Same key, same operation on a different resource ID in the path, or different query | 422 | business_rule_error / PERMANENT_MUTATION_ERROR |
| A request with the same key is still in flight | 409 | conflict_error / CONFLICT |
Idempotency-Key header present but blank | 400 | validation_error / VALIDATION_ERROR |
Idempotency-Key longer than 255 characters | 400 | validation_error / VALIDATION_ERROR |
The 422 message says which of the three mismatches happened. On a 409, wait briefly and retry with the same key. You then get the finished request’s response.
When to Use It
Section titled “When to Use It”Use Idempotency-Key on every POST request, especially:
- Creating resources (tasks, reservations, members) to avoid duplicates on network retries.
- Commands with real-world effects, such as locking or unlocking a device, which can’t be undone.
The header only applies to POST. It is ignored on GET, PATCH and DELETE requests.