API reference

Meshra API

Programmatic access to Meshra's CAD generation. Render starters, gifts, and chat-driven parts from your own scripts and apps.

Quick start

  1. Create an API key in Settings → API keys. Copy the value; it's shown once.
  2. Call any endpoint with the Authorization: Bearer mk_... header.
curl -X POST https://meshra.ai/api/v1/starters/phone_stand \
  -H "Authorization: Bearer mk_..."

Authentication

All /api/v1/* endpoints require an Authorization header with a Bearer key. Keys are SHA-256 hashed at rest; revoke any from your Settings page.

Rate limits

POST /v1/chat is limited to 50 calls per key per day (UTC). All other endpoints are unlimited (deterministic, no LLM cost).

Endpoints

POST/api/v1/starters/:id

Render a parametric starter by id (e.g. phone_stand, gridfinity_bin). Returns a generation with file URLs and the param manifest. Cached per-user: repeat calls for the same starter return the same generation.

curl -X POST https://meshra.ai/api/v1/starters/phone_stand \
  -H "Authorization: Bearer mk_..."

Response (200):

{
  "generationId": "abc123",
  "glbUrl": "https://meshra.ai/generated/abc123/part.glb",
  "stepUrl": "https://meshra.ai/generated/abc123/part.step",
  "stlUrl": "https://meshra.ai/generated/abc123/part.stl",
  "paramManifest": [...],
  "paramValues": {...}
}
POST/api/v1/gifts

Render a gift template. Body: { templateId, config }.

curl -X POST https://meshra.ai/api/v1/gifts \
  -H "Authorization: Bearer mk_..." \
  -H "Content-Type: application/json" \
  -d '{"templateId":"coaster","config":{"primaryText":"Cheers"}}'
POST/api/v1/generations/:id/params

Re-execute a generation with new param values. Body: { params: { width: 90, ... } }. Bumps the generation's version.

curl -X POST https://meshra.ai/api/v1/generations/abc123/params \
  -H "Authorization: Bearer mk_..." \
  -H "Content-Type: application/json" \
  -d '{"params":{"width":90}}'
POST/api/v1/chat

Async generation from a freeform prompt. Returns 202 with a generationId immediately; the work continues server-side. Poll GET /v1/generations/:id until status === "completed".

curl -X POST https://meshra.ai/api/v1/chat \
  -H "Authorization: Bearer mk_..." \
  -H "Content-Type: application/json" \
  -d '{"prompt":"A vibration-damping motor mount with M3 captive inserts"}'

Response (202):

{ "generationId": "abc123", "status": "processing" }
GET/api/v1/generations/:id

Poll a generation's status and outputs.

curl https://meshra.ai/api/v1/generations/abc123 \
  -H "Authorization: Bearer mk_..."

Response when complete:

{
  "generationId": "abc123",
  "status": "completed",
  "glbUrl": "https://meshra.ai/generated/abc123/part.glb",
  "stepUrl": "https://meshra.ai/generated/abc123/part.step",
  "stlUrl": "https://meshra.ai/generated/abc123/part.stl",
  "paramManifest": [...],
  "paramValues": {...},
  "createdAt": "2026-05-09T12:00:00.000Z"
}

Polling pattern

For chat-driven generations, poll every 2–3 seconds:

# Bash example
GEN=$(curl -s -X POST https://meshra.ai/api/v1/chat \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt":"a hex bolt M8x40"}' | jq -r .generationId)

while true; do
  STATUS=$(curl -s https://meshra.ai/api/v1/generations/$GEN \
    -H "Authorization: Bearer $KEY" | jq -r .status)
  [ "$STATUS" = "completed" ] && break
  [ "$STATUS" = "failed" ] && echo "failed" && break
  sleep 2
done

Errors

StatusMeaning
401Invalid or revoked API key
403Generation belongs to another user
404Generation or starter not found
429Daily chat quota exceeded
500Sidecar or pipeline failure