{"openapi":"3.1.0","info":{"title":"MCPBytes API","version":"2.0.0","description":"File-processing tools for agents and developers: each tool runs as a job (GET /v1/tools lists them). Authenticate with `Authorization: Bearer mcpb_...` (API key) or an OAuth access token. The MCP server is at /mcp (all tools) and /mcp/{toolset} (one family)."},"security":[{"bearer":[]}],"paths":{"/health":{"get":{"security":[],"summary":"Liveness","responses":{"200":{"description":"OK"}}}},"/v1/me":{"get":{"summary":"Current user, plan limits, usage and credit balance","responses":{"200":{"description":"User","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"$ref":"#/components/responses/Error"}}}},"/v1/billing":{"get":{"summary":"Credit balance in detail: lots and their expiry, spending per tool, ledger","responses":{"200":{"description":"Billing","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Billing"}}}},"401":{"$ref":"#/components/responses/Error"}}}},"/v1/billing/catalog":{"get":{"summary":"What can be bought, and whether buying is open","responses":{"200":{"description":"Catalog","content":{"application/json":{"schema":{"type":"object","properties":{"available":{"type":"boolean"},"items":{"type":"array","items":{"$ref":"#/components/schemas/CatalogItem"}}}}}}},"401":{"$ref":"#/components/responses/Error"}}}},"/v1/billing/checkout":{"post":{"summary":"Start a Stripe Checkout for a catalog item (console sessions only)","description":"Credits are granted when Stripe confirms the payment, not by this call.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["item","request_id"],"properties":{"item":{"type":"string","description":"Catalog id"},"request_id":{"type":"string","format":"uuid","description":"The same id again returns the same checkout"}}}}}},"responses":{"200":{"description":"A Stripe-hosted page to open in the browser","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"400":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/billing/portal":{"post":{"summary":"Open Stripe's customer portal: invoices, payment method, change or cancel a bundle (console sessions only)","responses":{"200":{"description":"A Stripe-hosted page to open in the browser","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string"}}}}}},"403":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/uploads":{"post":{"summary":"Create a one-hour URL to PUT a model file to","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["filename"],"properties":{"filename":{"type":"string","example":"airplane.glb"}}}}}},"responses":{"201":{"description":"Upload URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Upload"}}}},"400":{"$ref":"#/components/responses/Error"}}}},"/v1/tools":{"get":{"summary":"The tools you can run, with their options and your limits","responses":{"200":{"description":"Tools","content":{"application/json":{"schema":{"type":"object","properties":{"tools":{"type":"array","items":{"$ref":"#/components/schemas/Tool"}}}}}}}}}},"/v1/tools/{tool}/jobs":{"post":{"summary":"Start a job of a tool","description":"JSON body with `upload_id` or `url`, or the input file itself as the body (any non-JSON Content-Type) with `?filename=` and the tool's options as query parameters. An `Idempotency-Key` header makes retries safe (409 idempotency_conflict if the key was used for another tool). Costs credits (the tool's `pricing`): 402 `insufficient_credits` when the balance is below the tool's smallest price; the exact price is charged once the input has been measured, and a job that fails costs nothing.","parameters":[{"name":"tool","in":"path","required":true,"schema":{"type":"string"},"description":"A tool id from GET /v1/tools, e.g. split_3d_model"},{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":100}},{"name":"filename","in":"query","description":"Raw-body uploads only","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJob"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Existing job for this Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"202":{"description":"Job created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"411":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}}},"/v1/jobs":{"post":{"summary":"Start a split_3d_model job (same as POST /v1/tools/split_3d_model/jobs)","description":"JSON body with `upload_id` or `url`, or the model file itself as the body (any non-JSON Content-Type) with `?filename=` and options as query parameters. An `Idempotency-Key` header makes retries safe. Costs credits (the tool's `pricing`): 402 `insufficient_credits` when the balance is below the tool's smallest price; the exact price is charged once the input has been measured, and a job that fails costs nothing.","parameters":[{"name":"Idempotency-Key","in":"header","schema":{"type":"string","maxLength":100}},{"name":"filename","in":"query","description":"Raw-body uploads only","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateJob"}},"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Existing job for this Idempotency-Key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"202":{"description":"Job created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"400":{"$ref":"#/components/responses/Error"},"402":{"$ref":"#/components/responses/Error"},"411":{"$ref":"#/components/responses/Error"},"413":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"},"503":{"$ref":"#/components/responses/Error"}}},"get":{"summary":"List jobs, newest first","parameters":[{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":100,"default":20}},{"name":"before","in":"query","description":"`next_before` from the previous page","schema":{"type":"integer"}},{"name":"tool","in":"query","schema":{"type":"string"},"description":"Only this tool's jobs"}],"responses":{"200":{"description":"Jobs","content":{"application/json":{"schema":{"type":"object","properties":{"jobs":{"type":"array","items":{"$ref":"#/components/schemas/Job"}},"next_before":{"type":["integer","null"]}}}}}}}}},"/v1/jobs/{id}":{"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","pattern":"^j_[0-9a-z]{26}$"}}],"get":{"summary":"Get a job (fresh download URLs)","responses":{"200":{"description":"Job","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Job"}}}},"404":{"$ref":"#/components/responses/Error"}}},"delete":{"summary":"Cancel a queued job, or delete a finished job and its files","responses":{"200":{"description":"`{id, status: canceled | deleted}`"},"409":{"$ref":"#/components/responses/Error"}}}},"/v1/jobs/{id}/files/{name}":{"get":{"summary":"Read a text output (.txt .json .md .csv) in chunks","description":"For reading results without downloading them. Every file, text or not, downloads from its signed `url` in result.files.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"name","in":"path","required":true,"schema":{"type":"string"},"description":"File name from result.files, e.g. manifest.json or meshes/part_000.glb"},{"name":"offset","in":"query","schema":{"type":"integer","minimum":0,"default":0},"description":"Byte offset"},{"name":"limit","in":"query","schema":{"type":"integer","minimum":16,"maximum":100000,"default":20000},"description":"Bytes to read"}],"responses":{"200":{"description":"A chunk","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileChunk"}}}},"400":{"description":"not_text"},"404":{"description":"No such job or file (outputs expire)"}}}},"/v1/keys":{"get":{"summary":"List API keys (console sessions only: https://console.mcpbytes.com)","responses":{"200":{"description":"`{keys: [{id, name, prefix, created_at, last_used_at}]}`"},"403":{"$ref":"#/components/responses/Error"}}},"post":{"summary":"Create an API key (console sessions only); the key is returned once","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","maxLength":60,"default":"default"}}}}}},"responses":{"201":{"description":"`{id, name, prefix, created_at, last_used_at, key}`"},"403":{"$ref":"#/components/responses/Error"},"409":{"description":"`key_limit`: at most 10 active keys and 20 new keys per 24 h"}}}},"/v1/keys/{id}":{"delete":{"summary":"Revoke an API key (console sessions only)","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Revoked"},"404":{"$ref":"#/components/responses/Error"}}}}},"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer"}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}},"schemas":{"Options":{"type":"object","additionalProperties":false,"properties":{"detail":{"enum":["low","medium","high"],"default":"medium"},"max_parts":{"type":"integer","minimum":1,"maximum":64,"description":"Safety ceiling; clamped to the plan"},"min_part_faces":{"type":"integer","minimum":0,"default":0},"min_part_area":{"type":["number","null"],"minimum":0,"exclusiveMaximum":1},"format":{"enum":["glb","obj","ply"],"default":"glb"},"preprocess":{"enum":["auto","on","off"],"default":"auto"},"segmented":{"type":"boolean","default":true},"density":{"type":["number","null"],"exclusiveMinimum":0}},"description":"Options of split_3d_model."},"CreateJob":{"type":"object","additionalProperties":false,"description":"Exactly one of upload_id or url.","properties":{"upload_id":{"type":"string","pattern":"^up_[0-9a-z]{26}$"},"url":{"type":"string","format":"uri","description":"Public https URL"},"filename":{"type":"string","description":"For the file type, if the URL does not end in the file's extension"},"options":{"type":"object","description":"The tool's options: `options` in GET /v1/tools (split_3d_model: schema Options)"},"idempotency_key":{"type":"string","maxLength":100}}},"Upload":{"type":"object","properties":{"upload_id":{"type":"string"},"method":{"const":"PUT"},"url":{"type":"string","description":"PUT the file here with a Content-Length"},"max_bytes":{"type":"integer"},"expires_at":{"type":"string","format":"date-time"}}},"Job":{"type":"object","properties":{"id":{"type":"string"},"tool":{"type":"string"},"status":{"enum":["queued","running","succeeded","failed","canceled","expired"]},"input":{"type":"object","properties":{"name":{"type":"string"},"bytes":{"type":"integer"},"source":{"enum":["upload","url","body"]}}},"options":{"type":"object","description":"The tool's options as they run (defaults applied, clamped to your plan)"},"error":{"type":["object","null"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"hint":{"type":["string","null"]}}},"result":{"type":["object","null"],"properties":{"notes":{"type":"array","items":{"type":"string"}},"files":{"type":"array","description":"One entry per output file. split_3d_model adds <model>_parts.zip holding all the others (left out, with a note, above 100 MB)","items":{"type":"object","properties":{"name":{"type":"string"},"bytes":{"type":"integer"},"sha256":{"type":"string"},"url":{"type":"string","description":"Signed download URL, valid up to 24 h"}}}}},"description":"Tool-defined summary plus `files`. split_3d_model: schema_version, part_count, input_faces, exported_faces, notes, timings_s. extract_pdf: pages, first_page, last_page, empty_pages, chars, notes. inspect_3d_model (when enabled): schema_version, object_count, mesh_instance_count, vertex_count, face_count, details_truncated, notes; files inspection.json and summary.txt. Inspection has no tool-specific options."},"compute_ms":{"type":["integer","null"]},"credits_charged":{"type":["integer","null"],"description":"What the job cost. null until the input has been measured (the job is charged then, before the work); 0 for a failed job: its charge went back"},"created_at":{"type":"string","format":"date-time"},"started_at":{"type":["string","null"],"format":"date-time"},"finished_at":{"type":["string","null"],"format":"date-time"},"outputs_expire_at":{"type":"string","format":"date-time"}}},"Me":{"type":"object","properties":{"id":{"type":"string"},"login":{"type":"string"},"email":{"type":["string","null"]},"plan":{"type":"string"},"limits":{"type":"object","description":"Account-wide limits plus `tools`: your limits for each tool"},"auth":{"enum":["oauth","key"]},"usage":{"type":"object","properties":{"jobs_last_24h":{"type":"integer"},"active_jobs":{"type":"integer"},"jobs_last_24h_by_tool":{"type":"object","additionalProperties":{"type":"integer"}}}},"credits":{"type":"object","description":"Prepaid credits: jobs are paid from this balance","properties":{"balance":{"type":"integer"},"next_expiry":{"type":["object","null"],"description":"The credits that expire first","properties":{"credits":{"type":"integer"},"at":{"type":"string","format":"date-time"}}}}}}},"Tool":{"type":"object","properties":{"id":{"type":"string","description":"Tool id: the {tool} path segment, jobs' `tool`, and the MCP tool name"},"title":{"type":"string"},"summary":{"type":"string","description":"One sentence for people"},"description":{"type":"string","description":"How an agent calls the tool (its MCP description)"},"toolset":{"type":"string","description":"The family served at /mcp/{toolset}"},"input_extensions":{"type":"array","items":{"type":"string"}},"options":{"type":"object","description":"JSON Schema of the tool's job options"},"limits":{"type":"object","description":"Your limits for this tool (tool-specific ones, and jobs_per_day: an abuse cap, not an allowance)"},"pricing":{"$ref":"#/components/schemas/Pricing"},"jobs":{"type":"string","description":"URL to POST jobs to"},"mcp":{"type":"string","description":"The toolset's MCP endpoint"}}},"FileChunk":{"type":"object","properties":{"name":{"type":"string"},"offset":{"type":"integer"},"next_offset":{"type":"integer","description":"Pass as offset to continue; never inside a character"},"total_bytes":{"type":"integer"},"eof":{"type":"boolean"},"text":{"type":"string"}}},"Pricing":{"type":"object","description":"What a job of the tool costs, in credits (100 credits = US$1). The price depends on the size of the input, measured in `unit`.","properties":{"kind":{"type":"string","enum":["tiers","per","free"],"description":"tiers: the first tier the input fits in (beyond the last tier, the last tier again for each further `upTo` units); per: `credits` for every started `per` units; free: no credits"},"unit":{"type":"string","enum":["faces","pages"]},"tiers":{"type":"array","items":{"type":"object","properties":{"upTo":{"type":"integer"},"credits":{"type":"integer"}}}},"per":{"type":"integer"},"credits":{"type":"integer"},"description":{"type":"string","description":"The price in one sentence"}}},"Billing":{"type":"object","properties":{"balance":{"type":"integer"},"lots":{"type":"array","description":"What the balance is made of; credits are spent from the lot that expires first","items":{"type":"object","properties":{"kind":{"type":"string","enum":["signup","pack","subscription","adjustment"]},"credits":{"type":"integer"},"remaining":{"type":"integer"},"expires_at":{"type":"string","format":"date-time"},"created_at":{"type":"string","format":"date-time"}}}},"spent_last_30_days_by_tool":{"type":"object","additionalProperties":{"type":"integer"}},"entries":{"type":"array","description":"The 50 latest ledger entries, newest first","items":{"type":"object","properties":{"kind":{"type":"string","enum":["grant","charge","refund","expire","clawback"]},"amount":{"type":"integer"},"job_id":{"type":["string","null"]},"tool":{"type":["string","null"]},"created_at":{"type":"string","format":"date-time"}}}},"frozen":{"type":"boolean","description":"A disputed payment has the account on hold: no jobs, no purchases"},"portal":{"type":"boolean","description":"The account has bought before, so Stripe's portal is open to it"},"subscription":{"type":["object","null"],"description":"The monthly credit bundle, if any","properties":{"plan":{"type":"string","description":"Catalog id"},"status":{"type":"string"},"renews_at":{"type":["string","null"],"format":"date-time"},"ends_at":{"type":["string","null"],"format":"date-time","description":"Canceled: the bundle runs out then"}}}}},"CatalogItem":{"type":"object","properties":{"id":{"type":"string"},"kind":{"type":"string","enum":["pack","bundle"],"description":"pack: paid once, credits last 12 months. bundle: paid monthly, credits roll over for one extra month"},"name":{"type":"string"},"priceUsd":{"type":"number"},"credits":{"type":"integer","description":"Per purchase (pack) or per paid month (bundle)"},"terms":{"type":["string","null"],"description":"A bundle's renewal terms"}}}}},"servers":[{"url":"https://api.mcpbytes.com"}]}