Documentation Index
Fetch the complete documentation index at: https://docs.mareaalcalina.com/llms.txt
Use this file to discover all available pages before exploring further.
Safe mutations
Marea honorsIdempotency-Key on every POST and PATCH. Replays of the same key + same body return the same response (status + body, including failures). This lets agents retry network errors without double-creating resources.
Header contract
| Property | Value |
|---|---|
| Header name | Idempotency-Key |
| Length | 1–255 characters |
| Character class | ASCII printable only (0x20–0x7E) |
| Recommended format | UUID v4 |
| Applies to | POST and PATCH |
| Ignored on | GET, OPTIONS, DELETE |
400 invalid_idempotency_key. The regex is ^[\x20-\x7e]{1,255}$.
Match key
A stored idempotency record is keyed on the triple(keyId, method+path, Idempotency-Key). The body is hashed (canonical JSON, sorted keys, SHA-256 hex) and compared on every replay.
- Cross-key replays don’t work. Different API keys with the same
Idempotency-Keyare independent requests. - Cross-endpoint replays don’t work.
POST /v1/storefrontsandPOST /v1/storefronts/:id/productswith the sameIdempotency-Keyare independent.
Outcomes
| Match status | What you get | When |
|---|---|---|
owned | Handler runs; response is stored for future replays | First time the key is seen |
replay | Original response replayed verbatim (same status + body) | Same key + same body; original completed |
in_flight | 409 conflict + Retry-After: 1 (recoverable: true) | Same key + still processing |
conflict | 409 idempotency_conflict (recoverable: false) | Same key + different body |
oversize | 410 idempotency_snapshot_unavailable (rare) | Original response exceeded the 100 KB snapshot cap |
Missing the header
SendingPOST / PATCH without Idempotency-Key is not an error. The request proceeds and Marea returns a Marea-Recommendation: include-idempotency-key response header to nudge you. Skipping the header is fine for one-shot calls; include it for any retry-prone integration.
The four 409 / 410 error shapes
in_flight — same key still processing
owned; the other waits or replays.
conflict — same key, different body
invalid_idempotency_key — format error
idempotency_snapshot_unavailable — oversize response
What is stored
The first successful response is persisted as(keyId, method+path, Idempotency-Key) → { status, body }. Failed responses are also stored — a replay of a failed call returns the same failure. The stored snapshot is held to back replays; there is no client-controlled TTL.
Convention
Stripe-style. If you already use a Stripe retry library that drivesIdempotency-Key, it works on Marea unchanged.
Verification in code
src/api/middleware/idempotency.ts— header parsing + replay vs. owned vs. conflict branching.src/api/services/apiIdempotency.service.ts—acquireOrReplay,complete,fail, snapshot cap (SNAPSHOT_MAX_BYTES).