API reference
The endpoints on this domain. The first one trades an API key for an access token and is the only one a backend calls; the rest are the dashboard's own routes and run on its session cookie. Everything you do with a token afterwards goes to the Data API, which is documented separately.
Authentication
The routes below authenticate with your dashboard session cookie. Every request is resolved to the signed-in user, then to the workspace they belong to, and all reads and writes are scoped to that workspace. An id from another workspace returns 404, never somebody else's data.
Calling from your own server? These routes will not answer an access token, only a browser session. Create a key, exchange it at POST /api/v1/token, and use the token against the Data API instead. See API keys below.
Order statuses
Any endpoint that accepts or returns a status uses one of these values. Anything else is rejected with a 400.
pendingprocessingcallingconfirmedunconfirmedfailedno-answerpostponedorder-changedunrecognizedEndpoints
/api/v1/tokenTrade an API key for an access token
The one endpoint you call with an API key, and the only one that supports server to server calls. Send the key as a bearer credential with no body. The token that comes back lasts one hour, carries no refresh token, and is used against the Data API rather than the routes below. The response also returns the project URL and publishable key so an integration can configure itself from this single call. Call it from your own server: it sends no CORS headers, and a key must never reach a browser.
Responses
200access_token, token_type, expires_in in seconds, project_url, and publishable_key.401invalid_api_key. The key is missing, malformed, unknown, expired, or revoked. The body is identical for all of them on purpose.429rate_limited. 60 exchanges per IP and 12 per key, each per 5 minutes. Honour Retry-After.500server_error. The key checked out but the session could not be minted. Retry with backoff.
curl -X POST https://www.saficonfirm.com/api/v1/token \
-H "Authorization: Bearer sk_live_..."{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "bearer",
"expires_in": 3600,
"project_url": "https://nvkkanirwnjjvuwxsjch.supabase.co",
"publishable_key": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}/api/ordersList every order in the workspace
Returns all orders belonging to the caller's workspace, newest first. Orders from other workspaces are never returned, even if you know their id.
Responses
200An object with an orders array.401No valid session.500The orders could not be loaded.
curl https://www.saficonfirm.com/api/orders \
-H "Cookie: <session cookie>"{
"orders": [
{
"id": "3f1c...",
"workspace_id": "9b20...",
"client_name": "Yassine B.",
"phone": "+212600112233",
"store_name": "Atlas Store",
"products_name": "Wireless earbuds x1",
"address": "Casablanca",
"status": "confirmed",
"created_at": "2026-07-19T09:12:44.000Z"
}
]
}/api/ordersCreate an order and queue it for confirmation
Creates one order in the caller's workspace and attaches a pending outbound operation assigned to the workspace's order handler agent. Field names are accepted in both camelCase and snake_case. The phone number is validated as a Moroccan number and normalized to the +212 format before it is stored.
Body
| Field | Type | Description |
|---|---|---|
clientNamerequired | string | The customer's name. |
phonerequired | string | A Moroccan phone number. Stored normalized as +212XXXXXXXXX. |
storeNamerequired | string | The store the order was placed in. |
productsNamerequired | string | What the customer ordered. |
address | string | Delivery address. Optional. |
status | enum | One of the order statuses. Defaults to pending. |
Responses
201The created order, including operation_id when the operation was attached.400Invalid JSON, a failed field validation, or an unknown status.401No valid session.403The caller has no workspace.422NO_ORDER_HANDLER. The workspace has no agent set as the order handler, so the order was not created.
curl -X POST https://www.saficonfirm.com/api/orders \
-H "Content-Type: application/json" \
-H "Cookie: <session cookie>" \
-d '{
"clientName": "Yassine B.",
"phone": "0600112233",
"storeName": "Atlas Store",
"productsName": "Wireless earbuds x1",
"address": "Casablanca"
}'{
"id": "3f1c...",
"status": "pending",
"phone": "+212600112233",
"operation_id": "7c44..."
}/api/orders/{id}Fetch one order
Returns a single order from the caller's workspace.
Responses
200The order.401No valid session.403The caller has no workspace.404No order with that id in this workspace.
curl https://www.saficonfirm.com/api/orders/3f1c... \
-H "Cookie: <session cookie>"/api/orders/{id}Update an order's status or details
Status can be changed at any point in the order's life. The content fields, name, phone, store, products, and address, can only be edited while the order is still pending, because once an agent has started calling, changing them would break the record of what was confirmed.
Body
| Field | Type | Description |
|---|---|---|
status | enum | A new status for the order. |
clientName | string | Editable while pending. |
phone | string | Editable while pending. |
storeName | string | Editable while pending. |
productsName | string | Editable while pending. |
address | string | Editable while pending. Send an empty string to clear it. |
Responses
200The updated order.400Invalid JSON or an unknown status.404No order with that id in this workspace.
curl -X PUT https://www.saficonfirm.com/api/orders/3f1c... \
-H "Content-Type: application/json" \
-H "Cookie: <session cookie>" \
-d '{ "status": "confirmed" }'/api/orders/{id}Delete an order
Permanently removes an order from the workspace. There is no undo.
Responses
204Deleted. No body is returned.401No valid session.403The caller has no workspace.
curl -X DELETE https://www.saficonfirm.com/api/orders/3f1c... \
-H "Cookie: <session cookie>"/api/creditsRead the workspace credit balance
Returns the credit balance for the caller's workspace. The balance belongs to the workspace owner and is shared by every member, so all members see the same numbers.
Responses
200The current balance, lifetime total, and lifetime spend.401No valid session.
curl https://www.saficonfirm.com/api/credits \
-H "Cookie: <session cookie>"{
"credits": 1420,
"totalCredits": 5000,
"totalSpent": 3580
}Errors
Errors return a JSON body with an error message, and where it helps, a machine readable code you can branch on.
VALIDATION_ERROR400One or more fields failed validation. The response carries a fields object naming each bad field and why it was rejected.
NO_ORDER_HANDLER422The workspace has no agent set as the order handler. Create one under Agents, then retry. The response includes redirectTo for convenience.
Unauthorized401The request carried no valid session. Sign in again, or create an API key and exchange it at POST /api/v1/token for an access token.
No workspace found403The authenticated user is not a member of any workspace.
API keys
LiveCreate a key under Dashboard, API keys and trade it at the endpoint above for an access token that lasts one hour. The token is an ordinary session for your own user, so the database scopes your requests exactly as it scopes the dashboard. Token lifetime, revocation, rate limits, and the project URL and publishable key you need are all on Authentication.
Want to see it work before writing any code? Open the playground and run a real read against your own data.