Repair Estimator (Beta)

Repair Estimator API (Beta)

Public, unauthenticated endpoints for the embeddable AI Repair Estimate Assistant — scoped by shop slug and session token, gated by CORS and the repair_estimator entitlement.

Public HTTP endpoints that power the AI Repair Estimate Assistant — a chat intake a shop embeds on its own site so a vehicle owner can turn a vague damage description into an estimator-ready repair intake.

Beta. This surface is gated by the repair_estimator entitlement and is intended for first-party / embedded use on a shop's own website. Unlike the rest of the SocialCRM API, these endpoints are public and unauthenticated — there is no API key. Access is scoped per shop by a slug, per visitor by an opaque session token, and per browser origin by the shop's configured allowed_origins. Endpoints, request shapes, and limits may change while in beta.

How it differs from the rest of the API

MCP / REST platform Repair Estimator
Auth Authorization: Bearer sk_live_… API key None — public
Tenant scoping API key → company slug (shop) + token (session)
Cross-origin Server-to-server Browser embed, gated by allowed_origins (CORS)
Base path /api/mcp-app /api/public/repair-estimator

Base URL: https://socialcrm.com/api/public/repair-estimator

CORS & origins

These endpoints are called from a browser on the shop's website. Send an Origin header; it must match the shop's configured allowed_origins (or a first-party SocialCRM origin). When the origin is allowed, the response echoes it in Access-Control-Allow-Origin. Each route also answers a OPTIONS preflight. A disallowed cross-origin request is rejected as 404. Non-browser requests (no Origin) are not blocked by CORS and are still subject to per-IP rate limits and per-tenant caps.

Typical flow

  1. GET /config/{slug} — load branding for the widget.
  2. POST /sessions — start a session, receive a token.
  3. POST /sessions/{token}/messages — one call per chat turn.
  4. POST /sessions/{token}/contact — capture the lead once the owner consents.
  5. GET /sessions/{token} — rehydrate an in-progress session (e.g. page reload).

GET /config/{slug}

Public, cacheable branding for a live estimator. Returns 404 if the slug is unknown or the estimator is not published.

Rate limit: 60 requests / minute / IP. Response is cacheable (Cache-Control: public, max-age=60).

curl https://socialcrm.com/api/public/repair-estimator/config/joes-auto-body
{
  "data": {
    "slug": "joes-auto-body",
    "displayName": "Joe's Auto Body",
    "welcomeMessage": "Tell me what happened and I'll help you get a head start on an estimate.",
    "disclaimerText": "This is a preliminary intake, not a quote. Final pricing requires an in-person inspection.",
    "theme": { "accent": "#047857" },
    "locale": "en-US",
    "units": "imperial"
  }
}

POST /sessions

Start an intake session. The slug identifies the shop; source is optional caller-supplied context (UTM, page URL, etc.).

Gated by the shop's repair_estimator entitlement and monthly intake cap. Rate limit: 5 requests / hour / IP.

curl -X POST https://socialcrm.com/api/public/repair-estimator/sessions \
  -H "Content-Type: application/json" \
  -H "Origin: https://joesautobody.com" \
  -d '{ "slug": "joes-auto-body", "source": { "page": "/estimate" } }'
{
  "data": {
    "token": "rin_8sQ2…",
    "expiresAt": "2026-08-01T16:00:00.000Z"
  }
}

The token is the credential for every subsequent call on this session. Treat it as a bearer secret for that visitor.

GET /sessions/{token}

Rehydrate a session — its status, captured vehicle data, safety flag, the shop's display config, and recent messages. Returns 404 once the session has expired.

Rate limit: 30 requests / minute / IP.

curl https://socialcrm.com/api/public/repair-estimator/sessions/rin_8sQ2…
{
  "data": {
    "session": { "status": "active", "vehicle": {}, "safetyFlag": false, "expiresAt": "2026-08-01T16:00:00.000Z" },
    "config": { "slug": "joes-auto-body", "displayName": "Joe's Auto Body", "welcomeMessage": "…", "disclaimerText": "…", "theme": {} },
    "messages": [
      { "id": "…", "role": "assistant", "content": "What year, make, and model is the vehicle?", "metadata": {}, "createdAt": "…" }
    ]
  }
}

POST /sessions/{token}/messages

Send one chat turn. Returns the assistant's structured turn envelope plus updated session counters.

Rate limit: 10 requests / minute / IP. Per-session cap: 80 messages. Also subject to the shop's monthly turn budget.

curl -X POST https://socialcrm.com/api/public/repair-estimator/sessions/rin_8sQ2…/messages \
  -H "Content-Type: application/json" \
  -H "Origin: https://joesautobody.com" \
  -d '{ "message": "2019 Honda Civic, someone rear-ended me and the bumper is cracked." }'
{
  "data": {
    "turn": {
      "reply": "Got it — a 2019 Civic with rear impact. Is the vehicle drivable, and did any warning lights come on?",
      "phase": "damage",
      "intake_draft": { "…": "partial RepairIntake v1" },
      "intake_complete": false,
      "safety_concern": null,
      "followups": ["drivability", "warning lights"]
    },
    "session": { "status": "active", "messageCount": 4, "safetyFlag": false }
  }
}

The assistant never returns prices, part numbers, labor hours, or insurance determinations; those are stripped by an output policy before the reply is returned or stored.

POST /sessions/{token}/contact

Capture the lead once the owner consents to send their intake to the shop. Creates or updates a CRM contact, marks the session submitted, and notifies configured staff.

consent must be true. honeypot must be empty (a filled honeypot returns a silent success and is discarded). Rate limit: 3 requests / hour / IP.

curl -X POST https://socialcrm.com/api/public/repair-estimator/sessions/rin_8sQ2…/contact \
  -H "Content-Type: application/json" \
  -H "Origin: https://joesautobody.com" \
  -d '{ "name": "Alex Rivera", "email": "alex@example.com", "phone": "555-123-4567", "consent": true }'
{
  "data": { "success": true, "ignored": false, "crmContactId": "…" }
}

Errors

Status Meaning
400 Invalid or missing request body
402 Estimator not entitled for this shop, or monthly cap reached
404 Unknown/unpublished slug, expired or unknown token, or disallowed origin
429 Per-IP rate limit or per-session message cap exceeded
502 Upstream AI provider error or timeout

Rate-limited responses include standard RateLimit-* headers and, where applicable, retryAfter (seconds) in the body.