Versioning & changelog
Rails Sandbox is a faithful mock of the public Integrations API plus a small set of clearly-labelled proposed extensions. This page covers how the API is versioned and what has changed.
The version is 2026-01, a date-stamped string carried in the URL path. Every call goes to:
POST https://partifact-mock-rails.thanhvuttv.workers.dev/api/2026-01/<dotted.method>
The version segment is part of the route, not a header or query parameter. The path prefix is exactly /api/2026-01/, and the dotted method name is the final path segment — for example .../api/2026-01/repairer.jobs.get. See the API Reference for the full method inventory.
Why date-versioning
A date-stamped version string (YYYY-MM) names a frozen snapshot of the contract. Code written against 2026-01 keeps working as long as it keeps sending requests to /api/2026-01/..., because that path will always answer with the 2026-01 request and response shapes. You opt into a newer contract deliberately, by changing the version segment in your URLs — never implicitly, because a behaviour changed underneath you.
This mirrors the API's own date-versioning convention; this sandbox reproduces the contract shape, not real production infrastructure.
How a breaking change rolls a new version
Within a single dated version the contract is additive-only. A change is non-breaking — and ships inside 2026-01 — when it cannot break a correct existing client. Examples:
- Adding a new method under
/api/2026-01/. - Adding an optional request field that defaults to today's behaviour when omitted.
- Adding a new field to a response (well-behaved clients ignore unknown fields).
A change is breaking — and would require a new dated version, e.g. a hypothetical 2026-07, served under /api/2026-07/... — when it could break a correct existing client. Examples:
- Removing or renaming a method, request field, or response field.
- Tightening validation so a previously-accepted request is now rejected.
- Changing the type, units, or meaning of an existing field.
- Adding a new enum value a client must handle (e.g. a new procurement status).
When that happens, 2026-01 continues to be served unchanged for existing integrations, and the new shapes live only under the new dated prefix. Clients migrate by changing the version segment in their URLs and adapting to the documented deltas — there is no silent cutover.
Simplification: this sandbox currently serves a single version,
2026-01. There is no2026-07prefix deployed. The policy above describes how a breaking change would be rolled; it is documented here so the versioning contract is legible, not because a second version exists today.
Proposed extensions are not part of 2026-01
Two methods — and their MCP tools place_procurement and reconcile_invoice — are proposed extensions beyond the public 2026-01 contract, not part of it. The public 2026-01 procurement lifecycle terminates at order_confirmed; these extensions complete the buyer loop past that terminal state (place a procurement, then reconcile its invoices).
Because they are not part of the dated contract, they are labelled everywhere they appear:
- The MCP tool descriptions open with the verbatim banner below.
- Their HTTP responses carry
x_extension: true; the MCP results carryis_extension: true. - They are documented in their own sections, never mixed in with the
2026-01surface.
(Proposed extension beyond the public 2026-01 API — the public contract stops at
order_confirmed; this completes the buyer loop.)
These extensions are versioned with the rest of the sandbox but are explicitly excluded from the 2026-01 contract guarantees. Treat them as a design proposal, not a shipped API. See the API Reference for their request/response shapes and the extension markers.
Changelog
Dates are the change dates; entries name the affected surface and the design decision (Dxx / R-Axx) they implement.
2026-06-04 — Stage 1
Presentation-layer currency on the basket projection (D52). The MCP
recommend_baskettool now derives and labels a currency (NZD) on its projected basket, as a presentation-layer convenience. This is not a change to the wire contract: the underlyingrepairer.jobs.baskets.latest.getresponse — and theOfferV1objects inside it — still carry nocurrencyfield. Currency is a procurement-level concept; it appears on the procurement (currency_code) and on invoices, never on the basket. The raw API docs continue to state the wire truth plainly. (commit7fc5137)place_procurementfails fast for a non-confirmable supplier (D53).place_procurement(a proposed extension) now validates the chosen supplier before hitting the wire. The demo holds a single supplier credential — "Christchurch Toyota — Parts" — so a procurement placed from any other supplier's offers could never reachorder_confirmed. Rather than leave such an order stranded inorder_requested, the tool now refuses it up front with anunprocessableerror that names the only confirmable supplier and points back torecommend_basket. (commitea1b603)get_run_metricsper-session telemetry (R-A5). Added aget_run_metricsMCP tool exposing per-session run counters, so an agent (or a human watching one) can read back what the current session has done. (commitbdaff71)
Stage 1 close-out was recorded in commit 22b0300.
For the methods affected by these changes and their exact request/response shapes, see the API Reference. Machine-readable surfaces: /openapi.json (the 2026-01 contract), /llms.txt, and /llms-full.txt.