PartWork.ai Developer API Guide
Generate production-ready CAD parts from code. This guide walks through every real step: creating an API key in the studio, authenticating your request, starting a generation job, polling for the result, and downloading your STEP or STL. No invented routes — everything here is the live API.
Base URL and versioning
All endpoints are under https://api.partwork.ai/v1. There is no versioning in the path beyond v1 — breaking changes will be communicated in advance. Responses are JSON; requests must include Content-Type: application/json where a body is expected.
Full API reference
The canonical reference lives at developer.partwork.ai. This guide focuses on the most common path: generate a part, poll for completion, and export the file.
Step 1 — Create an API key
API keys are tied to your registered account. You need to be signed in to studio.partwork.ai to create one. Guest accounts cannot use the developer API.
Once signed in, open your account settings and navigate to the Developer section. Click Create API key, give it a name (up to 50 characters — use something descriptive like “Production App” or “CI Pipeline”), and copy the key immediately. The full key is shown only once — it is stored as a hash and cannot be retrieved again. If you lose it, revoke it and create a new one.
Keys look like: pk_live_a1b2c3d4e5f6... (the prefix is always pk_live_, followed by 32 hex characters). You can have up to 10 active keys per account. Each key starts on the free tier: 60 requests/minute, 1,000 requests/day, 100 generations/month. These limits are per-key, not per-account.
You can also create a key via the API itself (useful for automation):
POST /v1/developer/keys
Authorization: Bearer <your-jwt-token>
Content-Type: application/json
{
"name": "Production App",
"permissions": ["generate", "export"]
}
// Response (201):
{
"key_id": "key_abc123def456",
"key": "pk_live_a1b2c3...", // shown only once
"key_preview": "pk_live_...o5p6",
"name": "Production App",
"permissions": ["generate", "export"],
"rate_limit_tier": "free",
"created_at": "2026-06-06T01:00:00Z"
}The permissions field is optional. If omitted, the key gets all four default permissions: generate, export, import, parts:read. You can scope a key to fewer permissions for least-privilege access.
Note: the key management endpoints (POST /v1/developer/keys, GET /v1/developer/keys, DELETE /v1/developer/keys/{key_id}) require JWT authentication only — they cannot be called using an API key. This prevents a compromised key from creating or revoking other keys.
Step 2 — Authenticate
Pass your API key in the X-API-Key header on every request. No Authorization: Bearer prefix — just the raw key value.
X-API-Key: pk_live_a1b2c3d4e5f6...If the key is invalid, revoked, or expired, the API returns 403 Forbiddenwith a JSON error body. If you exceed the per-minute rate limit, you receive 403 with rate-limit headers:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1749168060 // Unix timestampBack off and retry after the X-RateLimit-Reset timestamp. The daily limit (1,000 requests) resets at midnight UTC.
Step 3 — Start a generation job
Generation is asynchronous. You post a prompt and get back a job_id immediately — the actual CAD generation runs in the background and typically completes within 15–60 seconds depending on part complexity.
POST https://api.partwork.ai/v1/generate
X-API-Key: pk_live_...
Content-Type: application/json
{
"prompt": "A 50mm x 30mm x 10mm rectangular bracket with two M3 clearance holes spaced 40mm apart"
}
// Response (200):
{
"job_id": "3f8a2c1d-...",
"status": "processing",
"credits_remaining": 98
}The prompt field is required. One credit is deducted atomically when the job starts — you will not be double-charged if the generation fails. Credits are your account credits; API key users draw from the same credit pool as the studio.
Optional body fields:
conversation_id
Link the generation to an existing conversation (string). Enables multi-turn context: the AI sees prior turns and current model geometry. Create a conversation first via POST /v1/conversations.
imported_step_key
S3 key of a previously uploaded STEP file (string). Use this to modify an existing model rather than generating from scratch. Pair with the upload flow described below.
web_search_enabled
Boolean (default true). When enabled, the AI can look up real-world dimensions for named objects (e.g., a standard USB-A port). Set to false for fully offline / reproducible generation.
selected_faces
Array of face labels (e.g., ["Face 1", "Face 3"]). Scopes the operation to specific faces of the current model when modifying a part with conversation context.
Credits note
If the response is 402 Payment Required, your credit balance is zero. Purchase 100 credits for $4.99 (~5¢ each) in the studio at studio.partwork.ai. Start with 2 free generations — no card required when you sign up.
Step 4 — Poll for job completion
After starting a job, poll GET /v1/job/{job_id} until status is completed or failed. No auth header is needed — the job_id itself is the access credential.
GET https://api.partwork.ai/v1/job/3f8a2c1d-...
// While processing:
{
"status": "processing"
}
// When complete:
{
"status": "completed",
"result": {
"success": true,
"summary": "Created a 50×30×10mm rectangular bracket with two M3 clearance holes.",
"glb_url": "https://...", // presigned GLB for 3D preview
"glb_key": "models/3f8a.../model.glb",
"step_key": "models/3f8a.../model.step",
"dimensions": { "x": 50, "y": 30, "z": 10 },
"job_id": "3f8a2c1d-..."
}
}
// On failure:
{
"status": "failed",
"error": "Insufficient credits"
}A sensible polling strategy: wait 5 seconds, then poll every 3 seconds, up to a 2-minute timeout. Most simple parts complete in under 30 seconds; complex multi-step plans can take longer.
// Python polling example
import time, requests
API_KEY = "pk_live_..."
BASE = "https://api.partwork.ai/v1"
def poll_job(job_id, timeout=120, interval=3):
deadline = time.time() + timeout
time.sleep(5) # initial wait
while time.time() < deadline:
r = requests.get(f"{BASE}/job/{job_id}")
data = r.json()
if data["status"] == "completed":
return data["result"]
if data["status"] == "failed":
raise RuntimeError(data.get("error", "Generation failed"))
time.sleep(interval)
raise TimeoutError("Job timed out")Step 5 — Export the model
Once the job is complete, you can download the model in three formats: STEP, STL, or 3MF. Use POST /v1/export with an API key that has the export permission (included in the default permission set). You need a conversation_id for export — if you passed one to /v1/generate, use that; otherwise create a conversation and pass its id.
POST https://api.partwork.ai/v1/export
X-API-Key: pk_live_...
Content-Type: application/json
{
"conversation_id": "conv_xxx",
"format": "step" // "step" | "stl" | "3mf"
}
// Response (200):
{
"success": true,
"download_url": "https://...presigned...",
"filename": "My Part.step"
}The download_url is a presigned S3 URL valid for a short window — download the file immediately and store it yourself if you need it long-term.
Which format?
Use STEP for CNC machining, sending to a shop, or re-importing into a CAD tool — it carries exact solid geometry. Use STL or 3MF for 3D printing. For the full comparison, see STL vs STEP.
Managing your keys
List your active keys with GET /v1/developer/keys (JWT auth required). Each key record includes key_preview (last 4 characters), usage stats, and the current rate-limit tier. Revoke a key you no longer need with DELETE /v1/developer/keys/{key_id}.
Check your usage with GET /v1/developer/usage (API key auth is fine here). The response includes requests today, requests this month, generations this month, and your current limits.
GET https://api.partwork.ai/v1/developer/usage
X-API-Key: pk_live_...
// Response:
{
"totals": {
"requests_today": 12,
"requests_this_month": 87,
"generations_this_month": 9
},
"limits": {
"requests_per_day": 1000,
"generations_per_month": 100
},
"tier": "free",
"period": { "month": "2026-06", "day": "2026-06-06" }
}Minimal end-to-end example
Here is a complete Python example that creates a part and downloads the STEP file:
import time, requests
API_KEY = "pk_live_your_key_here"
BASE = "https://api.partwork.ai/v1"
HEADERS = {"X-API-Key": API_KEY, "Content-Type": "application/json"}
# 1. Create a conversation (needed for export)
conv = requests.post(f"{BASE}/conversations", headers=HEADERS, json={
"name": "API bracket"
}).json()
conversation_id = conv["conversation_id"]
# 2. Start generation
job = requests.post(f"{BASE}/generate", headers=HEADERS, json={
"prompt": "50mm × 30mm × 10mm bracket, two M3 clearance holes 40mm apart",
"conversation_id": conversation_id,
}).json()
job_id = job["job_id"]
print(f"Job started: {job_id}")
# 3. Poll until complete
time.sleep(5)
for _ in range(40):
r = requests.get(f"{BASE}/job/{job_id}").json()
if r["status"] == "completed":
print("Complete:", r["result"]["summary"])
break
if r["status"] == "failed":
raise RuntimeError(r.get("error"))
time.sleep(3)
# 4. Export as STEP
exp = requests.post(f"{BASE}/export", headers=HEADERS, json={
"conversation_id": conversation_id,
"format": "step",
}).json()
# 5. Download the file
step_bytes = requests.get(exp["download_url"]).content
with open(exp["filename"], "wb") as f:
f.write(step_bytes)
print(f"Saved {exp['filename']} ({len(step_bytes):,} bytes)")Start with 2 free AI generations — no card required
Sign up at studio.partwork.ai to get your API key and 2 free generations. Need more? 100 credits for $4.99 (~5¢ each). Read the full reference at developer.partwork.ai.