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

Deal hand-off

initiate_deal_handoff · scope deal:handoff · the one tool that accepts customer PII. It converts an active reservation into an emailed deal-intent package for a live sales manager. PII is hashed in every audit/DB surface; plaintext flows only to the dealer's inbox. Requires explicit customer_consent: true.

🔒 What "hashed" means here Fields marked 🔒 hashed are SHA-256'd before they touch the audit log or the deal_handoffs table. The only place their plaintext lands is the outbound email to the dealer desk (and the DriveCentric CRM lead, when enabled). Structured trade-in fields and consent channels/expiry are plaintext — they're not PII.

Build a request

Toggle optional fields on and the request builds live below. Validation mirrors the server's Pydantic models, so a green banner means the call would be accepted as shaped.

Required
reservation_token required
10–80 chars · an active hold from create_reservation
customer_contact.name required🔒 hashed
1–120 chars
customer_contact.phone required🔒 hashed
E.164 · 8–20 chars · ^+[1-9][0-9]{6,14}$
customer_contact.email required🔒 hashed
5–320 chars · RFC-5322-ish
customer_consent required
fixed true — the validator rejects false (PII transfer requires explicit consent)
Optional — toggle to include
✓ request valid

      

$DMC12_TOKEN in the curl tab is a literal placeholder — swap in the bearer token you mint per Partner onboarding. The endpoint origin is injected from the shared MCP_BASE.

Full field reference

FieldTypeConstraint · PII
reservation_tokenstringreq10–80 chars
customer_contact.namestringreq1–120 · 🔒
customer_contact.phonestringreqE.164, 8–20 · 🔒
customer_contact.emailstringreq5–320 · 🔒
customer_consentboolreqconst true
financing_preferenceenumoptcash|finance|lease|unknown (def unknown)
notesstringopt≤500 · 🔒
trade_in_disclosedbooloptauto-true if any trade_in field set
trade_inobjectoptextra fields forbidden
trade_in.descriptionstringopt≤500 · 🔒
trade_in.appraised_value_partnerMoneyopt{amount≥0, currency ^[A-Z]{3}$} · 💲
trade_in.vinstringopt^[A-HJ-NPR-Z0-9]{17}$
trade_in.yearintopt1900–2100
trade_in.makestringopt≤40
trade_in.modelstringopt≤80
trade_in.mileageintopt0–1,000,000
trade_in.conditionenumoptexcellent|good|fair|poor
consentobjectoptextra fields forbidden
consent.allowed_channelsenum[]opt≥1 unique of email|phone|sms · advisory
consent.expires_atdatetimeopttz-aware · enforced (CONSENT_INVALID if past)
consent.consent_textstringopt≤2000 · 🔒

Worked examples

Minimal — bare boolean consent

{
  "reservation_token": "rsv_Qh7m…",
  "customer_contact": { "name": "Jane Doe", "phone": "+15555551234", "email": "jane@example.com" },
  "financing_preference": "unknown",
  "trade_in_disclosed": false,
  "customer_consent": true
}

+ trade_in

{
  "reservation_token": "rsv_Qh7m…",
  "customer_contact": { "name": "Jane Doe", "phone": "+15555551234", "email": "jane@example.com" },
  "customer_consent": true,
  "financing_preference": "finance",
  "trade_in_disclosed": true,
  "trade_in": {
    "description": "Single owner, clean Carfax",
    "appraised_value_partner": { "amount": 18500, "currency": "USD" },
    "vin": "JF2GTACC4K8200000", "year": 2019, "make": "Subaru",
    "model": "Crosstrek", "mileage": 48000, "condition": "good"
  }
}

+ consent (channel-scoped)

{
  "reservation_token": "rsv_Qh7m…",
  "customer_contact": { "name": "Jane Doe", "phone": "+15555551234", "email": "jane@example.com" },
  "financing_preference": "unknown",
  "trade_in_disclosed": false,
  "customer_consent": true,
  "consent": {
    "allowed_channels": ["email", "phone"],
    "expires_at": "2026-06-01T00:00:00Z",
    "consent_text": "Customer authorized follow-up by email and phone on 2026-05-27."
  }
}

Full — everything populated

Use the builder above and toggle every optional field on; the params tab renders the full request.

What the dealer receives

On success the tool emails a deal-intent package to the dealer desk and returns a masked receipt — no plaintext customer data in the response:

{ "data": {
    "handoff_token": "hnd_xyz…",
    "sent_to_masked": "be****@markmillersubaru.com, ch****@markmillersubaru.com",
    "sent_at": "2026-05-27T18:22:01+00:00",
    "status": "sent",
    "crm_status": "sent",        // "sent" | "failed" | "disabled"
    "crm_lead_id": "hnd_xyz…",
    "next_steps": "A sales manager will contact ja****@example.com within 1 business day…"
  },
  "_metadata": { "trace_id": "trc_…", "tool": "initiate_deal_handoff", "protocol": "a2a" }
}

Response fields

The masked receipt. No plaintext customer data is ever returned. See Data formats for timestamp / enum conventions.

FieldTypeDescription
handoff_tokenstringalwaysOpaque receipt handle for the recorded hand-off. Do not parse.
sent_to_maskedstringalwaysComma-separated, masked dealer-desk recipients (e.g. be****@…) — confirms where the package went without exposing addresses.
sent_atstringalwaysISO-8601 UTC — when the dealer-ops email sent (the moment the hand-off became real).
statusenumalwayssent on success. The email is the contract — a send failure returns an error, not a status.
crm_statusenumalwayssent | failed | disabled. Best-effort DriveCentric (ADF 1.0) lead outcome; disabled means the CRM sink is off. A failed CRM does not fail the call.
crm_lead_idstring | nulloptionalCRM lead identifier when a lead was created; null/absent when crm_status is failed or disabled.
next_stepsstringalwaysHuman-readable follow-up summary, with the customer email masked.
Ownership & expiry The reservation must be active and owned by your agent. Common errors: RESERVATION_NOT_FOUND, RESERVATION_STATE, RESERVATION_EXPIRED, NOT_AUTHORIZED (token owned by another agent), CONSENT_INVALID (supplied consent.expires_at in the past). Full list on the error taxonomy page.
copied