API Reference
Programmatic access to the Polymath CAD translation service.
Base URL
https://api.polymathmade.com/v1
Authentication
Generate an API key from your API keys page. Keys begin with pw_live_. Include the key on every request:
X-Api-Key: pw_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
/convertSubmit a CAD file for conversion. The request returns immediately with a job_id; poll /status/{job_id} until the job completes, then download from /download/{job_id}.
Request Headers
X-Api-Key: pw_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx X-Output-Format: solidworks X-ITAR-Certified: true
Request Body
Send the file as multipart/form-data under the field name file. Raw binary with a X-Filename header is also accepted.
Response (202 Accepted)
{
"job_id": "fdfa3fed-4924-434f-a02b-b20a9d4c1902",
"status": "pending",
"input_format": "prt",
"output_format": "solidworks"
}When the Developer Discount is enabled, the response also includes "training_discount": true and a license_notice string.
/status/{job_id}Poll for job status. Once status is completed, the response includes feature_count and a mesh_comparison object summarizing reconstruction accuracy.
Status Values
| pending | Queued — waiting for the conversion worker. |
| processing | Worker is extracting and reconstructing the model. |
| completed | Conversion succeeded — output available at /download/{job_id}. |
| pending_review | Part requires manual review; output available within 48 hours. Includes a customer_message. |
| rejected | Part cannot be processed (e.g. neutral format with no feature history). Includes a customer_message. |
/download/{job_id}Streams the converted .sldprt file with a Content-Disposition: attachment header. Returns 409 if the job is not yet completed.
Developer Discount (Training Discount)
50% off all conversions in exchange for granting Polymath a non-exclusive, perpetual, irrevocable, royalty-free license to use your uploaded models for ML training. Can be toggled on or off at any time — only affects future uploads.
/training-discountToggle the Developer Discount on or off for your account.
Request Body
{
"enabled": true // true to opt in, false to opt out
}Response (opt in)
{
"training_discount": "enabled",
"message": "Developer Discount enabled. You receive a 50% discount on all conversions. By opting in, you grant a non-exclusive, perpetual, irrevocable, royalty-free license to use your uploaded models for machine learning training. You may opt out at any time for future uploads."
}Response (opt out)
{
"training_discount": "disabled",
"message": "Developer Discount disabled. Future uploads will not be used for training and will be billed at the standard rate."
}Error Codes
| Code | Meaning |
|---|---|
| 400 | Missing enabled field or invalid JSON |
| 401 | Invalid API key |
| 404 | No billing account or no active subscription |
| 503 | Billing/pricing not configured |
How it works
- Toggles your Stripe subscription between the standard and training metered prices (no proration).
- When enabled, every
POST /convertresponse includes"training_discount": trueand alicense_notice. GET /status/{job_id}also reflects the discount in its response.- Both the input .prt and output .sldprt are copied to Polymath's ML training pipeline.
- Opting out only affects future uploads — files already submitted under the discount remain licensed.
Code Examples
curl
# Submit a .prt file for conversion
curl -X POST https://api.polymathmade.com/v1/convert \
-H "X-Api-Key: $POLYWORKS_KEY" \
-H "X-Output-Format: solidworks" \
-H "X-ITAR-Certified: true" \
-F "file=@model.prt"
# -> {"job_id": "...", "status": "pending", ...}
# Poll status
curl https://api.polymathmade.com/v1/status/$JOB_ID \
-H "X-Api-Key: $POLYWORKS_KEY"
# Download once status is "completed"
curl -OJ https://api.polymathmade.com/v1/download/$JOB_ID \
-H "X-Api-Key: $POLYWORKS_KEY"Python
import time
import requests
BASE = "https://api.polymathmade.com/v1"
HEADERS = {"X-Api-Key": "pw_live_your_key"}
with open("model.prt", "rb") as f:
resp = requests.post(
f"{BASE}/convert",
headers={
**HEADERS,
"X-Output-Format": "solidworks",
"X-ITAR-Certified": "true",
},
files={"file": ("model.prt", f)},
)
resp.raise_for_status()
job_id = resp.json()["job_id"]
while True:
s = requests.get(f"{BASE}/status/{job_id}", headers=HEADERS).json()
if s["status"] in ("completed", "rejected", "pending_review"):
break
time.sleep(5)
if s["status"] == "completed":
out = requests.get(f"{BASE}/download/{job_id}", headers=HEADERS)
open("model.sldprt", "wb").write(out.content)Supported Feature Types
| Category | Types |
|---|---|
| Sketch | ProfileFeature3DProfileFeature |
| Extrusion | ExtrusionICE |
| Revolution | RevolutionRevCut |
| Edge | FilletChamfer |
| Body | Shell |
| Hole | HoleWzd |
| Pattern | CirPatternLPatternMirrorPattern |
| Datum | RefPlaneRefAxis |
Error Codes
| Code | Meaning |
|---|---|
| 400 | Missing required header, unsupported input/output format, or empty body |
| 401 | Missing or invalid API key |
| 403 | No active subscription on this account |
| 404 | Job not found |
| 409 | Download requested before the job reached completed |