Codefast 3D Studio API
Generate stunning 3D models from text and images using our REST API. All endpoints require API key authentication.
Authentication
All API requests require a valid API key in the Authorization header:
Authorization: Bearer sk-your-api-key-here
Keys use the sk-xxxx format. Contact your administrator to get one.
Errors
Standard HTTP status codes are used:
| Code | Description |
| 200 | Success |
| 400 | Bad Request — Invalid parameters |
| 401 | Unauthorized — Invalid or missing API key |
| 429 | Rate Limited — Daily credit limit exceeded |
| 500 | Internal Server Error |
{ "error": "Daily credit limit exceeded. Used: 500/500" }
Text to 3D
POST/api/text-to-3d
Create a 3D model from text. Two stages: preview (geometry) and refine (texture).
Preview Parameters
| Parameter | Type | Req | Description |
| mode | string | YES | Set to "preview" |
| prompt | string | YES | Description (max 600 chars) |
| ai_model | string | No | "latest" - Codefast 3D v1.0 engine. Default value. |
| topology | string | No | "triangle" | "quad" |
| target_polycount | int | No | 100–300,000 (default: 30,000) |
| symmetry_mode | string | No | "auto" | "on" | "off" |
curl -X POST https://your-worker.dev/api/text-to-3d \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{"mode":"preview","prompt":"a futuristic robot","ai_model":"latest"}'
Refine Parameters
| Parameter | Type | Req | Description |
| mode | string | YES | Set to "refine" |
| preview_task_id | string | YES | Task ID from preview step |
Response
{"taskId":"018a210d-xxx","creditsUsed":20,"remaining":480}
Image to 3D
POST/api/image-to-3d
Create a 3D model from an image (base64 or public URL).
| Parameter | Type | Req | Description |
| image_url | string | YES | Public URL or base64 data URI |
| ai_model | string | No | "latest" - Codefast 3D v1.0 engine. Default value. |
| should_texture | bool | No | Generate textures (default: true) |
| enable_pbr | bool | No | PBR maps (default: false) |
| texture_prompt | string | No | Guide texture generation |
curl -X POST https://your-worker.dev/api/image-to-3d \
-H "Authorization: Bearer sk-your-key" \
-H "Content-Type: application/json" \
-d '{"image_url":"https://example.com/img.jpg","should_texture":true}'
Get Task Status
GET/api/tasks/:id?type=text-to-3d
Poll a task's progress. Use type=image-to-3d for image tasks.
| Status | Description |
| PENDING | Queued, waiting |
| IN_PROGRESS | AI is generating |
| SUCCEEDED | Ready for download |
| FAILED | Check task_error |
{
"id": "018a210d-xxx",
"status": "SUCCEEDED",
"progress": 100,
"model_urls": {"glb":"/api/assets/tasks/018a210d-xxx/model.glb"},
"thumbnail_url": "/api/assets/tasks/018a210d-xxx/thumbnail.jpg"
}
All asset URLs are served from our CDN. No external dependencies.
Stream Task (SSE)
GET/api/tasks/:id/stream?type=text-to-3d
Server-Sent Events for real-time progress updates. Requires Authorization header, so use fetch with streaming:
const resp = await fetch('/api/tasks/xxx/stream?type=text-to-3d', {
headers: { Authorization: 'Bearer sk-your-key' }
});
const reader = resp.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
for (const line of buffer.split('\n')) {
if (line.startsWith('data:')) {
const data = JSON.parse(line.substring(5).trim());
console.log(data.progress + '%', data.status);
if (data.status === 'SUCCEEDED' || data.status === 'FAILED') break;
}
}
}
Generation History
GET/api/history
Last 100 generations.
{"items":[{"taskId":"xxx","type":"text-to-3d-preview","prompt":"a castle","status":"SUCCEEDED","thumbnailUrl":"https://..."}]}
Usage & Credits
GET/api/usage
{"currentUsage":45,"limit":500,"remaining":455,"allowed":true}
Credit Costs
| Operation | Credits |
| Text to 3D Preview | 20 |
| Text to 3D Refine | 10 |
| Image to 3D w/ texture | 30 |
| Image to 3D w/o texture | 20 |
Code Examples
Python
import requests, time
BASE = "https://your-worker.dev"
headers = {"Authorization": "Bearer sk-your-key"}
# Preview
r = requests.post(f"{BASE}/api/text-to-3d",
headers=headers, json={"mode":"preview","prompt":"crystal dragon"})
task_id = r.json()["taskId"]
# Poll
while True:
t = requests.get(f"{BASE}/api/tasks/{task_id}?type=text-to-3d", headers=headers).json()
if t["status"] == "SUCCEEDED":
print("GLB:", t["model_urls"]["glb"]); break
elif t["status"] == "FAILED":
print("Failed"); break
time.sleep(5)
# Refine
r = requests.post(f"{BASE}/api/text-to-3d",
headers=headers, json={"mode":"refine","preview_task_id":task_id})
JavaScript
const BASE = "https://your-worker.dev";
const headers = { Authorization: "Bearer sk-your-key", "Content-Type": "application/json" };
const { taskId } = await fetch(BASE + "/api/text-to-3d", {
method: "POST", headers,
body: JSON.stringify({ mode: "preview", prompt: "crystal dragon" })
}).then(r => r.json());
const poll = async () => {
const t = await fetch(BASE + "/api/tasks/" + taskId + "?type=text-to-3d", { headers }).then(r => r.json());
if (t.status === "SUCCEEDED") console.log("GLB:", t.model_urls.glb);
else if (t.status !== "FAILED") setTimeout(poll, 5000);
};
poll();