# HeavyHaul Agent × AI Backend — Integration Brief

**To:** the developer of the AI/extraction backend (order agent, estimator, extractors)
**From:** HeavyHaul Agent frontend team
**Purpose:** connect your existing AI products to the new HeavyHaul Agent trip-workspace SaaS over HTTP. No rewrites — we call your API from our server.

---

## 1. What HeavyHaul Agent is (30-second context)

A multi-user web app where a broker, dispatcher, and driver share one **Trip Workspace** per load: rate confirmation, state permits, participants, warnings, a shared chat room, and an AI assistant. Our stack is Next.js + Supabase (Postgres + file storage). All calls to you come **from our server only** (never the browser), authenticated with a Bearer token.

## 2. What we already have working

- Accounts, login, per-trip roles (broker/dispatcher/driver/pilot/shipper)
- Broker intake page (public link, rate-con upload, "buy permits vs. upload own")
- Trip workspace: documents, participants/invitations, status flow, audit history
- Shared trip chat room (participant messages work; AI answers are stubbed until you're connected)
- Warnings engine (dimension mismatch, expiry, curfew, escort — waiting on real extraction data)
- File storage for all uploaded PDFs (we can send you the file bytes or a signed URL)

## 3. Connected GPT endpoints

Our adapter is one file and can remap paths/shapes easily, so if your existing routes differ, just send us your actual spec. The shapes below are what our app consumes.

**Auth for all endpoints:** `Authorization: Bearer <HHA_API_CLIENT_SECRET>` plus
`X-HHA-Client-ID: <HHA_API_CLIENT_ID>`.

### 3.1 Permit extraction
`POST /api/workspace/extract/permit` — multipart form with `file` and optional
`trip_id`, `document_id`, and `permit_id`. GPT returns its existing Synchron
Permit API contract (`order_id`, `order_info`, `states_info`, and
`permit_responses`). The Workspace adapter maps it to the UI shape below while
preserving the complete response in `raw`.
```json
{
  "state_code": "TX", "permit_number": "123", 
  "effective_date": "YYYY-MM-DD", "expiration_date": "YYYY-MM-DD",
  "length_in": 0, "width_in": 0, "height_in": 0, "weight_lbs": 0,
  "route_description": "...", 
  "restrictions": ["..."], "curfews": ["..."], "escorts": ["..."],
  "raw": {}
}
```

### 3.2 Rate confirmation extraction
`POST /api/workspace/extract/rate-confirmation` — multipart form with `file` and
optional `trip_id` and `document_id`. GPT returns its existing Synchron RateCon
contract: `{ "url": "...", "ext_info": {...} }`. The Workspace adapter maps
`ext_info` to the UI shape below and preserves the complete response in `raw`.
```json
{
  "origin": "...", "destination": "...", "commodity": "...",
  "carrier_name": "...", "broker_name": "...",
  "pickup_date": "...", "delivery_date": "...",
  "length_in": 0, "width_in": 0, "height_in": 0, "weight_lbs": 0,
  "raw": {}
}
```

### 3.3 Trip AI chat (your order agent)
`POST /api/workspace/logistics-chat` — JSON. Workspace sends its immutable
Supabase trip id, so GPT loads only `all_trips.workspace_trip_id` and never
mixes it with Synchron `all_orders`.
```json
// request
{
  "message": "Can I drive at night in Ohio?",
  "workspace_trip_id": "26f1bfdf-1a93-4387-8774-a57a756bff43",
  "language": "en",
  "browser_id": "workspace-<trip-uuid>",
  "history": []
}
// response
{ "response": "...", "confidence": "high|partial|low", "source_citations": [] }
```

### 3.4 Trip AI voice
`POST /api/workspace/logistics-voice/token` — JSON. The server returns a
short-lived LiveKit room token after matching `workspace_trip_id` in
`all_trips`. Supported languages are `en`, `es`, `ru`, and `ro`. The browser
connects directly to LiveKit for microphone/audio; GPT's separate
`logistics_bot/livekit_agent.py` worker processes the room.
```json
// request
{
  "workspace_trip_id": "26f1bfdf-1a93-4387-8774-a57a756bff43",
  "browser_id": "browser-session-id",
  "name": "Driver name",
  "language": "es"
}
// response
{
  "token": "short-lived-jwt",
  "url": "wss://livekit-host",
  "room_name": "order-bot-workspace-...",
  "session_id": "...",
  "language": "es"
}
```

### 3.5 Synchron order creation and return
Workspace currently requests one Synchron order per Workspace trip by email, with the RateCon and Workspace trip reference. The factory has no implemented `/api/synchron/orders` creation endpoint. Synchron saves the reference and returns its order token and individual state permits through the signed Workspace callback described in `SYNCHRON_WORKSPACE_HANDOFF.md`.

## 4. Nice-to-have soon after MVP (tell us what already exists)

- **Async extraction callback:** if extraction is slow, return `202 { job_id }` and POST the result to a callback URL we provide — otherwise we wait synchronously (we time out at 120s).
- **More extractors** you already have: truck permit, trailer permit, state permits, IFTA, COI — same multipart pattern as 3.1; send us the response shapes.
- **Estimator agent:** endpoint + request/response spec so we can add an estimate tab/chat.
- **Synchron status webhook:** notify us when a permit/route order is fulfilled (we'll give you a callback URL + secret).

## 5. What we need to receive from you (checklist)

1. Base URL of the API (staging + production)
2. API key (Bearer)
3. Confirmation of the endpoint paths above, or your actual paths/shapes so we remap
4. Response time expectations per endpoint (sync vs. needs-async)
5. Spec for the extra extractors + estimator when ready
6. A sample permit PDF + its expected extraction JSON (for our tests)

Once we have items 1–3, integration on our side is a same-day task: we set two env vars and, if needed, adjust one adapter file.
