Browse the guides
Developers/Integrating
External References
Attach your own ids to Shop Commander records and look records up by them — private to your integration.
Most integrations already have an id for a customer, vehicle, repair order, or task on their side. Rather than keeping a mapping table, attach it to the record:
curl -X PUT https://api.shopcommander.com/v1/vehicles/veh_…/external-id \
-H "Authorization: Bearer $SC_API_KEY" -H "Content-Type: application/json" \
-d '{"external_id":"FLEET-UNIT-0417"}'
Then:
- the resource's nullable
external_idfield carries the value on every response, and - the matching list filter finds it exactly. Customers, vehicles, repair
orders, and tasks all support
?external_id=.
Writing requires the external_refs.write scope plus the resource's read
scope. PUT …/external-id is available on customers, vehicles, repair orders,
and tasks; DELETE …/external-id removes the reference. Reading or filtering
uses the normal resource read scope.
Rules
- One external id per record per integration, and one record per external id: assigning an id already used by another record of the same type returns
409 conflict / external_id_in_use. - References are private to the integration that set them. Another integration sees
external_id: nulland can set its own. - Filters are exact, not substring matches, and never search another integration's namespace.
- Ids are strings of 1–255 characters.
DELETE /v1/{resource}/{id}/external-idremoves one;PUTwith a new value replaces it.
Pattern: upsert by external id
GET /v1/repair-orders?external_id=DMS-RO-88213
→ found: PATCH it (with expected_version)
→ empty: POST /v1/repair-orders (Idempotency-Key: DMS-RO-88213), then PUT …/external-id
The idempotency key makes the create safe to retry, and the reference makes every later sync a lookup rather than a search.