Developer API

Generate 3D models programmatically via the Trify3D REST API. Authenticate with API keys, run async jobs via Trigger.dev, and receive webhooks on completion.

Base URLhttps://trify3d.com/api/v1AuthBearer token (trf_live_…)FormatJSON request / responseScopesread, write, adminRate limit600 requests / hour / key

Quickstart

  1. Create an API key — sign in to the dashboard → API Keys Create. Copy the plaintext value immediately; it is shown only once.
  2. Make your first request — generate a 3D model from text:
curl -X POST https://trify3d.com/api/v1/generations/text-to-3d \
  -H "Authorization: Bearer trf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "text_to_3d",
    "prompt": "A medieval sword with golden hilt",
    "style": "realistic",
    "mode": "quality"
  }'

# Response 201
{
  "ok": true,
  "data": {
    "taskId": "gen_abc123",
    "provider": "meshy",
    "status": "processing",
    "creditsUsed": 20,
    "creditsRemaining": 980
  },
  "requestId": "req_1a2b3c4d"
}
  1. Poll for completion GET https://trify3d.com/api/v1/generations/gen_abc123. When status is completed, data.outputModelUrl points to the generated .glb.
  2. Receive a webhook (optional) — pass webhookUrl on creation to be notified instead of polling.

Response envelope

All responses follow a single envelope. Every response carries an X-Request-ID header — include it when reporting issues.

// success (2xx)
{ "ok": true, "data": { /* … */ }, "requestId": "req_abc123" }

// error (4xx / 5xx)
{
  "ok": false,
  "error": {
    "code": "snake_case_code",
    "message": "Human-readable message.",
    "requestId": "req_abc123",
    "details": { /* optional, e.g. validation issues */ }
  }
}

Authentication

