Concepts
Making requests
One endpoint for everything. Image, video, audio, and tools all go through the same POST /generations — only the model and params change.
Base URL
All paths are relative to:
https://caranguejo.art/api/v1/dev
Responses are always JSON. Success is { "data": … } (lists also add "meta"); errors are { "success": false, "error": { "code", "message" } }.
The universal endpoint
POST /generations accepts a handful of first-class fields plus a free-form params bag validated against the model's schema:
| Field | Type | What it's for |
|---|---|---|
model required | string | Slug of a model or tool (from GET /models). |
prompt | string | Guiding text (optional for tools). |
image_urls | string[] | References / edit source / tool input. Upload with POST /uploads. |
start_frame_url / end_frame_url | string | First / last frame for image-to-video. |
audio_url | string | Conditioning audio (lip-sync / avatar). |
aspect_ratio, duration_seconds, quality, resolution, n | — | Common fields; use whichever the model supports. |
params | object | Any model-specific field (see GET /models/:slug). |
webhook_url | string | Signed https callback on completion. |
One endpoint, three media types
curl -X POST https://caranguejo.art/api/v1/dev/generations \
-H "Authorization: Bearer $CK" -H "Content-Type: application/json" \
-d '{ "model": "gpt-image-2", "prompt": "um caranguejo numa praia neon",
"params": { "quality": "high", "resolution": "2K" } }'
curl -X POST https://caranguejo.art/api/v1/dev/generations \
-H "Authorization: Bearer $CK" -H "Content-Type: application/json" \
-d '{ "model": "seedance-2", "prompt": "gire o produto 360°",
"start_frame_url": "https://media.caranguejo.art/inputs/…/produto.png",
"duration_seconds": 5, "aspect_ratio": "9:16" }'
curl -X POST https://caranguejo.art/api/v1/dev/generations \
-H "Authorization: Bearer $CK" -H "Content-Type: application/json" \
-d '{ "model": "upscale",
"image_urls": ["https://media.caranguejo.art/inputs/…/foto.png"] }'
Uploading files
To edit or condition on local media, upload it first with POST /uploads (multipart, up to 25 MB). You get back a permanent and public URL to use in image_urls, start_frame_url, etc. Identical files are de-duplicated.
curl -X POST https://caranguejo.art/api/v1/dev/uploads \
-H "Authorization: Bearer $CK" \
-F file=@./produto.png
{ "data": { "url": "https://media.caranguejo.art/inputs/…/produto.png",
"mime_type": "image/png", "size": 482113 } }
Response shape
An accepted job comes back as processing. Once complete, output.assets lists each output URL with its type (image jobs also keep output.images for backward compatibility):
{
"data": {
"id": "9f0c…",
"status": "completed",
"type": "image",
"credits_charged": 40,
"output": {
"assets": [{ "url": "https://media.caranguejo.art/…", "type": "image" }],
"images": [{ "url": "https://media.caranguejo.art/…" }]
}
}
}
Sync vs. async
The API is asynchronous by nature: POST /generations returns immediately with status: "processing". To learn the result you have two options — poll GET /generations/:id, or pass a webhook_url. The higher-level surfaces (CLI, SDK, MCP) offer a wait mode (e.g. --wait / waitForGeneration) that polls for you. Details in Async & webhooks.