Interrupted submissions
Each accepted create is its own task with its own charge. When a create times out, find out what happened before you send it again.
Send a create once
Every create that the API accepts makes a new task, holds Credits for it and may charge for it, even when the body is identical to an earlier one. Turn off automatic retries for POST /v1/generations in your HTTP client, SDK wrapper and any proxy in between.
Give every create a metadata.client_reference of your own, such as your order ID. It is how you find the task when the response is lost.
What you may retry
| What happened | Was a task created? | What to do |
|---|---|---|
| HTTP 202 | Yes | Save the id. Never resend. |
| HTTP 4xx other than 429 | No | Fix the request. Resending it unchanged gets the same error. |
| HTTP 429 | No | Wait Retry-After seconds and send it again. |
| HTTP 500 or 503 | Possibly | Look first, as below. |
| Timeout or dropped connection | Possibly | Look first, as below. |
Look before you resend
- If you have the task
id, read it with get a generation. - Otherwise, list tasks with list generations, filtered by your
client_reference. - Only if no task matches, send the create again.
cURL
curl "https://api.vizoapi.com/v1/generations?client_reference=order-1042" \
-H "Authorization: Bearer $VIZO_API_KEY" \
| jq '.entries[] | {id, status, created_at}'Python
import os, requests
def find(reference):
res = requests.get(
"https://api.vizoapi.com/v1/generations",
headers={"Authorization": f"Bearer {os.environ['VIZO_API_KEY']}"},
params={"client_reference": reference},
timeout=30,
).json()
return res["entries"][0] if res["entries"] else NoneThe list is newest first and can be narrowed further with model, status, created_after (inclusive) and created_before (exclusive). Listing needs the generations:list scope.
Note
A task found this way is the one you created: keep polling it. A second create would make a second task and a second charge.