Skip to content
Staging environmentWaffo Pancake sandbox: no real charges. Accounts and assets are separate from production.Production site

Developer API

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

Base URL
https://gzhclaw.com/api/v1
Auth
Bearer trf_live_…
Format
JSON
Rate limit
600 / hour / key

Quickstart

Create an API key

Sign in, open Account → API Keys → Create. Copy the plaintext value immediately; it is shown only once.

Make your first request

Generate a 3D model from text:

curl -X POST https://gzhclaw.com/api/v1/generations/text-to-3d \
  -H "Authorization: Bearer trf_live_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "type": "text_to_3d",
    "prompt": "A medieval sword with a golden hilt",
    "style": "realistic",
    "mode": "quality",
    "webhookUrl": "https://yourapp.com/hooks/open3dai"
  }'

# 201 Created
{
  "ok": true,
  "data": {
    "taskId": "gen_abc123",
    "provider": "procedural",
    "status": "processing",
    "creditsUsed": 20,
    "creditsRemaining": 980
  },
  "requestId": "req_1a2b3c4d"
}

Poll or wait for the webhook

Poll GET /generations/{taskId}. When status is completed, data.outputModelUrl points at the generated .glb.

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

Response envelope

All responses follow one envelope, and every response carries an X-Request-ID header — include it when reporting an issue.

// 成功 (2xx)
{ "ok": true, "data": { … }, "requestId": "req_abc123" }
// 失败 (4xx / 5xx)
{
  "ok": false,
  "error": {
    "code": "snake_case_code",
    "message": "Human-readable message.",
    "requestId": "req_abc123",
    "details": { }
  }
}

Endpoints

MethodPathScopesDescription
POST/generations/text-to-3dwrite Generate a 3D model from a natural-language prompt.
POST/generations/image-to-3dwrite Turn one reference image (JPG/PNG/WEBP as a base64 data URL) into a textured 3D model.
POST/generations/multiview-to-3dwrite Reconstruct a 3D model from at least 2 photos taken from different angles.
GET/generations/{taskId}read Poll task status, output URL and credit usage.
GET/generations/{taskId}/modelread Download the generated model file directly.
GET/usageread Check credit balance and rate-limit quota without spending credits.
GET/api/docs— Interactive OpenAPI documentation.

Idempotency

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

-H "Idempotency-Key: 8f14e45f-ceea-467a-9a1e-3b1c2d4e5f60"
  • Format: 1–255 characters from A–Z a–z 0–9 _ -. A random UUID v4 per client action is recommended.
  • The same key with an identical body replays the first response and does not charge again.
  • The same key with a different body returns 400 validation_failed.
  • A malformed key returns 400 invalid_idempotency_key.

Webhooks

Pass webhookUrl at creation and we POST the result when the job finishes, success or failure.

POST {your webhookUrl}
X-open3dai-Event: generation.completed   # or generation.failed
X-open3dai-Delivery: gen_abc123

{
  "taskId": "gen_abc123",
  "status": "completed",
  "outputModelUrl": "https://gzhclaw.com/api/v1/generations/gen_abc123/model",
  "thumbnailUrl": "https://gzhclaw.com/api/v1/generations/gen_abc123/thumbnail",
  "creditsUsed": 20,
  "errorCode": null,
  "timestamp": "2026-08-14T14:00:00Z"
}
Delivery guarantees. Failures (non-2xx or network errors) are retried up to 3 times after 1s, 5s and 15s. A 4xx other than 429 is a permanent failure and is not retried. Requests time out after 10 seconds, so acknowledge quickly and offload heavy work.

Rate limiting

Each API key gets 600 requests per hour in a rolling window.

HeaderMeaning
X-RateLimit-LimitMaximum requests in the window (600).
X-RateLimit-RemainingRequests remaining in the current window.
Retry-AfterReturned on 429 only: seconds until the window resets.
X-Request-IDUnique per-request identifier for debugging.

Errors

CodeHTTPTrigger
missing_bearer_token401No Authorization: Bearer … header was supplied.
invalid_api_key401The key is malformed, revoked or unknown.
insufficient_scope403The key lacks the scope for this endpoint.
insufficient_credits402Account balance is too low for this generation.
validation_failed400The body failed validation; see details.issues.
invalid_idempotency_key400The Idempotency-Key header is malformed.
invalid_request_body400The request body is not valid JSON.
rate_limit_exceeded429Hourly quota exhausted; see Retry-After.
task_not_found404No such task for this account.
internal_error500Unexpected server error; report the requestId.

Validation issue codes

  • prompt_required — empty prompt for text-to-3D.
  • prompt_too_long — prompt exceeds 2000 characters.
  • image_required — imageDataUrl is missing.
  • invalid_image_format — not a supported base64 data URL.
  • image_too_large — decoded image exceeds 20MB.
  • multiview_requires_two_images — fewer than 2 images for multiview.
  • invalid_mode — mode must be speed or quality.
  • invalid_style — style is not recognised.
  • idempotency_key_reused — same idempotency key with a different body.

Create an API key

Sign in, open Account → API Keys → Create. Copy the plaintext value immediately; it is shown only once.