The Affogato API
Every image, video and audio model Affogato serves, from your own code. One REST API, billed in the credits of your plan.
First generation in four calls.
Create a generation, long-poll it, read the output. The same three steps work for every model; the model id and its input come from GET /v1/models/{id}.
- STEP 01
Get a key
On a paid plan, open Developers in the app and create a key. Put it in
AFFOGATO_API_KEY. - STEP 02
Create a generation
POST /v1/generationswith a model id and its input. The response is201withstatus: "queued". - STEP 03
Poll until it finishes
GET /v1/generations/{id}?wait=25returns as soon as the status changes, or after 25 seconds. Loop while it isqueuedorprocessing. - STEP 04
Read the output
On
succeeded,outputs[0].urlis the file. Each output also carries a thumbnail, mime type and dimensions.
# 1. Create a generation (credits are charged now, refunded if it fails)
curl -X POST "https://staging.api.affogato.ai/v1/generations" \
-H "Authorization: Bearer $AFFOGATO_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "nano-banana-pro", "input": {"prompt": "A portrait photo of a barista, natural window light"}}'
# 201 {"id": "<generation id>", "status": "queued", ...}
# 2. Poll. ?wait=25 holds the request up to 25 s until the status changes.
curl "https://staging.api.affogato.ai/v1/generations/<generation id>?wait=25" \
-H "Authorization: Bearer $AFFOGATO_API_KEY"
# {"id": "...", "status": "succeeded", "outputs": [{"url": "https://...", ...}]}
# 3. Download outputs[0].urlKeys, credits, async, files.
One bearer token
Create a key on the Developers page of the app and send it as Authorization: Bearer afg_… on every request.
Keys are available on paid plans and belong to your organisation. Keep them on a server: a key must never ship in client-side code.
Your plan's credits
The API spends the same credits as the studios. Quote first with POST /v1/generations/estimate, which never charges.
POST /v1/generations charges up front and refunds in full if the generation fails or is cancelled.
Long-poll or webhooks
Every generation is asynchronous: queued → processing → succeeded | failed | cancelled. Read it with ?wait=25 to hold the request for up to 25 seconds, or on the create call itself.
Or pass a webhook_url per request, or register organisation endpoints. Deliveries are signed (Standard Webhooks).
Upload once, reference by id
POST /v1/files (multipart) or POST /v1/files/from-url return {id, url, mime_type, …}.
Pass the file id in a model's input slot, for image-to-video, edits, lipsync and every other model that takes media.
The whole surface.
Every path is under https://staging.api.affogato.ai/v1. Request and response schemas are in the interactive reference, built from the API's own openapi.json.
Models
The catalog: what you can call and what each model takes.
| GET | /v1/models | List models. Filters: feature, output_type, q. |
| GET | /v1/models/{id} | One model: parameters, input slots, pricing in credits and an example_request. |
Generations
Create work, follow it to a terminal status, read outputs.
| POST | /v1/generations/estimate | Quote a request in credits without charging. |
| POST | /v1/generations | Create a generation: {model, input, webhook_url?, metadata?}. Returns 201 with status "queued". Optional Idempotency-Key header and ?wait=25. |
| GET | /v1/generations/{id} | Read a generation. ?wait=25 long-polls for up to 25 seconds. |
| GET | /v1/generations | List generations, including failed and cancelled ones. |
| POST | /v1/generations/{id}/cancel | Cancel a queued or processing generation. |
Files
Upload inputs once, then pass the file id in a model's input slot.
| POST | /v1/files | Upload a file (multipart field "file"). |
| POST | /v1/files/from-url | Import a file from a URL: {url}. |
| GET | /v1/files | List your files. |
| DELETE | /v1/files/{id} | Delete a file. |
Prompts
The same prompt enhancer the studios use.
| POST | /v1/prompts/enhance | Rewrite a prompt for a kind: {prompt, kind: image | video}. |
Webhooks
Org-level endpoints, signed with your whsec_… secret.
| GET | /v1/webhooks | List endpoints. |
| POST | /v1/webhooks | Add an endpoint. |
| PATCH | /v1/webhooks/{id} | Update an endpoint. |
| DELETE | /v1/webhooks/{id} | Remove an endpoint. |
| GET | /v1/webhooks/secret | Read the signing secret. |
Account
Who the key belongs to and what it has spent.
| GET | /v1/account | The organisation, plan and credit balance behind the key. |
| GET | /v1/usage | Credit usage. |
What to expect at the edges.
Rate limits
Over a limit the API answers 429 with a Retry-After header. Retry after that many seconds; an Idempotency-Key on the create call makes the retry safe.
Errors
Every error is JSON with one shape: a stable code to branch on and a message for people.
{
"error": {
"code": "insufficient_credits",
"message": "This generation needs 40 credits; the organisation has 12."
}
}Generation statuses
A generation moves forward only; the last three are terminal. Failed and cancelled generations are refunded in full and stay in GET /v1/generations.
outputs[]url,thumbnail_url,mime_type,width,height,duration_ms
Webhooks
Events generation.succeeded, generation.failed, generation.cancelled. Deliveries follow the Standard Webhooks spec, signed with your whsec_… secret from GET /v1/webhooks/secret.
webhook-ida unique id for this deliverywebhook-timestampUnix seconds the delivery was sentwebhook-signaturev1,<base64 HMAC-SHA256> over "{id}.{timestamp}.{body}"
Every model Affogato serves.
Image, video and audio, unless the operator withholds one. GET /v1/models is the authoritative list, with filters for feature, output_type and q; each model's page has its parameters, input slots, price in credits and an example request.
image
112 modelsvideo
135 modelsaudio
12 modelsCounts are the public studio catalog at the time this page was rendered; variants of one model (image-to-video, edit, 4K) are folded into one name here but are separate ids in the API.
Build with Affogato.
Create a key, send one request, keep the output. Agents can read llms.txt.