Idempotency keys
Send an Idempotency-Key header with POST /v1/render or POST /v1/batch. If the same key comes again within 24 hours, you get the first answer again and pay once.
Use a key
Make a key that names the work, like an order number, and send it with the request. When the network fails or your code times out, send the same request with the same key again.
curl
curl -X POST "https://mintrender.com/v1/render" \ -H "Authorization: Bearer $MINTRENDER_KEY" \ -H "Idempotency-Key: order-1234-receipt" \ -H "Content-Type: application/json" \ -d '{"template":"tpl_3k2jQ8xLm0P4nB7vR2sT","data":{"title":"Receipt for order 1234"},"format":"pdf"}'JavaScript
const res = await fetch("https://mintrender.com/v1/render", { method: "POST", headers: { Authorization: `Bearer ${process.env.MINTRENDER_KEY}`, "Idempotency-Key": "order-1234-receipt", "Content-Type": "application/json", }, body: JSON.stringify({ template: "tpl_3k2jQ8xLm0P4nB7vR2sT", data: { title: "Receipt for order 1234", }, format: "pdf", }),});const body = await res.json();if (!res.ok) throw new Error(`${body.error.code}: ${body.error.message} (${body.error.request_id})`);console.log(body);Python
import os import requests res = requests.post( "https://mintrender.com/v1/render", headers={"Authorization": f"Bearer {os.environ['MINTRENDER_KEY']}", "Idempotency-Key": "order-1234-receipt"}, json={ "template": "tpl_3k2jQ8xLm0P4nB7vR2sT", "data": { "title": "Receipt for order 1234", }, "format": "pdf", }, timeout=120,)body = res.json()if not res.ok: raise RuntimeError(f"{body['error']['code']}: {body['error']['message']} ({body['error']['request_id']})")print(body)The second answer has the same status and the same JSON body as the first, and the header Idempotent-Replayed: true. A batch sent twice with one key is one batch.
The rules
- The routes that read the header are
POST /v1/renderandPOST /v1/batch. - A key is 1 to 255 visible ASCII characters (no spaces). Keys are per workspace: two workspaces can use the same key.
- A key lasts 24 hours from its first use. After that, the same key starts a new request.
- The body must be the same. The order of the JSON keys does not matter:
{"a":1,"b":2}and{"b":2,"a":1}are the same body. - Live keys and test keys never share an answer. One Idempotency-Key works with both: each kind of key keeps its own answer, so a key sent first with a test key and then with a live key gives no 422.
What is kept
| First answer | Kept for the same key? |
|---|---|
| 200 and 202 | Yes. The same key gives the same answer. |
| 400, 404 and 451 | Yes. |
| 402, 409 and 429 | No. These can change on a retry, so the request runs again. |
| 500 and other 5xx answers | No. The request runs again. |
| A file from ?inline=1 | No. The request runs again. The file then comes from the stored copy and costs nothing. |
A request that started and never stored an answer (for example, the server stopped) holds the key for 5 minutes. After that, the key is free again.
Errors
| Status | Code | When |
|---|---|---|
| 400 | invalid_request | The key is empty, longer than 255 characters, or has characters that are not visible ASCII. |
| 409 | in_progress | The first request with this key is still running. Wait for Retry-After (2 seconds) and send it again. |
| 422 | idempotency_mismatch | The key was used with a different body in the last 24 hours. Use a new key for new work. |
Without a key, the same render again is free once the first one has stored its file. A key also covers the time before that: while the first request still runs, a retry gets 409 in_progress and starts no second render. With a key, a job or a batch sent twice is made once.
Seen MintRender used for content that breaks our terms? Report it. Questions about the API: support@mintrender.com, with the request id.