API reference · v1
Floee API
Read your conversations, sync your store's catalogue and orders, start scripts, place phone calls with your voice agent, and connect an MCP client. Everything is scoped to one agent by the API key you send.
Base URL and versioning
Every endpoint lives under https://icebot.icebergaisolutions.com/api/v1. Requests and responses are JSON (Content-Type: application/json); timestamps are ISO 8601 in UTC; money is ringgit (MYR) as a decimal number.
The version is in the path. Within v1 we only make additive changes: new endpoints, new optional parameters and new fields in responses. Ignore fields you do not recognise. A change that could break a working integration (removing or renaming a field, changing a type or a status code) ships as a new version beside this one, announced in advance, with v1 kept running while you move.
Endpoints
Conversations
- List conversationsGET
/api/v1/conversationsThe key's agent's conversations on every channel, most recent activity first. - List messages in a conversationGET
/api/v1/conversations/{id}/messagesThe messages of one conversation, oldest first. Internal notes are never returned. - Start a script on a conversationPOST
/api/v1/conversations/{id}/scriptsRuns one of your scripts on a conversation from your own system, for example a pickup reminder after an order is packed.
Orders
- List ordersGET
/api/v1/ordersOrders taken in conversation, oldest first, for a store connector to create in the store. - Report an order statusPOST
/api/v1/orders/{id}/statusThe store acknowledges an order, or reports its progress. The first external_id releases Floee's reservation; cancelled or refunded gives stock back.
Catalogue
- Create or update productsPOST
/api/v1/catalogue/productsBatch upsert from your store, keyed on your own product id. At most 200 products per request, 100 variants per product. - Archive productsPOST
/api/v1/catalogue/products/archiveYour store deleted these products. They go off sale; the rows are never deleted, and a later upsert restores them. At most 500 ids. - Set stock levelsPOST
/api/v1/catalogue/stockYour store's stock numbers, in bulk (up to 1,000). The store owns stock: Floee reads these and never writes them back.
Calls
- Place a phone callPOST
/api/v1/callsRings a number from your workspace's default outbound number, with the key's agent speaking. For apps and backends that want the agent to call a customer. - Get a callGET
/api/v1/calls/{id}The status of a call you placed: live while it is going, then its summary once it has ended. Poll it, or use the post-call data in your dashboard. - Get a call's recordingGET
/api/v1/calls/{id}/recordingA link to the recording of a call you placed, valid for 5 minutes.
MCP
Authentication
Send an API key as a bearer token on every request. Create keys in the dashboard under Settings, API keys. A key belongs to one agent: every request made with it sees only that agent's data, and no endpoint accepts a tenant or agent id from you.
curl https://icebot.icebergaisolutions.com/api/v1/conversations \
-H "Authorization: Bearer ibk_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"- Keys start with
ibk_. The full key is shown once, when it is created; afterwards the dashboard shows only its first twelve characters so you can tell keys apart. We store a one-way hash, so a lost key cannot be recovered, only replaced. - Allowed origins. A key with no allowed origins works from anywhere, which is what a server-to-server integration needs. List origins on the key and a request carrying any other
Originheader is refused with 403. Never put a key in a browser or a mobile app bundle; call the API from your own server. - Rotation. Create the new key, deploy it, then revoke the old one. Revocation takes effect on the next request, which then gets 401.
Scopes
Reads need no scope. Every write needs exactly one scope on the key, granted deliberately: keys are read-only by default, and no scope implies another. A request without the scope gets 403 with a message naming the missing scope.
| Scope | What it allows | Used by |
|---|---|---|
conversations:label | Add and remove labels on conversations | MCP tool set_conversation_labels |
conversations:status | Open, hold or close conversations | MCP tool set_conversation_status |
conversations:note | Write internal notes (never seen by the customer) | MCP tool add_conversation_note |
catalogue:sync | Sync products, stock and order status from your online store | POST /api/v1/catalogue/products, POST /api/v1/catalogue/products/archive, POST /api/v1/catalogue/stock, POST /api/v1/orders/{id}/status |
calls:create | Place outbound phone calls from your number (billed as voice minutes) | POST /api/v1/calls |
calls:recordings | Download the recording of a call (a short-lived link) | GET /api/v1/calls/{id}/recording |
Rate limits
- 120 requests per 60 seconds per API key, counted over a trailing window across every endpoint.
- 10 calls per minute per workspace on
POST /api/v1/calls, on top of the per-key limit, because each one rings a real phone.
Over a limit you get 429 with { "error": "rate limit exceeded" }. Nothing was done. Wait and retry with backoff (for example 1, 2, 4, 8 seconds); the window is trailing, so requests become available again as older ones age out.
Errors
Errors are JSON with an error string. Validation failures add details, a list of every problem found, and refusals meant for a person add a message.
{
"error": "invalid body",
"details": ["products[0]: name is required", "products[2]: price must be a non-negative number"]
}| Status | Meaning |
|---|---|
400 | The request is malformed. Nothing was written. Fix it before retrying. |
401 | No bearer token, or the key is unknown or revoked. |
402 | The workspace is out of credits for a billable action. |
403 | The key lacks the scope, the Origin is not allowed, or the plan does not include the feature. |
404 | Not found, or it belongs to another agent. The API does not say which. |
409 | Conflicts with the current state (for example an order already linked to a different store order). |
422 | Understood but refused (for example the number is on your do-not-call list). |
429 | Rate limited. Retry later. |
500 | Our fault. Safe to retry reads; retry writes with care. |
502 | An upstream provider failed. The message says what was and was not done. |
Beyond REST
- Webhooks: we POST each new message to your URL, signed.
- MCP server: your workspace as tools for any AI assistant that speaks MCP.
- Embed guide: the chat widget, the Talk button, the JavaScript SDK and React Native.