Generate 3D models with two API calls
Integrate 3D model generation into your pipeline. POST a job (a photo, 2-6 photos of the same object, or a text prompt), poll its status, download a server-validated GLB — metered by credits, failed jobs refunded automatically.
Get API KeyNot a developer? Use the web app instead — no code required.
How the job flow works
3D generation takes 30-60+ seconds, so the API is asynchronous:
- 1 — Create
POST /api/v1/3d/jobsreturns202with ajob_idimmediately. Credits are charged here.- 2 — Poll
GET /api/v1/3d/jobs/{job_id}every ~3 seconds:queued → processing → succeeded | failedwith aprogressnumber. If a job fails, the charge is refunded automatically.- 3 — Download
- On success the payload carries
output.model_url(GLB, validated server-side: it parses and contains meshes) plus polygon/texture stats and a turntable MP4 URL.
Get started
Create an API key in your dashboard, top up credits, then send your first job. A generation costs 2 credits — failed jobs are never charged (auto-refund). Authenticate with X-Api-Key: g3_live_… (or Authorization: Bearer g3_live_…).
Sample code
Create → poll → download:
# 1. create the job (text mode shown; see Modes for image/multi-view)
curl -X POST https://usely.tools/api/v1/3d/jobs \
-H "X-Api-Key: g3_live_..." \
-H "Content-Type: application/json" \
-d '{ "mode": "text", "prompt": "a vintage leather armchair", "quality": "standard" }'
# → 202 { "data": { "job_id": "...", "status": "queued", ... } }
# 2. poll until succeeded (every ~3s)
curl -H "X-Api-Key: g3_live_..." https://usely.tools/api/v1/3d/jobs/JOB_ID
# 3. download the validated GLB
curl -L -o model.glb "https://usely.tools/api/demo/3d/jobs/JOB_ID/model?download=1"Modes & quality
| Mode | Input | Notes |
|---|---|---|
image (1 photo) | images: [url | data-URL] | Best with a single centered object on a clean background, ≥512px. Optional remove_background preprocessing. |
image (multi-view) | images: [2-6 photos] | Same object from different angles (front/back/left/right/top recommended). Improves hidden-side geometry. |
text | prompt | We render a square reference image first (returned as reference_image_url), then reconstruct it in 3D. |
| Quality | Texture size | Sampling steps |
|---|---|---|
fast | 512 px | 12 |
standard (default) | 1024 px | 12 |
high | 2048 px | 25 (more detail kept) |
Output format is GLB (binary glTF). OBJ/FBX export ships when our conversion passes validation — we do not expose formats we cannot produce reliably.
API Reference
POST /api/v1/3d/jobs
Creates a generation job. JSON body only. Requires an API key in the X-Api-Key header (or a Bearer token in Authorization). Responds 202 with the job to poll.
Request body — application/json
| Parameter | Type | Description |
|---|---|---|
mode | string | image or text. Required. |
images | string[] | 1-6 image sources (http(s) URLs or data URLs, JPG/PNG/WebP, ≤12 MB each). Required in image mode. 2+ entries = multi-view of the same object. |
prompt | string | Object description, 3-300 chars. Required in text mode. |
quality | string | fast · standard (default) · high. |
remove_background | boolean | Image mode only: run background removal on each photo before reconstruction (default false). Helps with busy backdrops. |
seed | integer | Reproducible generation. Omit for a random seed (returned in the response — reuse it to retry, omit it for a variation). |
Request headers
| Header | Description |
|---|---|
X-Api-Key | Your API key (g3_live_…). Also accepted as Authorization: Bearer …. |
Idempotency-Key | Optional. Retries with the same key return the original 202 and are never double-charged. |
GET /api/v1/3d/jobs/{job_id}
Polls a job. The response envelope:
{
"data": {
"job_id": "0jw2...",
"status": "succeeded", // queued | processing | succeeded | failed
"progress": 100, // 0-100
"output": {
"model_url": "/api/demo/3d/jobs/0jw2.../model", // validated GLB (proxied)
"provider_model_url": "https://replicate.delivery/...", // direct, expires
"turntable_url": "https://replicate.delivery/....mp4",
"stats": {
"triangles": 24310, "vertices": 13544, "meshes": 1,
"materials": 1, "textures": 1, "maxTextureSize": 1024,
"bytes": 2381244, "animations": 0
}
},
"error": null // { "code", "message" } when failed
}
}Responses
| Code | Description |
|---|---|
202 | Job created. Headers include X-Credits-Charged, X-Credits-Remaining, Location (poll URL) and rate-limit headers. |
400 | Invalid parameters (no credits charged). Envelope: { "error": { "code", "message" } }. |
401 | Authentication failed — missing or invalid API key (no credits charged). |
402 | Insufficient credits (no credits charged). |
429 | Rate limit exceeded (no credits charged). Includes a Retry-After header. |
500 | Provider failure at creation (no credits charged). Failures AFTER creation are refunded automatically. |
Account endpoint
GET /api/v1/account
Fetch the current credit balance for the authenticated key. Balance changes may lag a few seconds; to track locally, read this once and then adjust using the X-Credits-Charged header returned by each job creation.
{
"data": {
"credits": { "balance": 200 }
}
}