The API at a glance
This is the one-screen tour of the mock API. The full, authoritative contract lives in the docs portal and /openapi.json — generate a typed client from the spec rather than transcribing field names.
The wire convention
Section titled “The wire convention”- Base URL:
https://partifact-mock-rails.thanhvuttv.workers.dev - Every call:
POST <base>/api/2026-01/<dotted.method>with a JSON body. The method is the last path segment, e.g..../api/2026-01/repairer.jobs.get. It’s RPC-over-POST, date-versioned (2026-01) — not REST resources. - Two headers on every call (except the install call):
Authorization: Bearer <api_key>Partly-Integration-ID: <integration_id>
Your first call — read the seeded demo job with pre-loaded repairer credentials, no install needed:
curl -s https://partifact-mock-rails.thanhvuttv.workers.dev/api/2026-01/repairer.jobs.get \ -H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \ -H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \ -H "Content-Type: application/json" \ -d '{"identity":{"external":"CCC-2026-04817"}}'The OAuth install flow
Section titled “The OAuth install flow”A real integration provisions itself rather than using hand-pasted keys. The install call — integrations.insert — is the one method that takes no auth headers; it exchanges an OAuth grant for the api_key + integration_id every other call needs. (The mock also pre-loads ready-to-use repairer and supplier credentials, so you can skip the dance while exploring.) Full flow: Authentication →.
The procurement lifecycle
Section titled “The procurement lifecycle”The ordered path from a vehicle to a settled invoice, wire method by wire method:
| Step | Wire method | Result |
|---|---|---|
| Prepare the vehicle | tier1.prepare | normalized vehicle |
| Find the repairer site | businesses.list | site id |
| List work providers | repairer.work-providers.list | provider ids |
| Open a repair job | repairer.jobs.insert | job |
| Identify parts | repairer.jobs.parts.insert | parts on the job |
| Get a basket | repairer.jobs.baskets.latest.get | { offers, suppliers } |
| Place the order extension | repairer.procurements.insert | order_requested |
| Confirm the order | supplier.procurements.confirm | order_confirmed ← terminal public state |
| Reconcile the invoice extension | repairer.procurements.invoices.list | itemized invoice |
Re-read state any time with repairer.jobs.get and repairer.procurements.get. Full walkthrough: Lifecycle →.
Signed webhooks
Section titled “Signed webhooks”State changes emit HMAC-SHA256-signed webhooks: an 8-field envelope (message_id, event type, timestamp, payload, …), a base64 signature in the partly-hmac-sha256 header, and a 5-minute replay window. Verifying the signature is the single most security-sensitive thing an integrator does — the recipe (TS + Python, paste-ready) is on the Webhooks → page.
The error model
Section titled “The error model”Each method declares its own type-tagged union of errors, and the variant object is the response body — there is no shared { code, message } envelope. The HTTP status is added for realism; the body’s type is the signal. (The Rails MCP enriches these into { code, message, retryable } for agents, but the wire model is type-tagged.) Full table: Errors →.
Machine-readable surfaces
Section titled “Machine-readable surfaces”Built for agents — prefer these over scraping HTML: