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

POST https://forgepilot-production-9575.up.railway.app/analyze

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

promptrequired

What 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 ...".

filesoptional

Repeatable 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.

historyoptional

JSON 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 [].

planoptional

Ignored. 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

PlanAnalyses / day
Free10
Pro150
EnterpriseEffectively unlimited

Shared with your web workspace usage — an API call and a UI click draw from the same daily count.

Errors

401

Missing or invalid Authorization header — check the key is active and correctly prefixed with "Bearer ".

429

Daily limit reached. Body includes { count, limit, reset_at } — reset_at is a UTC midnight epoch-ms timestamp.

500

Something 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.

pip install forgepilot-cli

Usage: forgepilot fmea --file part.pdf --context "..."

Or download the single-file script directly