DMC-12 Mark Miller Subaru / dmc-12 guide
endpoint live · DMC-12 v0.6 · 11 tools

Reservations

Three tools, one scope: reservation:write. A reservation is a 30-minute soft hold on a VIN, created from an open quote. It is not a binding purchase — a human closes the deal after hand-off.

Rules of the hold
  • One active hold per VIN. A second create on a VIN that already has an unexpired active hold fails with RESERVATION_CONFLICT.
  • 30-minute TTL. expires_at is set at insert (now + 30 min). There is no background sweeper — stale active holds are lazy-expired the next time anyone reserves that VIN.
  • Per-agent daily budget. Default 5 reservations/day (raise on request). Creating charges the budget; the create is the only tool that consumes it.
  • Same-day-release refund. Releasing within the same UTC day you created the hold refunds 1 slot to your daily budget.

create_reservation

Convert an open quote into a soft hold. Validates that the quote exists, is open and unexpired, is owned by you, and that the vehicle is still available. On success the quote flips to converted.

FieldTypeConstraints
quote_idstringrequired10–64 chars — from request_quote
customer_refstringoptional≤ 200 chars — opaque; your own handle, not PII
// arguments
{ "quote_id": "qte_8f1c…", "customer_ref": "caredge-sess-91f3" }

// data
{ "reservation_token": "rsv_Qh7m…",
  "vin": "4S4BTGUD8R3201234",
  "reserved_price": 34187.0,
  "created_at": "2026-05-27T18:05:02+00:00",
  "expires_at": "2026-05-27T18:35:02+00:00",
  "status": "active",
  "terms": "30-minute soft hold. Not a binding purchase. A human closes the deal. …" }

Errors: QUOTE_NOT_FOUND, QUOTE_EXPIRED, QUOTE_STATE (already converted/closed), VEHICLE_UNAVAILABLE, RESERVATION_CONFLICT (VIN already held), RESERVATION_LIMIT (daily budget hit), NOT_AUTHORIZED (quote owned by another agent).

release_reservation

Release a hold you own. Idempotent — calling it on an already-released or expired reservation returns status with already_closed: true instead of an error, so it is always safe to call twice. Releasing within the same UTC day refunds 1 slot to your daily budget.

FieldTypeConstraints
reservation_tokenstringrequired10–80 chars
// arguments
{ "reservation_token": "rsv_Qh7m…" }

// data (first release)
{ "status": "released", "released_at": "2026-05-27T18:12:40+00:00", "vin": "4S4BTGUD8R3201234" }

// data (second, idempotent release)
{ "status": "released", "already_closed": true }

get_reservation_status

Look up the current state of a reservation you created. Same input shape as release.

FieldTypeConstraints
reservation_tokenstringrequired10–80 chars
// data
{ "reservation_token": "rsv_Qh7m…",
  "vin": "4S4BTGUD8R3201234",
  "reserved_price": 34187.0,
  "created_at": "2026-05-27T18:05:02+00:00",
  "expires_at": "2026-05-27T18:35:02+00:00",
  "released_at": null,
  "released_by": null,
  "status": "active" }

Status values: active, released, expired, converted. released_by is agent for an agent-initiated release. Errors: RESERVATION_NOT_FOUND, NOT_AUTHORIZED (owned by another agent).

Response fields

Shared across create_reservation, release_reservation, and get_reservation_status. See Data formats for the timestamp / Money / opaque-token conventions.

FieldTypeDescription
reservation_tokenstringcreate / statusOpaque hold handle (10–80 chars). Use it for release_reservation, get_reservation_status, and initiate_deal_handoff. Do not parse.
vinstringalwaysThe held VIN.
reserved_pricenumbercreate / statusPrice locked at hold creation — the quote's quoted_price. Non-binding.
statusenumalwaysactive | released | expired | converted.
created_atstringcreate / statusISO-8601 UTC — when the hold was created.
expires_atstringcreate / statusISO-8601 UTC — created_at + 30 min. After this the hold lazy-expires.
released_atstring | nullstatus / releaseISO-8601 UTC when released; null while the hold is still active.
released_bystring | nullstatusagent for an agent-initiated release; null while active or if it expired untouched.
already_closedbooleanreleasetrue on an idempotent re-release of an already released/expired hold (no error). Absent on the first release.
termsstringcreateHuman-readable hold terms.

Next step

While a reservation is active you have a 30-minute window to either release it or run initiate_deal_handoff to bring a human into the loop. Let the window lapse and the hold expires automatically.

copied