API reference
Endpoints, authentication, request and response formats, webhooks and error codes for the threeD generation API.
Last updated
The REST API is available on the Studio plan. All requests use HTTPS and JSON. The base URL is https://api.threed.site/v1.
Authentication
Create a key in Dashboard → API keys and send it as a bearer token. Keys are shown once; store them in a secret manager, never in client-side code.
Authorization: Bearer threed_sk_...Create a generation
POST /generations
| Field | Type | Description |
|---|---|---|
mode | string | text, image, texture, remesh or rig |
prompt | string | Required for text and texture. Up to 600 characters. |
negative_prompt | string | Optional. Things to avoid. |
image_urls | string[] | 1–4 HTTPS URLs for image mode. |
source_asset_id | string | Existing asset for texture, remesh and rig. |
stage | string | preview or refine for text mode. Default preview. |
options | object | Style, target polycount, topology, texture resolution, symmetry. |
webhook_url | string | Optional. A public HTTPS URL that receives a signed POST when the job finishes. |
curl https://api.threed.site/v1/generations \
-H "Authorization: Bearer $THREED_KEY" \
-H "Content-Type: application/json" \
-d '{
"mode": "text",
"prompt": "mossy stone well with a wooden roof",
"stage": "preview",
"options": { "style": "stylized", "target_triangles": 8000 }
}'Response:
{
"id": "gen_8f2c1a",
"status": "queued",
"mode": "text",
"credits": 10,
"created_at": "2026-10-05T10:12:03Z"
}Get a generation
GET /generations/{id} returns the job with its status: queued, running, succeeded or failed. When it succeeds, assets lists the resulting asset IDs with preview images.
{
"id": "gen_8f2c1a",
"status": "succeeded",
"progress": 100,
"assets": [
{ "id": "ast_31d9", "thumbnail_url": "https://cdn.threed.site/...", "triangles": 7964 }
]
}List and download assets
GET /assets lists the models in your library, newest first (?limit= up to 100, ?before= a created_at value to page back).
GET /assets/{id}/download?format=glb returns the file URL. Fetch it with the same API key. Through the API, files come as glb today; the studio also exports OBJ, STL and USDZ.
Webhooks
If you pass webhook_url, we POST the final generation object (the same JSON as GET /generations/{id}) to it once the job succeeds or fails. Each request carries a threed-signature header: the hex HMAC-SHA256 of the raw body using the signing secret from Dashboard → API keys. Verify it before trusting the payload, and respond with a 2xx status within 10 seconds. Failed deliveries are retried with backoff for about 21 hours. A delivery can occasionally repeat, so treat the job id as idempotency key. The URL must be public HTTPS; private and local addresses are refused.
Errors
| Status | Code | Meaning |
|---|---|---|
| 400 | invalid_request | A field is missing or malformed. The message names it. |
| 401 | unauthorized | Missing or revoked API key. |
| 402 | insufficient_credits | Not enough credits for this job. |
| 404 | not_found | No generation or source asset with that ID in your account. |
| 422 | content_rejected | The prompt or image breaks the acceptable use policy. |
| 429 | too_many_jobs | Your plan's concurrent job limit is reached. Retry when a job finishes. |
| 429 | rate_limited | Too many requests. Retry after the Retry-After header. |
| 503 | provider_unavailable | The generation service could not accept the job. No credits were charged; retry later. |
Rate limits
Concurrency limits match your plan: see credits and limits. Read endpoints allow 120 requests per minute per key.