Back-office side of the per-order support chat. Two support kinds share this panel:
the driver side and the client side, both defined in Chat. Paths are
relative to the /api/v1 prefix; all routes require an admin bearer token. Support
is global — there is no city scoping, so any active admin sees the whole queue.
Kinds. The inbox is filterable by
kind(driverorclient); omit it to get both. The room-addressed endpoints (show/claim/messages/release/read) work the same for either kind — a room already carries itskind, so nokindparam is needed there.
Claim model. A support room starts unassigned (the pool). An admin claims it explicitly (
POST …/claim) or by sending the first message; from then on only that admin can read, write, or release it. Releasing returns the room to the pool.
Addressing. Admins reach a room by its
room_id, taken from the inbox.
See Common errors.
| Method | URI | Description |
|---|---|---|
GET |
/admin/order-support |
Support inbox (pool or mine) |
GET |
/admin/chat-rooms/{roomId} |
Read a support room |
POST |
/admin/chat-rooms/{roomId}/claim |
Claim a pooled room |
POST |
/admin/chat-rooms/{roomId}/messages |
Send a message (claims a pooled room) |
POST |
/admin/chat-rooms/{roomId}/release |
Release a claimed room to the pool |
POST |
/admin/chat-rooms/{roomId}/read |
Mark the room read |
Failures share the envelope { "error": "SupportError", "message": "…" }.
Paginated support inbox, newest activity first. Each item carries the room_id used
to address the room in the other endpoints.
Query parameters
| Param | Type | Default | Rules |
|---|---|---|---|
bucket |
string | pool |
pool (unassigned) or mine (claimed by you) |
kind |
string | — (both) | driver or client; omit to include both kinds |
limit |
integer | 25 |
1–100 |
cursor |
string | — | Opaque cursor from next_cursor |
Response 200
{
"items": [
{
"order_id": 42,
"room_id": 12,
"kind": "driver",
"channel": "chat.rooms.12",
"state": "pool",
"assigned_admin": null,
"last_message": {
"sender_role": "DRIVER",
"sender_name": "Pedro",
"content": "Se me dañó la bomba, no puedo cargar.",
"created_at": "2026-06-26T12:40:00+00:00"
}
}
],
"next_cursor": "eyJjaGF0X3Jvb21zLmxhc3RfbWVzc2FnZV9hdCI6...",
"has_more": false
}
Each item's kind is driver or client. In the mine bucket, state is
claimed and assigned_admin is { "id", "name" }.
Reads a support room: channel, the last 50 messages (oldest first) and status. A
pooled room can be read by any admin (for triage); a claimed room only by its
assigned admin. Read-only.
Response 200
{
"channel": "chat.rooms.12",
"messages": [
{
"id": 44,
"order_id": 42,
"sender_id": 3,
"sender_role": "DRIVER",
"sender_name": "Pedro",
"content": "Se me dañó la bomba, no puedo cargar.",
"type": "TEXT",
"created_at": "2026-06-26T12:40:00+00:00"
}
],
"status": { "state": "pool", "assigned_admin": null }
}
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "SupportError", "message": "Chat de soporte no encontrado." } |
Unknown room (or not a support room) |
403 |
{ "error": "SupportError", "message": "Este chat está asignado a otro administrador." } |
Room claimed by another admin |
Claims a pooled room for you. Idempotent if you already own it. Only while the order is active.
Response 200
{ "status": { "state": "claimed", "assigned_admin": { "id": 7, "name": "Ana" } } }
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "SupportError", "message": "Chat de soporte no encontrado." } |
Unknown room |
400 |
{ "error": "SupportError", "message": "Soporte no disponible para esta orden." } |
Order is not active |
403 |
{ "error": "SupportError", "message": "Este chat está asignado a otro administrador." } |
Claimed by another admin |
409 |
{ "error": "SupportError", "message": "Otro administrador tomó este chat." } |
Lost the claim race |
Sends a message. If the room is in the pool, sending claims it for you; if you already own it, it appends. Only available while the order is active.
Request body
| Field | Type | Required | Rules |
|---|---|---|---|
content |
string | yes | 1–500 chars |
Response 201
{
"message": {
"id": 46,
"order_id": 42,
"sender_id": 7,
"sender_role": "ADMIN",
"sender_name": "Ana",
"content": "Te contacto con la estación más cercana.",
"type": "TEXT",
"created_at": "2026-06-26T12:42:00+00:00"
},
"channel": "chat.rooms.12",
"status": { "state": "claimed", "assigned_admin": { "id": 7, "name": "Ana" } }
}
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "SupportError", "message": "Chat de soporte no encontrado." } |
Unknown room |
400 |
{ "error": "SupportError", "message": "Soporte no disponible para esta orden." } |
Order is not active |
403 |
{ "error": "SupportError", "message": "Este chat está asignado a otro administrador." } |
Claimed by another admin |
409 |
{ "error": "SupportError", "message": "Otro administrador tomó este chat." } |
Lost the claim race |
Releases a room you own back to the pool. Only the assigned admin may release.
Response 200
{ "status": { "state": "pool", "assigned_admin": null } }
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "SupportError", "message": "Chat de soporte no encontrado." } |
Unknown room |
403 |
{ "error": "SupportError", "message": "No sos el administrador asignado de este chat." } |
You are not the assigned admin |
409 |
{ "error": "SupportError", "message": "Este chat no tiene soporte asignado." } |
Room is not claimed |
Marks the room read up to now. Only the assigned admin may call it.
Response 200
{ "read_at": "2026-06-26T12:43:00+00:00" }
# Pool inbox (both kinds)
curl "/api/v1/admin/order-support?bucket=pool" -H "Authorization: Bearer {admin_token}"
# Pool inbox, client support only
curl "/api/v1/admin/order-support?bucket=pool&kind=client" -H "Authorization: Bearer {admin_token}"
# Claim a room (room_id from the inbox)
curl -X POST /api/v1/admin/chat-rooms/12/claim -H "Authorization: Bearer {admin_token}"
# Reply
curl -X POST /api/v1/admin/chat-rooms/12/messages \
-H "Authorization: Bearer {admin_token}" \
-H "Content-Type: application/json" \
-d '{"content": "Te contacto con la estación más cercana."}'
# Release back to the pool
curl -X POST /api/v1/admin/chat-rooms/12/release -H "Authorization: Bearer {admin_token}"