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.

# 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.

  1. 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.
  2. 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.
  3. Lifecycle — the ordered procurement lifecycle, wire method by wire method, and the public/extension boundary.
  4. Webhooks — the HMAC-signed envelope, the 5-minute replay window, and verification snippets you can paste verbatim.
  5. Errors — the per-method type-tagged error model and what each coded variant means.
  6. 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)

# 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:

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:

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>

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