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, Excel (.xlsx), 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