For AI agents
You are an LLM or coding agent building an integration against Rails Sandbox — a Rails-compatible API. This is a faithful mock of the public 2026-01 Integrations API, plus a small set of clearly-labelled proposed extensions. It is not a real vendor's own documentation.
This page tells you how to read these docs efficiently, where the machine-readable surfaces are, and how to tell apart the two things that look similar but are not: this docs site (for building an integration) and the companion Rails MCP server (for driving one at runtime).
Two distinct surfaces — pick the right one
| You want to… | Use | What it is |
|---|---|---|
| Build an integration — write HTTP/SDK code that calls the API | This docs site + /openapi.json |
Prose contract, copy-paste examples, the typed OpenAPI spec |
| Drive the procurement lifecycle at runtime as an agent | The companion Rails MCP server | Intent-level tools (open_repair_job, recommend_basket, …) that wrap the same wire methods |
If your task is "implement a client / SDK / webhook receiver," stay on the docs site. If your task is "run a parts-procurement workflow end to end," connect the Rails MCP and call its tools — you do not need to hand-write HTTP requests at all.
Machine-readable surfaces
Every page on this site is available as raw markdown, and the whole corpus is downloadable in two forms. Prefer these over scraping rendered HTML.
- Raw markdown for any page — append
.mdto the path, or sendAccept: text/markdown. For example, Quickstart is fetchable as/docs/quickstart.md. /llms.txt— the index: every page's title, summary, and link, in one short file. Read this first to plan which pages you need./llms-full.txt— the entire docs corpus concatenated into one file. Fetch this once if you want all the prose in a single context window instead of crawling page by page./openapi.json— the typed contract (OpenAPI 3.1). This is the source of truth for request/response/error schemas. Generate a typed client from it rather than transcribing field names by hand.
# The four machine surfaces (replace the host if you self-host the mock).
curl -s https://partifact-mock-rails.thanhvuttv.workers.dev/llms.txt
curl -s https://partifact-mock-rails.thanhvuttv.workers.dev/llms-full.txt
curl -s https://partifact-mock-rails.thanhvuttv.workers.dev/openapi.json
# Any page as raw markdown — append .md:
curl -s https://partifact-mock-rails.thanhvuttv.workers.dev/docs/quickstart.md
# …or negotiate by content type:
curl -s -H "Accept: text/markdown" https://partifact-mock-rails.thanhvuttv.workers.dev/docs/quickstart
Recommended reading order
Read in this sequence. Each page assumes you've read the ones before it.
- Quickstart — the base URL, the RPC-over-POST convention, and a first call you can make in under a minute against pre-loaded demo credentials.
- Authentication — the two required headers, the OAuth install flow (
integrations.insert), and the coded auth/install failures. Note: you can skip the OAuth dance entirely — the mock pre-loads ready-to-use repairer and supplier credentials. - Lifecycle — the ordered procurement lifecycle, wire method by wire method, and the public/extension boundary.
- Webhooks — the HMAC-signed envelope, the 5-minute replay window, and verification snippets you can paste verbatim.
- Errors — the per-method type-tagged error model and what each coded variant means.
- API Reference — the full method-by-method contract; consult per call, don't read end-to-end.
If you only have one fetch, get /llms-full.txt — it contains all of the above.
The wire convention (so the examples make sense)
- Base URL:
https://partifact-mock-rails.thanhvuttv.workers.dev - Every call:
POST <base>/api/2026-01/<dotted.method>with a JSON body. The dotted method name is the last path segment, e.g..../api/2026-01/repairer.jobs.get. - Auth headers on every call except
integrations.insert:Authorization: Bearer <api_key>Partly-Integration-ID: <integration_id>
# Read the seeded demo job. 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"}}'
Errors name the next step
When you build against this mock, error bodies are the wire contract — each method declares its own type-tagged union, 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. See Errors for the full table.
If instead you DRIVE the lifecycle through the companion Rails MCP, the MCP layer goes one step further: it enriches every error into { code, message, retryable } where message names the next action so you can self-correct from the message alone. Two rules worth internalizing:
retryable: trueis reserved for transport faults (the call never reached the server). A contract error always needs a different action — never a blind retry.- After any state-changing call, re-fetch (
get_job/track_procurement); do not assume the new state.
The companion Rails MCP (runtime)
A separate Rails MCP server exposes the same procurement lifecycle as intent-level tools and resources, for an agent to drive at runtime. It wraps the wire methods documented here, so the contract is identical — you just call named tools instead of constructing HTTP requests.
It currently exposes 13 tools and 8 resources.
Tools (13): get_started, get_run_metrics, prepare_vehicle, find_repairer_site, list_work_providers, open_repair_job, get_job, identify_parts, recommend_basket, track_procurement, confirm_procurement, place_procurement ⚠, reconcile_invoice ⚠.
Resources (8): guide://lifecycle, scenario://current, reference://suppliers, reference://ghca-categories, reference://work-providers, job://current, job://{job_id} (template), events://recent (the webhook outbox).
Notes:
- Call
get_startedfirst — it returns the full tool order for the lifecycle. confirm_procurementis the only supplier-scope tool; everything else is repairer-scope.- The ⚠ tools (
place_procurement,reconcile_invoice) are proposed extensions (see below); they announce themselves at runtime viais_extension: true.
The distinction is the whole point: the docs site is for writing an integration; the MCP is for an agent to operate one. A coding agent implementing a an API client reads these pages and /openapi.json. An agent running a repair-shop procurement workflow connects the MCP and calls its tools.
Install & connect the MCP (deployed — no local build)
Both MCP servers are live on Cloudflare Workers, so you can connect and test without cloning or building anything. Both speak Streamable HTTP. The Rails MCP is gated by a shared access token (it drives stateful, per-tenant sandboxes); the Docs MCP is public and read-only — no token. For the Rails MCP a connector UI (such as claude.ai) takes a URL, so the token rides in the path (or send it as an Authorization: Bearer <token> header).
1. The Rails MCP — operate the lifecycle
The runtime server described above (13 tools + 8 resources). Connect it at:
https://partifact-rails-mcp.thanhvuttv.workers.dev/mcp/<MCP_ACCESS_TOKEN>/<your-slot>
<MCP_ACCESS_TOKEN>— the shared token provided with your invite. It only gates the endpoint against random traffic.<your-slot>— any name you choose ([a-z0-9_-]). It selects your own private sandbox, seeded fresh with the same Corolla job (external referenceCCC-2026-04817). Two people on two slots never touch each other's data; to start over, just change the name. Idle slots self-reset after ~1 hour.
In claude.ai → Settings → Connectors → Add custom connector, paste the URL and save. Then, in a fresh chat with the connector enabled, ask the agent to drive the job — e.g. "Using only the Rails MCP tools, take the 2019 Toyota Corolla job (CCC-2026-04817) through to a reconciled invoice, and tell me what you did at each step." The agent orients itself from get_started / guide://lifecycle / scenario://current alone.
2. The Docs MCP — read these docs as tools
A separate, read-only server that exposes this documentation as tools (list_docs, get_doc, search_docs) — for an agent that would rather query the docs than crawl the rendered site. It is public (no token) and stateless:
https://partifact-docs-mcp.thanhvuttv.workers.dev/mcp
No token, no slot — its corpus is already public (the same markdown this site serves), so there is nothing to gate. For example, search_docs("verify webhook signature") returns the Webhooks page.
Liveness check (no token needed)
curl https://partifact-rails-mcp.thanhvuttv.workers.dev/ # the runtime MCP — expect a 200 liveness line
curl https://partifact-docs-mcp.thanhvuttv.workers.dev/ # the docs MCP — expect a 200 liveness line
A local, zero-config install over stdio (Claude Desktop / Claude Code / Cursor) is also available for development — it runs the mock in-process, with no token and no slot. The deployed URLs above are the canonical way to test with no local build.
Fidelity boundary — read before you trust a field
This sandbox is faithful to the public 2026-01 contract, with two explicit additions. Hold the line on the following.
The public lifecycle terminates at order_confirmed. supplier.procurements.confirm transitions a procurement order_requested → order_confirmed, which is the terminal public state of the 2026-01 contract.
Two proposed extensions go beyond it. place_procurement (repairer.procurements.insert) and reconcile_invoice (repairer.procurements.invoices.list) are clearly-labelled proposed extensions, NOT part of the public 2026-01 API. Wherever they appear they carry this banner verbatim:
(Proposed extension beyond the public 2026-01 API — the public contract stops at
order_confirmed; this completes the buyer loop.)
Their HTTP responses carry x_extension: true; the MCP equivalents carry is_extension: true. Treat these as a proposal, not the shipped contract.
The basket carries no currency. The basket response (repairer.jobs.baskets.latest.get, returning { offers, suppliers }) has no currency field — not on the envelope, not on an offer. Currency is a procurement-level concept (D52): it first appears later in the lifecycle as currency_code on the procurement. The MCP's projected basket derives an NZD label purely as a presentation-layer convenience; the wire basket itself asserts no currency. If you read a currency off a basket offer, you are inventing it — go to the procurement instead.
Where to go next
- Quickstart — make your first authenticated call.
- API Reference — the full method-by-method contract.
/openapi.json— generate a typed client instead of transcribing schemas.