Getting started
Get a key, run your first validation, and read the report card.
Get a key
Everything below needs an API key. Getting one is self-serve and takes a minute:
- Pick a plan on the pricing page. Free ($0, 300 credits/month) needs no card; paid plans (Indie, Studio, Scale) run on Polar, our merchant of record.
- Sign up at /signup with your email. We send a single-use sign-in link — no password. (A paid plan carries you straight to checkout after you sign in.)
- Mint a key from your dashboard. The raw key is shown once, right then — we store only a hash and can’t recover it. If you lose it, mint a new one and revoke the old. Keys are never sent by email.
The site’s drag-and-drop demo needs none of this: it runs on a separate, server-held demo key you never see, rate-limited per IP.
Authentication
Every request carries your key in the X-Api-Key header:
X-Api-Key: mc_live_...
No key returns 401 MISSING_API_KEY; a bad key returns 401 INVALID_API_KEY. Keys map to an account
with a credit balance and a per-plan rate limit.
Your first validation
Send a model as multipart/form-data with a file field. Pick a budget profile (web, mobile,
pc, or hero); it sets the thresholds the checks measure against.
curl -X POST https://api.meshcheck.dev/v1/validate \
-H "X-Api-Key: mc_live_..." \
-F file=@barrel.glb \
-F profile=web
Files up to the platform’s multipart cap (~4.5 MB) post directly. For larger models, send a JSON body
with a public url (the server fetches it, with an SSRF guard), or use the presigned upload flow:
POST /v1/uploads returns a single-use upload_url and a blob_id, you PUT the bytes, then validate
by blob_id. Models up to 20 MB validate synchronously; above that, the call returns a job envelope you
poll.
Reading the report card
The response is a single JSON document. Three fields carry the verdict:
verdict— the rollup:pass,warn, orfail. Anyerror-severity check that fails makes the whole reportfail; anywarnand no failures makes itwarn; otherwisepass. There is no numeric score.summary— counts oferrors,warnings,info, andskippedresults.checks[]— oneCheckResultper check, in a fixed ID order, each with structuredmeasuredandthresholdobjects and a human-readablemessagederived from them.
{
"verdict": "fail",
"summary": { "errors": 1, "warnings": 2, "info": 6, "skipped": 0 },
"checks": [
{
"id": "PERF-001",
"name": "Triangle count",
"status": "fail",
"measured": { "triangles": 48231 },
"threshold": { "max_tris": 25000 },
"message": "48,231 triangles exceeds profile budget of 25,000"
}
]
}
An agent acts on status and the structured measured/threshold values — never by parsing the
message prose. Because the core is deterministic, the same file and profile always produce the same
report (timestamps and signed URLs aside), so you can cache and diff reports across regenerations.
Determinism and the one exception
Every /validate check is a pure measurement. The only non-deterministic surface is /inspect, which
asks a vision model a semantic question (“does this look like a barrel?”). It is a separate endpoint,
priced separately, and every answer is labelled deterministic: false with the model version. Vision
opinions never appear in a /validate report.
Next steps
- The Checks reference — every check ID, what it measures, and its default severity.
- The API reference — every endpoint, option, error code, and credit cost.
- The Report schema — the field-by-field contract your code builds against.
- The MCP guide — drive meshcheck from Claude Code or any MCP client.