API Reference
Generated from the published OpenAPI spec — the 14 wire methods of the public 2026-01 Integrations API. This page is a per-method overview; /openapi.json is the full machine-readable contract (every schema resolved), and the better source for generating a typed client.
Every call is POST <base>/api/2026-01/<dotted.method> with a JSON body. See Authentication for the two required headers and Errors for the coded error model. Examples use the pre-loaded demo credentials; set the base URL once, and prepend -H 'x-partifact-tenant: <name>' for a private, isolated sandbox (see Quickstart).
BASE=https://partifact-mock-rails.thanhvuttv.workers.dev
Wire-truth (D52). The basket response (
repairer.jobs.baskets.latest.get→BasketsLatestGetResponseV1,OfferV1) carries nocurrencyfield. Currency is a procurement-level concept —currency_codeon the procurement and the invoice, never on a basket offer.
Bare-string errors (D24). Most methods return type-tagged error bodies (
{"type":"not_found"}). The one exception isrepairer.jobs.parts.insert, whose error variants are bare JSON strings ("not_found"). See Errors.
Wire methods (2026-01)
businesses.list
Lists the sub-businesses of the organization that the integration belongs to.
| Request | BusinessesListRequestV1 — required: none |
| Response | BusinessesListResponseV1 — items: BusinessV1[] |
| Errors | unauthorized, forbidden |
curl -sS -X POST "$BASE/api/2026-01/businesses.list" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{}'
integrations.insert
Completes the integration installation and API key generation for a given install. The request must provide the client secret, client ID and the access code generated during the OAuth authorization process
| Request | IntegrationsInstallRequestV1 — required: access_code, client_id, client_secret |
| Response | IntegrationsInstallResponseV1 — api_key: std.string.String, integration_id: uuid.Uuid |
| Errors | unauthorized, forbidden, integration_not_found, o_auth_not_supported_by_integration, invalid_client_secret, invalid_access_code |
curl -sS -X POST "$BASE/api/2026-01/integrations.insert" \
-H "Content-Type: application/json" \
-d '{"access_code":"ac_demo_valid_15m","client_id":"partly_client_demo","client_secret":"secret_demo_8f3a"}'
repairer.jobs.baskets.latest.get
Fetches the latest basket for a given repair job.
| Request | BasketsLatestGetRequestV1 — required: job_identity |
| Response | BasketsLatestGetResponseV1 — offers: OfferV1[], suppliers: SupplierV1[] |
| Errors | unauthorized, forbidden, not_found, bad_request |
curl -sS -X POST "$BASE/api/2026-01/repairer.jobs.baskets.latest.get" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"job_identity":{"external":"CCC-2026-04817"}}'
repairer.jobs.get
Fetches a repair job by ID, external ID, or siteID and job number
| Request | _(inline)_ — required: identity |
| Response | JobV1 — claim_number?: oneOf, external_id?: oneOf, id: uuid.Uuid, images: ImageV1[], job_number?: oneOf, repairer_site_id: uuid.Uuid, vehicle?: oneOf, work_provider_id?: oneOf |
| Errors | unauthorized, forbidden, not_found |
curl -sS -X POST "$BASE/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"}}'
repairer.jobs.insert
Inserts a new repair job or updates an existing repair job.
| Request | JobsInsertRequestV1 — required: repairer_site_id, identity |
| Response | JobV1 — claim_number?: oneOf, external_id?: oneOf, id: uuid.Uuid, images: ImageV1[], job_number?: oneOf, repairer_site_id: uuid.Uuid, vehicle?: oneOf, work_provider_id?: oneOf |
| Errors | unauthorized, forbidden, unprocessable, work_provider_not_found |
curl -sS -X POST "$BASE/api/2026-01/repairer.jobs.insert" \
-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"},"repairer_site_id":"0b000000-0000-4000-8000-000000000001","work_provider_id":"0a000000-0000-4000-8000-000000000020"}'
repairer.jobs.parts.insert
Inserts parts for a repair job.
| Request | JobsPartsInsertRequestV1 — required: job_identity, parts |
| Response | JobsPartsListResponseV1 — items: PartV1[] |
| Errors | unauthorized, forbidden, not_found, unprocessable — bare JSON strings, not {type} objects (D24) |
curl -sS -X POST "$BASE/api/2026-01/repairer.jobs.parts.insert" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"job_identity":{"external":"CCC-2026-04817"},"parts":[{"description":"Front bumper cover assembly","quantity":1}]}'
repairer.jobs.parts.list
Lists all parts for a repair job.
| Request | JobsPartsListRequestV1 — required: job_identity |
| Response | JobsPartsListResponseV1 — items: PartV1[] |
| Errors | unauthorized, forbidden, not_found |
curl -sS -X POST "$BASE/api/2026-01/repairer.jobs.parts.list" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"job_identity":{"external":"CCC-2026-04817"}}'
repairer.procurements.get
Fetch a procurement for a repairer by ID
| Request | _(inline)_ — required: identity |
| Response | procurements.v1.buyer.Procurement — created_at: string, currency_code: oneOf, id: uuid.Uuid, job_id: uuid.Uuid, reference: oneOf, source_items: procurements.v1.buyer.SourceItem[], supplier_business: procurements.v1.buyer.SupplierBusiness, supplier_organization: procurements.v1.buyer.SupplierOrganization, total_shipping_price: oneOf, updated_at: string, vehicle: procurements.v1.Vehicle |
| Errors | unauthorized, forbidden, not_found |
curl -sS -X POST "$BASE/api/2026-01/repairer.procurements.get" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"identity":{"id":"10000000-0000-4000-8000-000000000001"}}'
repairer.procurements.list
List procurements for a repairer
| Request | procurements.v1.repairer.ProcurementsListRequest — required: job_identity |
| Response | procurements.v1.buyer.ProcurementsListResponse — items: procurements.v1.buyer.Procurement[] |
| Errors | unauthorized, forbidden, not_found |
curl -sS -X POST "$BASE/api/2026-01/repairer.procurements.list" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"job_identity":{"external":"CCC-2026-04817"}}'
repairer.work-providers.list
Fetches the list of work providers for a repairer.
| Request | WorkProvidersListRequestV1 — required: none |
| Response | WorkProvidersListResponseV1 — items: WorkProviderV1[] |
| Errors | unauthorized, forbidden |
curl -sS -X POST "$BASE/api/2026-01/repairer.work-providers.list" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{}'
supplier.procurements.confirm
Transition a procurement to order confirmed
| Request | _(inline)_ — required: identity |
| Response | procurements.v1.supplier.Procurement — buyer_business: procurements.v1.supplier.BuyerBusiness, buyer_organization: procurements.v1.supplier.BuyerOrganization, buyer_shipping_address: procurements.v1.Address, created_at: string, currency_code: oneOf, id: uuid.Uuid, job_id: uuid.Uuid, reference: oneOf, source_items: procurements.v1.supplier.SourceItem[], total_shipping_price: oneOf, updated_at: string, vehicle: procurements.v1.Vehicle |
| Errors | unauthorized, forbidden, not_found |
curl -sS -X POST "$BASE/api/2026-01/supplier.procurements.confirm" \
-H "Authorization: Bearer partly_demo_supplier_8b4e2f1a6c0d3e9f7a25" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000002" \
-H "Content-Type: application/json" \
-d '{"identity":{"id":"10000000-0000-4000-8000-000000000001"}}'
supplier.procurements.get
Fetch a procurement for a supplier by ID
| Request | _(inline)_ — required: identity |
| Response | procurements.v1.supplier.Procurement — buyer_business: procurements.v1.supplier.BuyerBusiness, buyer_organization: procurements.v1.supplier.BuyerOrganization, buyer_shipping_address: procurements.v1.Address, created_at: string, currency_code: oneOf, id: uuid.Uuid, job_id: uuid.Uuid, reference: oneOf, source_items: procurements.v1.supplier.SourceItem[], total_shipping_price: oneOf, updated_at: string, vehicle: procurements.v1.Vehicle |
| Errors | unauthorized, forbidden, not_found |
curl -sS -X POST "$BASE/api/2026-01/supplier.procurements.get" \
-H "Authorization: Bearer partly_demo_supplier_8b4e2f1a6c0d3e9f7a25" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000002" \
-H "Content-Type: application/json" \
-d '{"identity":{"id":"10000000-0000-4000-8000-000000000001"}}'
tier1.prepare
Queue up a given vehicle VIN for future use in other services.
| Request | Tier1PrepareRequestV1 — required: identifiers |
| Response | Tier1PrepareResponseV1 — invalid_identifiers: InvalidIdentifierV1[] |
| Errors | unauthorized |
curl -sS -X POST "$BASE/api/2026-01/tier1.prepare" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"identifiers":[{"vin":"JTDBR32E730012345"}]}'
uploads.prepare
Generate a pre-signed URL for uploading a file.
| Request | UploadsPrepareRequestV1 — required: file_name, media_type, type |
| Response | UploadsPrepareResponseV1 — public_url: oneOf, upload_url: std.string.String |
| Errors | unauthorized, forbidden, unprocessable |
curl -sS -X POST "$BASE/api/2026-01/uploads.prepare" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"file_name":"estimate.jpg","media_type":"image","type":"job_media"}'
Proposed extensions (NOT in 2026-01)
These three methods are not part of the public 2026-01 contract and are not in /openapi.json. the upstream platform performs procurement-placement and invoice-reconciliation internally but exposes no public method; here they are reconstructed as a clearly-labelled proposed extension so the buyer loop is demonstrable end to end. Every extension response carries x_extension: true. See Lifecycle.
repairer.procurements.insert (MCP tool: place_procurement ⚠)
(Proposed extension beyond the public 2026-01 API — the public contract stops at
order_confirmed; this completes the buyer loop.)
Creates a procurement in order_requested from selected basket offers and moves the chosen parts estimated → ordered. Its response carries "x_extension": true.
| Request | job_identity + offer_selections[] (each { sellable_id, supplier_business_id, job_part_ids, quantity }) |
| Response | RepairerProcurementsInsertResponseV1 (local schema; x_extension: true) |
curl -sS -X POST "$BASE/api/2026-01/repairer.procurements.insert" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"job_identity":{"external":"CCC-2026-04817"},"offer_selections":[{"sellable_id":"0f000000-0000-4000-8000-000000000007","supplier_business_id":"0b000000-0000-4000-8000-000000000010","job_part_ids":["0e000000-0000-4000-8000-000000000004"],"quantity":1}]}'
repairer.procurements.invoices.list (MCP tool: reconcile_invoice ⚠)
(Proposed extension beyond the public 2026-01 API — the public contract stops at
order_confirmed; this completes the buyer loop.)
Lists the reconciled invoices and credit notes for a procurement (or job). Invoices appear only after order_confirmed. Its response carries "x_extension": true.
| Request | exactly one selector — procurement_identity XOR job_identity |
| Response | RepairerProcurementsInvoicesListResponseV1 (local schema; x_extension: true) |
curl -sS -X POST "$BASE/api/2026-01/repairer.procurements.invoices.list" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"procurement_identity":{"id":"10000000-0000-4000-8000-000000000001"}}'
repairer.procurements.invoices.get
(Proposed extension beyond the public 2026-01 API — the public contract stops at
order_confirmed; this completes the buyer loop.)
Fetches a single invoice or credit note by its own id (obtain the id from repairer.procurements.invoices.list). Its response carries "x_extension": true.
| Request | identity — { id: <invoice_id> } |
| Response | RepairerProcurementsInvoicesGetResponseV1 (local schema; x_extension: true) |
curl -sS -X POST "$BASE/api/2026-01/repairer.procurements.invoices.get" \
-H "Authorization: Bearer partly_demo_repairer_3f8a1c0d9e2b4a67b1c2" \
-H "Partly-Integration-ID: 0c000000-0000-4000-8000-000000000001" \
-H "Content-Type: application/json" \
-d '{"identity":{"id":"<invoice_id from invoices.list>"}}'