Generations (REST)
The non-MCP path: create Kling video and Nano Banana 2 image jobs over REST, poll them to completion, list and delete them, and how credits are charged and refunded.
View as MarkdownThis is the REST API for generations — the non-MCP way to drive Figgshield from your own tools and scripts. In Claude or the Claude Code CLI you would use the MCP tools (generate_video, generate_image) instead; both paths run the same models against the same credit balance.
A generation is one video or image job. The lifecycle is asynchronous: you create a job, it moves through queued → running, and it ends as succeeded (with an output_url) or failed (credits refunded automatically).
The generation object
{
"uuid": "0b8f6a2e-4c1d-4f7a-9b2e-6d3c8a1f5e90",
"model": "kling-video",
"model_name": "Kling",
"kind": "video",
"prompt": "A slow dolly shot across a quiet harbour at dawn",
"params": { "duration": 5, "resolution": "720p", "audio": false, "aspect_ratio": "16:9" },
"status": "succeeded",
"output_url": "https://cdn.figgshield.ai/outputs/0b8f6a2e.mp4",
"thumbnail_url": "https://cdn.figgshield.ai/thumbs/0b8f6a2e.jpg",
"credits_charged": 35,
"error_message": null,
"created_at": "2026-07-06T09:00:00Z",
"completed_at": "2026-07-06T09:00:48Z",
"duration_ms": 48000,
"is_watermarked": false
}
status is one of queued, running, succeeded, failed. output_url and thumbnail_url are null until the job succeeds; error_message is set only on failure. is_watermarked is always false — outputs are never watermarked.
Create a generation
POST /api/generations/create/
# Kling video (35 credits)
curl https://api.figgshield.ai/api/generations/create/ \
-X POST \
-H "Authorization: Bearer $FIGGSHIELD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "kling-video",
"prompt": "A slow dolly shot across a quiet harbour at dawn",
"params": { "duration": 5, "resolution": "720p", "audio": false }
}'
# Nano Banana 2 image (8 credits)
curl https://api.figgshield.ai/api/generations/create/ \
-X POST \
-H "Authorization: Bearer $FIGGSHIELD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana-2",
"prompt": "A paper boat on a still pond, top-down",
"params": { "resolution": "2K" }
}'
Returns 201 with the new generation (status: "queued").
Request body
| Field | Type | Notes |
|---|---|---|
model | string | kling-video or nano-banana-2 (from GET /api/models/). |
prompt | string | What to generate. |
params | object | Optional settings; allowed keys depend on the model — see below. |
Params by model
| Param | Applies to | Example | Notes |
|---|---|---|---|
duration | Kling | 5 | 5 or 10 seconds. 10 doubles the cost. |
resolution | Kling | "720p" | 720p or 1080p. |
audio | Kling | false | Default off; true doubles the cost. |
resolution | Nano Banana 2 | "2K" | 1K, 2K or 4K. |
aspect_ratio | both | "16:9" | Optional. |
Omitted params fall back to defaults. A value outside the model’s schema returns 400 validation_error.
Credits: pre-flight check, charge, refund
- The credit cost is checked before dispatch. If your balance cannot cover it, the request fails with
402 insufficient_creditsand nothing is charged. Kling is 35 credits (70 for 10 seconds or with audio); Nano Banana 2 is 8. - With automatic top-ups enabled, the top-up runs first and the pre-flight check happens after it.
- On success the cost is recorded as
credits_chargedand appears in the ledger as aburn. - If the job fails, the charged credits are refunded automatically (ledger entry
refund). You only pay for output.
Error responses
| Status | Code | Meaning |
|---|---|---|
400 | validation_error | Unknown model slug, bad prompt, or params outside the model’s schema. |
402 | insufficient_credits | Balance cannot cover the cost (after any automatic top-up attempt). |
402 | subscription_required | The account has no active subscription. |
409 | parallel_limit_reached | As many jobs already in flight as your plan allows — wait for one to finish. |
503 | model_unavailable | The model is offline or its provider is not responding. Retry later. |
See Errors for the full envelope and handling advice.
Poll a generation
GET /api/generations/{uuid}/ — the polling endpoint. Reading it refreshes the job’s provider status; the backend throttles provider polls to at most one per 2 seconds per job, so poll at a 2-second interval or slower.
while true; do
BODY=$(curl -s "https://api.figgshield.ai/api/generations/$GENERATION_UUID/" \
-H "Authorization: Bearer $FIGGSHIELD_API_KEY")
STATUS=$(echo "$BODY" | jq -r .status)
[ "$STATUS" = "succeeded" ] && { echo "$BODY" | jq -r .output_url; break; }
[ "$STATUS" = "failed" ] && { echo "$BODY" | jq -r .error_message >&2; exit 1; }
sleep 2
done
Kling clips typically take tens of seconds; Nano Banana 2 images usually finish in seconds.
List generations
GET /api/generations/ — your own generations, newest first (-created_at), in the standard list envelope. Page through with ?page=N.
curl "https://api.figgshield.ai/api/generations/?page=1" \
-H "Authorization: Bearer $FIGGSHIELD_API_KEY"
Delete a generation
DELETE /api/generations/{uuid}/ — soft delete; the generation disappears from your list. Deleting does not refund credits (only failure does).
curl https://api.figgshield.ai/api/generations/$GENERATION_UUID/ \
-X DELETE \
-H "Authorization: Bearer $FIGGSHIELD_API_KEY"
Returns 204 No Content.