Generations API Reference
Complete documentation for the ModelStack Generations API — create, list, and manage AI-generated images and videos.
Overview
The Generations API provides a unified interface for AI image and video generation across multiple providers. All requests require authentication with an API key.
Base URL
https://api.modelstack.ccAuthentication
Include your API key in the Authorization header:
Authorization: Bearer sk_YOUR_API_KEYRate Limits
There is currently no enforced rate limit on the Generations API — don't build against a specific requests-per-minute figure. Your effective throughput is bounded by your account balance, since every generation is billed on creation.
Create Generation
/v1/generationsCreate a new image or video generation. Returns immediately with a pending generation — poll the generation ID to get the result.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| type | string | Yes | Generation type, e.g. TEXT_TO_IMAGE, TEXT_TO_VIDEO, IMAGE_TO_IMAGE |
| prompt | string | Yes | Text prompt describing the desired output |
| model | string | Yes | Model identifier, e.g. google/nano-banana-2-lite |
| modelSettings | object | No | Model-specific parameters (aspect ratio, resolution, duration, etc.) |
curl -X POST "https://api.modelstack.cc/v1/generations" \
-H "Authorization: Bearer sk_YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "TEXT_TO_IMAGE",
"prompt": "A serene mountain landscape at sunset",
"model": "google/nano-banana-2-lite",
"modelSettings": {
"aspect_ratio": "16:9"
}
}'Response
{ "data": { "id": "gen_abc123" } }Only the id is returned — poll GET /v1/generations/{id} for status and output.
Get Generation
/v1/generations/{id}Get the status and result of a specific generation. Poll this endpoint to check when generation is complete.
curl "https://api.modelstack.cc/v1/generations/gen_abc123" \
-H "Authorization: Bearer sk_YOUR_API_KEY"Response
{
"data": {
"id": "gen_abc123",
"status": "completed",
"creditsUsed": 40,
"outputMediaUrls": ["media/user_123/gen_abc123/0.png"],
"createdAt": "2026-01-01T00:00:00.000Z",
"completedAt": "2026-01-01T00:00:12.000Z"
}
}status is one of pending, processing, completed, failed, or deleted.outputMediaUrls holds storage keys, not downloadable URLs — exchange each key for a signed URL via GET /v1/media/presigned-url?key=... (expires after 1 hour).
List Generations
/v1/generationsList all generations with pagination and optional status filtering.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
| limit | number | No | Max records (max 100)(default: 25) |
| offset | number | No | Pagination offset(default: 0) |
| status | string | No | Filter: pending | processing | completed | failed |
curl "https://api.modelstack.cc/v1/generations?limit=10&status=completed" \
-H "Authorization: Bearer sk_YOUR_API_KEY"Delete Generation
/v1/generations/{id}Delete a completed or failed generation to free up storage.
curl -X DELETE "https://api.modelstack.cc/v1/generations/gen_abc123" \
-H "Authorization: Bearer sk_YOUR_API_KEY"Response
{ "success": true }Error Handling
Error responses are not uniformly shaped — the shape depends on which layer rejects the request.
Rejected before reaching the app
Auth failures and insufficient-balance pre-checks return a nested shape:
{ "error": { "message": "Authentication failed", "type": "invalid_api_key" } }HTTP 401.
{
"error": { "message": "Insufficient balance", "type": "insufficient_balance", "code": "insufficient_balance" },
"balance": { "available": 0, "required": 10000 }
}HTTP 402. This pre-check uses a rough flat cost estimate, not the exact per-request price — it can pass and still have the real balance check fail later (surfacing as a 500, see below).
Rejected by the app
Validation/lookup failures once the request reaches the app return a flat string, not a nested object:
{ "error": "type, prompt, and model are required" }HTTP 400. Similarly, { "error": "Unauthorized" } for 401, and { "error": "<message>" } for 404.
Known edge-case behavior
GET /v1/generations/{id}for a nonexistent id returns HTTP 200 with{ "data": null }, not a 404.DELETE /v1/generations/{id}on a pending/processing generation returns HTTP 500, not a 400 — only completed/failed generations can be deleted.- Unexpected failures (including the real balance check failing after the pre-check estimate passed) return
{ "error": "Internal server error" }(500) rather than a specific 4xx.