Getting started
Get a key, run your first validation, and read the report card.
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. The site’s drag-and-drop demo uses a separate,
server-held demo key you never see — it is rate-limited per IP and watermarks its screenshots.
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.