All /v1/* endpoints require a Bearer token in the Authorization header:

Authorization: Bearer trf_live_xxxxxxxx

Create keys from /api/api-keys using your session cookie. Keys are prefixed trf_live_ and stored as a SHA-256 hash; the plaintext is shown only once and is never retrievable after creation.

Managing keys

  • Create — Dashboard → API Keys → Create. Plaintext shown once.
  • Scopes — assigned at creation.
  • Revoke — Dashboard → API Keys → Revoke. Revoked keys immediately return 401 invalid_api_key.
  • Rotation — revoke + create a new key. No grace period; update clients promptly.

Scopes

ScopeGrants
readGET endpoints (e.g. fetch a task).
writePOST endpoints (create generations).
adminAll of the above (satisfies any requirement).

A read-scoped key cannot create generations — the API returns 403 insufficient_scope.

Endpoints

POST/api/v1/generations/image-to-3dscope: write

Turn a single reference image (JPG/PNG) into a textured 3D model.

POST/api/v1/generations/text-to-3dscope: write

Generate a 3D model from a natural-language prompt.

POST/api/v1/generations/multiview-to-3dscope: write

Reconstruct a 3D model from 2+ photos of different angles.

GET/api/v1/generations/{taskId}scope: read

Poll the status of a generation task. Returns status, output URL, and credit usage.

GET/api/api-keysscope: session

List your API keys (requires session auth, not Bearer).

POST/api/api-keysscope: session

Create a new API key. Returns the plaintext key once.

POST/api/api-keys/{keyId}/revokescope: session

Revoke an API key. Irreversible.

POST /generations/image-to-3d

Turn one reference image (JPG/PNG) into a textured 3D model. Upload the image as a base64 data URL.

curl -X POST https://trify3d.com/api/v1/generations/image-to-3d \
  -H "Authorization: Bearer trf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "image_to_3d",
    "fileName": "sword.png",
    "fileSize": 524288,
    "fileType": "image/png",
    "imageDataUrl": "data:image/png;base64,iVBORw0KGgo...",
    "mode": "quality",
    "model": "rodin/rodin-v25",
    "multiPart": false,
    "settings": {
      "texture": true,
      "hdTexture": true,
      "geometryQuality": "standard",
      "topology": "triangle"
    },
    "webhookUrl": "https://yourapp.com/hooks/trify3d"
  }'

# 201 Created
{
  "ok": true,
  "data": {
    "taskId": "gen_abc123",
    "provider": "rodin",
    "status": "processing",
    "creditsUsed": 30,
    "creditsRemaining": 970
  },
  "requestId": "req_1a2b3c4d"
}
FieldRequiredDescription
typeyes"image_to_3d" discriminator.
fileNameyesOriginal filename.
fileSizeyesByte size.
fileTypeyesMIME (image/jpeg, image/png).
imageDataUrlyesBase64 data URL of the image.
modeyes"speed" | "quality".
modelnoProvider model id (e.g. rodin/rodin-v25).
multiPartnoUse multipart/rodin pipeline.
settingsnoTexture / geometry options (see below).
webhookUrlnoHTTPS URL for completion callback.

settings: texture (bool), hdTexture (bool), geometryQuality ("standard" | …), topology ("triangle" | …).

Provider selection: model starts with rodin/ → rodin; multiPart: true → rodin; mode: "speed" → tripo3d; otherwise meshy.

POST /generations/text-to-3d

Describe the model you want in natural language.

curl -X POST https://trify3d.com/api/v1/generations/text-to-3d \
  -H "Authorization: Bearer trf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "text_to_3d",
    "prompt": "A medieval sword with golden hilt",
    "style": "realistic",
    "mode": "quality"
  }'
FieldRequiredDescription
typeyes"text_to_3d" discriminator.
promptyesNatural-language description.
styleyes"realistic" | "cartoon" | "low_poly".
modeyes"speed" | "quality".
modelnoProvider model id.
settingsnoSame shape as image-to-3d.
webhookUrlnoHTTPS URL for completion callback.

POST /generations/multiview-to-3d

Reconstruct a 3D model from multiple photographs taken from different angles. Requires at least 2 images.

curl -X POST https://trify3d.com/api/v1/generations/multiview-to-3d \
  -H "Authorization: Bearer trf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "multiview_to_3d",
    "imageDataUrls": [
      "data:image/png;base64,iVBOR...",
      "data:image/png;base64,iVBOR..."
    ],
    "mode": "quality"
  }'
FieldRequiredDescription
typeyes"multiview_to_3d" discriminator.
imageDataUrlsyesAt least 2 base64 data URLs.
modeyes"speed" | "quality".
modelnoProvider model id.
multiPartnoForce rodin provider.
settingsnoSame shape as image-to-3d.
webhookUrlnoHTTPS URL for completion callback.

GET /generations/{taskId}

Returns the current state of a generation task. Tasks are scoped to the API key's account — a task created by another account's key returns 404.

curl https://trify3d.com/api/v1/generations/gen_abc123 \
  -H "Authorization: Bearer trf_live_xxx"

# 200 OK (completed)
{
  "ok": true,
  "data": {
    "taskId": "gen_abc123",
    "type": "image_to_3d",
    "status": "completed",
    "provider": "meshy",
    "outputModelUrl": "https://cdn.trify3d.com/models/gen_abc123/model.glb",
    "thumbnailUrl": "https://cdn.trify3d.com/thumbnails/gen_abc123.png",
    "creditsUsed": 20,
    "errorCode": null,
    "createdAt": "2026-06-22T13:55:00.000Z",
    "completedAt": "2026-06-22T13:58:12.000Z"
  },
  "requestId": "req_3l4m5n6o"
}

Status lifecycle: pendingprocessing completed | failed. When failed, errorCode carries the reason.

Idempotency

Network retries are common. Without idempotency, a retried generation request could create a duplicate task and charge credits twice.

Pass an Idempotency-Key header on any POST endpoint. If the key is new, the request proceeds and credits are held against it. If the same key is submitted again, the credit hold is deduplicated — no double charge.

curl -X POST https://trify3d.com/api/v1/generations/text-to-3d \
  -H "Authorization: Bearer trf_live_xxx" \
  -H "Idempotency-Key: my-unique-key-123" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

Key format

  • 1–255 characters.
  • Allowed: A–Z, a–z, 0–9, _, -.
  • A random UUID v4 per client action is recommended.

Invalid keys return 400 invalid_idempotency_key. If the header is omitted, the server generates an internal key — server-side holds are still deduplicated, but client-driven retries will not benefit from cross-request deduplication.

Webhooks

If you pass webhookUrl on task creation, we POST the result when the job finishes (success or failure).

POST {your webhookUrl}
Headers:
  X-Trify3D-Event: generation.completed   # or generation.failed
  X-Trify3D-Delivery: {taskId}
Body:
{
  "taskId": "gen_abc123",
  "type": "image_to_3d",
  "status": "completed",
  "provider": "meshy",
  "outputModelUrl": "https://...",
  "thumbnailUrl": "https://...",
  "creditsUsed": 20,
  "errorCode": null,
  "timestamp": "2026-06-22T14:00:00.000Z"
}

Delivery guarantees

  • Retries — failed deliveries (non-2xx, network errors) retried up to 3 times with delays of 1s, 5s, 15s.
  • 4xx (not 429) — treated as permanent failure, no retry.
  • Timeout — requests abort after 10s.

Return any 2xx status to acknowledge. Keep your handler fast (< 10s) — offload heavy work to a queue.

Rate limiting

Each API key: 600 requests / hour, tracked in a rolling window. Responses include X-RateLimit-Limit, X-RateLimit-Remaining, and on 429 a Retry-After header (seconds).

HeaderMeaning
X-RateLimit-LimitMax requests in the window (600).
X-RateLimit-RemainingRequests remaining in the current window.
Retry-AfterSeconds until the window resets (429 only).
X-Request-IDUnique per-request ID for debugging.

Errors

details is optional and carries structured context — e.g. validation_failed returns details.issues, insufficient_scope returns details.required / details.granted. Always include the requestId when contacting support.

CodeHTTPMeaning
missing_bearer_token401No Authorization: Bearer … header.
invalid_api_key401Key is malformed, revoked, or unknown.
insufficient_scope403Key lacks the scope for this endpoint. See details.required.
insufficient_credits402Account balance too low for this generation.
validation_failed400Request body failed validation. See details.issues.
invalid_idempotency_key400Idempotency-Key header format invalid.
invalid_request_body400Request body is not valid JSON.
rate_limit_exceeded429Hourly quota exhausted. See Retry-After.
task_not_found404No task with that ID for this account.
internal_error500Unexpected server error. Retry with backoff; report requestId.

Validation issue codes

CodeMeaning
prompt_requiredEmpty prompt (text-to-3d).
prompt_too_longPrompt exceeds the max length.
image_requiredMissing reference image, or fewer than 2 images (multiview).
image_type_unsupportedFile type not in the supported set.
image_too_largeFile exceeds the size limit.

Handling errors

  • 4xx (except 429) — do not retry blindly; fix the request.
  • 429 — honor Retry-After, then retry.
  • 5xx — retry with exponential backoff (1s, 2s, 4s, 8s).
  • Always log requestId alongside the error for traceability.

Async model

Jobs run on Trigger.dev with retries and 10-minute max duration. Poll GET /api/v1/generations/{taskId} or wait for the webhook — your choice.

© 2026 Trify3D