API & CLI
Everything the web workspace does — FMEA, drawing review, tolerance stack-up, compliance checks, the calculators — runs on one endpoint you can call from a script, a CI pipeline, or a CAD macro. Same rate limits as your plan, no separate quota.
Requires a Pro or Enterprise plan. Generate a key at Settings → API Keys.
Endpoint
multipart/form-data. Authenticate with Authorization: Bearer fp_live_.... The response streams back as raw text/plain — no JSON envelope, no SSE framing — read the bytes as they arrive and concatenate.
Fields
promptrequiredWhat you want analyzed — a plain-text description. Attach files for the model to read; for a full report (not a quick answer), lead with a clear label like "FMEA for <part>: ..." or "Tolerance stack-up for ...".
filesoptionalRepeatable multipart field. Images, PDF, STL, STEP/IGES/SAT, DXF, CSV, simulation outputs, code/text. Native CAD (SolidWorks, Inventor, CATIA, Creo) isn't readable directly — export as STEP or IGES first.
historyoptionalJSON array of {role, content} pairs from earlier turns in the same session — this is what makes a follow-up actually aware of what already ran. Defaults to [].
planoptionalIgnored. Your plan is looked up server-side from the key's owner — this field can't be used to claim a higher tier.
curl
curl -N -X POST https://forgepilot-production-9575.up.railway.app/analyze \
-H "Authorization: Bearer fp_live_your_key_here" \
-F "prompt=FMEA for a bolted flange assembly transmitting 5 kN axial load, sealing 200 bar hydraulic fluid, -40C to 120C operating range" \
-F "files=@bracket_drawing.pdf"Python
import requests
API_KEY = "fp_live_your_key_here"
BACKEND = "https://forgepilot-production-9575.up.railway.app"
with requests.post(
f"{BACKEND}/analyze",
headers={"Authorization": f"Bearer {API_KEY}"},
data={"prompt": "Tolerance stack-up for a 4-part shaft/bearing/housing chain, worst-case and RSS"},
files={"files": open("assembly.step", "rb")},
stream=True,
) as r:
r.raise_for_status()
for chunk in r.iter_content(chunk_size=None, decode_unicode=True):
print(chunk, end="", flush=True)To keep a multi-step session coherent — ask a follow-up that references a result you already got — pass the prior turns back as history:
# Follow-up turn in the same session: pass back what already happened
# as {role, content} pairs so the model has real context, not a cold prompt.
import json
history = [
{"role": "user", "content": "[Ran Drawing Review (files: bracket_drawing.pdf)]"},
{"role": "assistant", "content": "<the first response's text>"},
]
requests.post(
f"{BACKEND}/analyze",
headers={"Authorization": f"Bearer {API_KEY}"},
data={
"prompt": "What about the tolerance on the mounting hole we flagged?",
"history": json.dumps(history),
},
stream=True,
)Rate limits
| Plan | Analyses / day |
|---|---|
| Free | 10 |
| Pro | 150 |
| Enterprise | Effectively unlimited |
Shared with your web workspace usage — an API call and a UI click draw from the same daily count.
Errors
401Missing or invalid Authorization header — check the key is active and correctly prefixed with "Bearer ".
429Daily limit reached. Body includes { count, limit, reset_at } — reset_at is a UTC midnight epoch-ms timestamp.
500Something failed server-side. The response body still streams a plain-text explanation — no credit is consumed for a failure before the first token.
Prefer a CLI to raw curl?
A minimal CLI wraps this endpoint — set an env var, run one command, get a streamed result in your terminal.
Usage: forgepilot fmea --file part.pdf --context "..."
