# API guide

Except health, static dashboard, login and signed Meta webhook, endpoints require a logged-in session. Mutating endpoints require the session's `X-CSRF-Token`. Staff cannot manage routes/areas/settings/accounts/numbers/templates/holidays. Drivers can only access `/api/driver` and `/api/delivery` for their assigned driver profile.

| Method | Endpoint | Purpose |
|---|---|---|
| POST | /api/login | `{username,password}` → session cookie and CSRF token |
| GET | /api/me | Current user and CSRF token |
| POST | /api/logout | Revoke session |
| GET | /api/state | Dashboard masters, orders/items, recent inbox, audit and queues |
| POST/PUT/DELETE | /api/routes, /api/areas, /api/customers, /api/products, /api/vehicles, /api/drivers, /api/whatsapp_numbers, /api/holidays, /api/message_templates | Create; PUT/DELETE use `?id=ID` |
| POST | /api/stops | `{route_id,area_ids:[ordered IDs]}` |
| POST | /api/orders | `{customer_id,items:[{product_id,quantity}],notes,override?,allow_duplicate?,review_message_id?}` |
| PUT | /api/orders | `{id,customer_id?,area_id?,route_id?,delivery_date?,status?,payment_status?,notes?,items?}` |
| POST | /api/assign | `{route_id,date,vehicle_id,driver_id,departed}` |
| GET | /api/driver | Today's assigned delivery list |
| POST | /api/delivery | `{order_id,status,notes?,date?}`; Reschedule requires date |
| GET | /api/customer-history?id=ID | Details, orders and frequent products |
| POST | /api/simulate | Local only: `{phone,body,external_id?,kind?}` |
| POST | /api/takeover | `{conversation_id,enabled}` |
| POST | /api/reply | `{conversation_id,body,template?}` approved Meta template object optional |
| POST | /api/settings | duplicate_minutes, automation (`true`/`false` string), summary_time |
| POST | /api/users | Admin only: `{username,password,role,driver_id?}` |
| POST | /api/resolve | `{id: notification ID}` |
| POST | /api/retry | `{webhook_id}` or `{outbox_id}`; inspect provider logs before send retry |
| POST | /api/demo | Explicitly load fictional masters into an empty business |
| GET | /webhook/whatsapp | Meta verification challenge |
| POST | /webhook/whatsapp | Exact-byte HMAC-verified Meta envelope persisted before 200 |

## Supplied gateway compatibility

These imports simulate receipt, not live WhatsApp connectivity. They are authenticated and cannot send through real numbers.

```json
{
  "provider": "wa-akg",
  "payload": {
    "event": "message.received",
    "data": {
      "key": {"id":"sample-001","fromMe":false},
      "from":"919000000000@s.whatsapp.net",
      "type":"TEXT",
      "content":"5 box cleaner bhej do",
      "isGroup":false
    }
  }
}
```

```json
{
  "provider":"wechaty",
  "payload":{"id":"sample-002","phone":"919000000000","text":"2 carton tissue chahiye","type":"text","self":false,"room":false}
}
```

Submit either JSON to `/api/simulate` with session and CSRF headers. Group, self-sent, nonnumeric sender and unsupported provider inputs are rejected. A real Cloud API event must instead arrive at the public signed webhook.

## Manual booking example

```json
{
  "customer_id":1,
  "items":[{"product_id":1,"quantity":5},{"product_id":2,"quantity":10}],
  "notes":"Retailer confirmed by phone",
  "allow_duplicate":false
}
```

Customer must have an area and a configured active route. Product units/prices are resolved from the master; callers cannot invent them. A route/date override is a staff decision and is audited. Customer WhatsApp bookings are created by the confirmation workflow; direct manual bookings have source `manual`.
