Automate renders from any codebase, plugin, or pipeline. Upload an image, get a photorealistic render back.
Base https://rendercad.ai/backend/
Get API Token
# Quick start: create job, upload, finalize, poll
JOB=$(curl -s -X POST "https://rendercad.ai/backend/render.php?action=create_job" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"model":"pro","quality":"standard","render_mode":"preserve","background_style":"auto","condition":"auto"}')
JOB_ID=$(echo "$JOB" | jq -r '.job_id')
UPLOAD=$(curl -s -X POST "https://rendercad.ai/backend/render.php?action=presign_upload" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"job_id\":\"$JOB_ID\",\"slot\":\"input_main\",\"content_type\":\"image/jpeg\"}")
curl -s -X PUT "$(echo "$UPLOAD" | jq -r '.presigned_url')" \
-H "Content-Type: image/jpeg" \
--data-binary "@photo.jpg" > /dev/null
RENDER=$(curl -s -X POST "https://rendercad.ai/backend/render.php?action=finalize_job" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d "{\"job_id\":\"$JOB_ID\"}")
while true; do
STATUS=$(curl -s "https://rendercad.ai/backend/render.php?action=status&job_id=$JOB_ID" \
-H "Authorization: Bearer $TOKEN")
STATE=$(echo "$STATUS" | jq -r '.status')
[ "$STATE" != "pending" ] && [ "$STATE" != "processing" ] && break
sleep 2
done
echo "$STATUS" | jq '{status,output_url,asset_url,error_message}'
Include your API token in the Authorization header. Apps usually obtain their first token through the device-code browser flow below. Manage long-lived tokens in Settings > API Tokens.
Authorization: Bearer rendercad_xxxxxxxxxxxx
POST endpoints are JSON-only. If you send Authorization or X-Auth-Token and it is invalid, the API returns 401 and does not fall back to cookie/session auth.For desktop apps, browser extensions, and CLIs that hand sign-in off to a browser.
curl -s -X POST "https://rendercad.ai/backend/auth.php?action=request_device_code" \ -H "Content-Type: application/json" \ -d '{"app_name":"RENDERCAD Browser Extension","app_type":"browser-extension","app_version":"1.0.0"}'
{
"success": true,
"code": "ABCDEF",
"verification_url": "https://rendercad.ai/auth_device.html?code=ABCDEF&app_name=RENDERCAD%20Browser%20Extension&app_type=browser-extension&app_version=1.0.0",
"expires_in": 600,
"poll_interval": 3
}
Open verification_url in the user's browser.
The page already includes the device code in the link.
The user signs in there, and RENDERCAD authorizes automatically on that page.
curl "https://rendercad.ai/backend/auth.php?action=poll_device_code&code=ABCDEF"
{
"status": "pending",
"message": "Waiting for user authorization"
}
{
"status": "authorized",
"api_token": "rendercad_xxxxxxxxxxxx",
"message": "Authorization successful"
}
{
"status": "expired",
"message": "Code has expired"
}
{
"error": "Code parameter required"
}
verification_url, let the user sign in in the browser, then keep polling poll_device_code until the token is returned.Returns available models, capabilities, and credit costs.
curl "https://rendercad.ai/backend/api_discovery.php?action=models" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"models": [
{
"id": "classic",
"name": "Fast",
"description": "Quick renders with good quality",
"cost_credits": 1,
"supports_4k": false,
"supports_references": false,
"max_references": 0
},
{
"id": "pro",
"name": "Realistic",
"description": "High-quality photorealistic renders",
"cost_credits": 2,
"supports_4k": true,
"supports_references": true,
"max_references": 6
}
],
"quality_tiers": [
{
"id": "standard",
"name": "HD",
"resolution": "1024x1024",
"additional_cost": 0
},
{
"id": "4k",
"name": "4K",
"resolution": "4096x4096",
"additional_cost": 2,
"requires_model": "pro"
}
],
"render_modes": [
{
"id": "preserve",
"name": "Exact Mode"
},
{
"id": "creative",
"name": "Enhance Mode"
},
{
"id": "freeform",
"name": "Freeform Mode"
}
]
}
Returns all valid condition values accepted by image render and batch render requests. The current total_count is 43.
curl "https://rendercad.ai/backend/api_discovery.php?action=conditions" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"conditions": [
{"value": "auto", "label": "Auto (no condition)", "category": null},
{"value": "pristine", "label": "Pristine", "category": "Clean"},
{"value": "factory-new", "label": "Factory New", "category": "Clean"},
{"value": "snow-covered", "label": "Snow-Covered", "category": "Environmental Coverage"}
],
"total_count": 43,
"categories": ["Clean", "Surface", "Damage", "Age", "Wear", "Structural", "Moisture & Temperature", "Extreme States", "Environmental Coverage"]
}
Returns the background asset library for references objects with type: "background". These asset IDs are not valid background_style values.
curl "https://rendercad.ai/backend/api_discovery.php?action=backgrounds" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"backgrounds": [
{
"id": "24charpublicid",
"name": "Modern White House with Pool and Garden",
"category": "exterior",
"thumb_url": "https://renders.rendercad.ai/backgrounds/thumbs/exterior-3d-rendering-exterior-modern-house-in-minimal-architecture.webp"
}
],
"total_count": 371
}
Returns the texture asset library for references objects with type: "material" and asset_kind: "texture".
curl "https://rendercad.ai/backend/api_discovery.php?action=textures" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"textures": [
{
"id": "24charpublicid",
"name": "Brushed Metal",
"category": "metal",
"thumb_url": "https://renders.rendercad.ai/textures/thumbs/metal-brushed-metal-1.webp"
}
],
"total_count": 2942
}
Returns valid video preset values, defaults, durations, and resolutions for video generation requests.
curl "https://rendercad.ai/backend/api_discovery.php?action=video_options" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"video_options": {
"defaults": {
"video_mode": "single",
"style": "preserve",
"camera": "auto",
"motion": "auto",
"duration": 8,
"resolution": "720p"
},
"styles": [{ "value": "preserve", "label": "Preserve" }],
"camera_presets": [{ "value": "auto", "label": "Auto" }],
"motion_presets": [{ "value": "auto", "label": "Auto" }],
"durations": [{ "value": 8, "label": "8 seconds" }],
"resolutions": [{ "value": "720p", "label": "720p" }]
}
}
create_job, presign_upload, finalize_job, and cancel require render-only or full-access. delete requires full-access. status and history require read-only or higher.
curl -s -X POST "https://rendercad.ai/backend/render.php?action=create_job" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "source_url":"https://renders.rendercad.ai/abc123_input", "model":"pro", "quality":"standard", "render_mode":"preserve", "background_style":"auto", "condition":"auto", "custom_instructions":"Make it more modern" }'
| Parameter | Req | Values | Description |
|---|---|---|---|
source_url | No | URL | Existing RENDERCAD asset URL to copy into the new job namespace. Omit to upload after job creation. |
model | No | classic pro | Classic = 1 token, Pro = 2 (default: classic) |
quality | No | standard 4k | 4K requires Pro model |
render_mode | No | preserve creative freeform | Image prompt mode |
custom_instructions | No | string (max 1500) | Additional AI instructions |
condition | No | string | Condition preset from GET /backend/api_discovery.php?action=conditions |
background_style | No | auto white grey black gradient or custom:#RRGGBB | Simple prompt-level background preset |
references | No | JSON array | Reference objects. Remote asset URLs are copied immediately; local files are returned as upload slots. |
{
"success": true,
"job_id": "render_abc123",
"status": "uploading",
"required_uploads": [
{ "slot": "input_main" }
]
}
source_url and required_uploads can be empty. If uploads are required, call presign_upload for each slot, upload the bytes yourself, then call finalize_job. Uploaded images are validated during finalize and must be 80MB or smaller.curl -s -X POST "https://rendercad.ai/backend/render.php?action=presign_upload" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"job_id":"render_abc123","slot":"input_main","content_type":"image/jpeg"}'
{
"success": true,
"presigned_url": "https://...signed-put-url...",
"asset_url": "https://renders.rendercad.ai/abc123_input",
"slot": "input_main",
"index": null,
"expires_in": 300,
"cache_control": "public, max-age=31536000, immutable"
}
PUT presigned_url using the matching Content-Type. Presign does not require a file-size field; the 80MB image limit is enforced when finalize_job validates the uploaded object. The returned asset_url is the canonical RENDERCAD asset URL for that uploaded slot.curl -s -X POST "https://rendercad.ai/backend/render.php?action=finalize_job" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"job_id":"render_abc123"}'
{
"success": true,
"job_id": "render_abc123",
"status": "pending",
"queue_depth": 0,
"queue_position": 0,
"estimated_wait_seconds": 0
}
curl "https://rendercad.ai/backend/render.php?action=status&job_id=render_abc123" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"job_id": "render_abc123",
"status": "pending",
"status_detail": "Queued...",
"queue_depth": 3,
"estimated_wait_seconds": 90
}
{
"success": true,
"job_id": "render_abc123",
"status": "completed",
"status_detail": null,
"output_url": "https://rendercad.ai/backend/serve_render.php?id=render_abc123",
"asset_url": "https://renders.rendercad.ai/abc123",
"input_url": "https://renders.rendercad.ai/abc123_input",
"completed_at": "2026-02-11T10:04:22Z"
}
{
"success": true,
"job_id": "render_abc123",
"status": "failed",
"status_detail": "Failed",
"error_message": "Content policy violation",
"completed_at": "2026-02-11T10:04:22Z"
}
Returns paginated render history for the authenticated user. Supports page, limit, and filter=all|image|video.
curl "https://rendercad.ai/backend/render.php?action=history&page=1&limit=50&filter=all" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"renders": [
{
"job_id": "render_abc123",
"status": "completed",
"render_mode": "creative",
"model": "pro",
"quality_tier": "4k",
"input_url": "https://renders.rendercad.ai/abc123_input",
"output_url": "https://renders.rendercad.ai/abc123",
"created_at": "2026-02-11T10:00:00Z",
"completed_at": "2026-02-11T10:04:22Z",
"days_to_deletion": 87
}
],
"pagination": {
"page": 1,
"limit": 50,
"total_count": 124,
"total_pages": 3,
"has_next": true
}
}
output_url. The status endpoint returns an authenticated proxy output_url plus direct asset_url. For video renders, consume video_settings as the canonical settings object; background_style is image-only and will be null on video rows.curl -s -X POST "https://rendercad.ai/backend/render.php?action=cancel" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"job_id":"render_abc123"}'
{
"success": true,
"job_id": "render_abc123",
"status": "canceled"
}
pending jobs can be canceled. Once a job has started processing, cancel returns 409 and there is no refund.curl -s -X POST "https://rendercad.ai/backend/render.php?action=delete" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"job_id":"render_abc123"}'
{
"success": true
}
uploading, pending, or processing return 409; cancel pending jobs first or wait until processing finishes.create_job, finalize_job, convert, and cancel require render-only or full-access. status requires read-only or higher.
curl -s -X POST "https://rendercad.ai/backend/video.php?action=create_job" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "image_url": "https://renders.rendercad.ai/abc123.jpg", "camera": "orbit", "motion": "hero-spin", "style": "preserve", "prompt": "Slow dramatic product reveal", "duration": 8, "resolution": "1080p" }'
| Parameter | Req | Values | Description |
|---|---|---|---|
image_url | Yes* | RENDERCAD asset URL | Source image for single-image video mode |
video_mode | No | single transition loop | Default: single |
first_frame_url | Yes** | RENDERCAD asset URL | Required for video_mode=transition |
last_frame_url | Yes** | RENDERCAD asset URL | Required for video_mode=transition |
camera | No | preset | Camera motion preset, default auto |
motion | No | preset | Product motion preset, default auto |
style | No | preserve creative | Canonical video style preset |
prompt | No | string | Extra creative direction |
duration | No | 4 6 8 | Seconds (default: 8) |
resolution | No | 720p 1080p | Default: 720p |
crossfade_duration | No | 0.0-2.0 | Crossfade seconds for video_mode=loop |
image_url for single and loop videos. **Use first_frame_url and last_frame_url for transition videos. Submit public RENDERCAD asset URLs when you already have them. If the response includes upload slots, call POST /backend/render.php?action=presign_upload for each slot, upload the bytes yourself, then call POST /backend/video.php?action=finalize_job. Preset values are discoverable via GET /backend/api_discovery.php?action=video_options.exact and enhance are not supported. Use preserve or creative for style.Token cost: duration + (resolution === '1080p' ? 1 : 0)
{
"success": true,
"job_id": "uuid-format-id",
"status": "uploading",
"required_uploads": []
}
curl -s -X POST "https://rendercad.ai/backend/video.php?action=finalize_job" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"job_id":"uuid-format-id"}'
{
"success": true,
"job_id": "uuid-format-id",
"status": "pending",
"tokens_used": 9,
"queue_depth": 0,
"queue_position": 0,
"estimated_wait_seconds": 0
}
curl -s -X POST "https://rendercad.ai/backend/video.php?action=convert" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "video_url": "https://renders.rendercad.ai/video_abc123.mp4", "format": "gif" }'
{
"success": true,
"job_id": "vc_abc123",
"status": "pending",
"format": "gif"
}
Videos take 2-5 minutes. Poll every 10 seconds.
curl "https://rendercad.ai/backend/video.php?action=status&job_id=uuid-format-id" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"job_id": "uuid-format-id",
"status": "pending",
"status_detail": "Queued...",
"queue_depth": 2,
"estimated_wait_seconds": 60
}
{
"success": true,
"job_id": "uuid-format-id",
"status": "completed",
"status_detail": null,
"video_url": "https://renders.rendercad.ai/video_abc123.mp4",
"completed_at": "2026-02-11T10:04:22Z"
}
{
"success": true,
"job_id": "uuid-format-id",
"status": "failed",
"status_detail": "Failed",
"error": "Generation failed",
"completed_at": "2026-02-11T10:04:22Z"
}
curl -s -X POST "https://rendercad.ai/backend/video.php?action=cancel" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"job_id":"uuid-format-id"}'
{
"success": true,
"job_id": "uuid-format-id",
"status": "canceled"
}
pending video jobs can be canceled. Once a job has started processing, cancel returns 409 and there is no refund./backend/sse_status.php was removed. Use polling instead:
| Resource | Endpoint | Interval |
|---|---|---|
| Images | GET /backend/render.php?action=status&job_id=... | 2 seconds |
| Videos | GET /backend/video.php?action=status&job_id=... | 10 seconds |
async function pollVideoStatus(jobId) { const res = await fetch( `/backend/video.php?action=status&job_id=${encodeURIComponent(jobId)}`, { credentials: 'include' } ); const data = await res.json(); return data.status; }
curl "https://rendercad.ai/backend/auth.php?action=check" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"authenticated": true,
"token_valid": true,
"csrf_token": "csrf_...",
"token_costs": {
"classic": 1,
"pro": 2,
"4k_upgrade": 2
},
"user": {
"id": 123,
"email": "user@example.com",
"subscription_plan": "professional",
"monthly_render_limit": 120,
"monthly_renders_used": 45,
"grant_tokens_remaining": 12,
"pooled_tokens_remaining": 87
}
}
200 with {"success":false,"authenticated":false,"token_valid":false}. If Authorization or X-Auth-Token is present but invalid, it returns 401 with the same flags plus error.Detailed usage statistics for the current billing cycle.
curl "https://rendercad.ai/backend/auth.php?action=usage" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"monthly_limit": 120,
"monthly_used": 45,
"monthly_remaining": 75,
"grant_tokens_remaining": 12,
"pooled_tokens_remaining": 87,
"pending_renders": 2,
"billing_cycle_start": "2026-02-01",
"billing_cycle_end": "2026-02-28",
"avg_render_times": {
"avg_image_seconds": 18,
"avg_video_seconds": 77
}
}
Returns detailed subscription plan and billing information.
curl "https://rendercad.ai/backend/auth.php?action=plan_info" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"plan_name": "Professional",
"plan_code": "professional",
"plan_id": "professional",
"monthly_credit_limit": 120,
"credits_used_this_month": 45,
"credits_remaining": 75,
"grant_tokens_remaining": 12,
"pooled_tokens_remaining": 87,
"billing_cycle_start": "2026-02-01",
"billing_cycle_end": "2026-02-28",
"next_reset_date": "2026-03-01",
"subscription_status": "active",
"price_cents": 4999,
"cancel_at_period_end": false,
"cancel_at": null
}
Returns all API tokens for the authenticated user.
curl "https://rendercad.ai/backend/auth.php?action=get_api_tokens" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"tokens": [
{
"id": 123,
"token_name": "My App",
"scope": "full-access",
"created_at": "2026-02-11T10:00:00Z",
"last_used_at": "2026-02-11T14:25:10Z",
"usage_count": 42,
"is_active": true
}
],
"max_tokens": 10
}
curl -s -X POST "https://rendercad.ai/backend/auth.php?action=create_api_token" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"token_name":"My App","scope":"full-access"}'
| Parameter | Req | Description |
|---|---|---|
token_name | Yes | Display name (max 100 chars) |
scope | No | read-only, render-only, or full-access (default: full-access) |
| Scope | Permissions |
|---|---|
read-only | Check auth, view usage, view plan info, call discovery endpoints, list tokens, list webhooks, and get history |
render-only | Everything in read-only, plus request upload URLs, submit/cancel renders, and submit/cancel video jobs |
full-access | All actions, including token create/revoke/rename and webhook register/delete |
{
"success": true,
"message": "API token created successfully",
"token": "rendercad_xxxxxxxxxxxx",
"token_data": {
"id": 123,
"token_name": "My App",
"scope": "full-access",
"created_at": "2026-02-11T10:00:00Z",
"last_used_at": null,
"usage_count": 0
},
"warning": "Save this token now. You will not be able to see it again."
}
curl -s -X POST "https://rendercad.ai/backend/auth.php?action=revoke_api_token" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"token_id":123}'
{
"success": true,
"message": "API token revoked successfully"
}
curl -s -X POST "https://rendercad.ai/backend/auth.php?action=rename_api_token" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"token_id":123,"new_name":"Production CLI"}'
{
"success": true,
"message": "API token renamed successfully"
}
Real-time notifications. Max 5 per account. Register/delete require full-access scope; list requires read-only or higher.
curl -s -X POST "https://rendercad.ai/backend/webhooks.php?action=register" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-domain.com/webhook", "events": ["render.completed", "render.failed", "video.completed", "video.failed"] }'
| Parameter | Req | Description |
|---|---|---|
url | Yes | HTTPS webhook endpoint (must be HTTPS) |
events | Yes | Array: render.completed, render.failed, video.completed, video.failed, credits.exhausted |
{
"success": true,
"id": 123,
"url": "https://your-domain.com/webhook",
"events": ["render.completed", "render.failed"],
"status": "active",
"secret": "whsec_...",
"created_at": "2026-02-11T10:30:00Z"
}
Returns all registered webhooks with status and delivery stats.
curl "https://rendercad.ai/backend/webhooks.php?action=list" \ -H "Authorization: Bearer YOUR_TOKEN"
{
"success": true,
"webhooks": [
{
"id": 123,
"url": "https://your-domain.com/webhook",
"events": ["render.completed", "render.failed", "video.completed", "video.failed"],
"status": "active",
"created_at": "2026-02-11T10:30:00Z",
"last_triggered_at": "2026-02-11T14:25:10Z",
"last_success_at": "2026-02-11T14:25:10Z",
"failure_count": 0
}
]
}
curl -s -X POST "https://rendercad.ai/backend/webhooks.php?action=delete" \ -H "Authorization: Bearer YOUR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"id":123}'
{
"success": true,
"message": "Webhook deleted"
}
Webhooks are delivered asynchronously as POST requests. Delivery uses one immediate attempt plus retries after 1m, 5m, and 15m if your endpoint does not return 2xx.
Verify signatures with hash_hmac('sha256', raw_json_body, webhook_secret) and compare the hex digest to the value after sha256= in X-Webhook-Signature.
Content-Type: application/json User-Agent: RENDERCAD-Webhooks/1.0 X-Webhook-Signature: sha256=... X-Webhook-Event: render.completed X-Webhook-Delivery: <delivery_id>
{
"event_type": "render.completed",
"delivery_id": "12345",
"timestamp": "2026-02-11T14:25:10Z",
"job_id": "render_abc123",
"status": "completed",
"output_url": "https://renders.rendercad.ai/output_abc123.jpg",
"processing_time_ms": 4200,
"completed_at": "2026-02-11T14:25:10Z"
}
{
"event_type": "video.completed",
"delivery_id": "12346",
"timestamp": "2026-02-11T14:30:00Z",
"job_id": "video_uuid",
"status": "completed",
"video_url": "https://renders.rendercad.ai/video_abc123.mp4",
"processing_time_ms": 95000,
"completed_at": "2026-02-11T14:30:00Z"
}
format.{
"event_type": "render.failed",
"delivery_id": "12347",
"timestamp": "2026-02-11T14:31:00Z",
"job_id": "render_def456",
"status": "failed",
"error": "Provider rejected the input image",
"input_url": "https://renders.rendercad.ai/input_def456.jpg",
"completed_at": "2026-02-11T14:31:00Z"
}
{
"event_type": "video.failed",
"delivery_id": "12348",
"timestamp": "2026-02-11T14:32:00Z",
"job_id": "video_ghi789",
"status": "failed",
"error": "Generation timed out",
"input_url": "https://renders.rendercad.ai/input_ghi789.jpg",
"completed_at": "2026-02-11T14:32:00Z"
}
{
"event_type": "credits.exhausted",
"delivery_id": "12347",
"timestamp": "2026-02-11T15:00:00Z",
"user_id": "user_xyz",
"credits_used": 120,
"credits_limit": 120,
"billing_cycle_end": "2026-02-28"
}
failure_count; a successful later delivery resets it to 0.| Model | Quality | Tokens |
|---|---|---|
| Classic | Standard | 1 |
| Pro | Standard | 2 |
| Pro | 4K | 4 |
| Duration | 720p | 1080p |
|---|---|---|
| 4 seconds | 4 | 5 |
| 6 seconds | 6 | 7 |
| 8 seconds | 8 | 9 |
| Code | Meaning |
|---|---|
200 | Success |
400 | Bad request / validation error |
401 | Missing required auth or invalid supplied auth credentials |
403 | Forbidden / not authorized (scope insufficient) |
404 | Unknown action or missing resource |
409 | State conflict, including non-cancelable jobs |
405 | Method not allowed |
415 | Content-Type must be application/json for documented public POST endpoints |
422 | Semantic validation error (for example oversized Pro input) |
429 | Rate limit, credit exhaustion, or queue/capacity limit |
500 | Server error |
{
"error": "Error message here"
}
error string on non-2xx responses.| Endpoint | Limit |
|---|---|
| Render submit, presign upload, history, delete, cancel | No request-rate limit. These endpoints can still return 429 for credit exhaustion, concurrency, or queue capacity. |
| Batch render | 30 requests/hour |
| Video generate | 10 requests / 5 minutes |
| Video convert | 20 requests / 5 minutes |
| Status polling | 120 requests/minute combined across render and video status endpoints |
| Device code request | 10 requests/hour |
| Device code poll | 60 requests / 10 minutes |
| Device code authorize | 5 requests/hour |
| Auth status, usage, plan info | No request-rate limit |
| Token list | 120 requests/hour |
| Token create, revoke, rename | 10 requests/hour |
| Discovery endpoints | 60 requests/hour |
| Webhook list | 60 requests/hour |
| Webhook register and delete | 10 requests/hour |
X-RateLimit-Endpoint, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, and Retry-After on 429.