Agent chat API
Agent chat API
Send messages to your trained AI agent from your own code and get structured replies in one round-trip.
POST /v1/agent/messages runs one synchronous turn against your AI agent — the same agent, knowledge base, and guardrails that answer on the widget and messaging channels. Use it to put your agent inside your own product: an in-app assistant, a support bot on a channel Asks doesn't cover, or an internal tool.
Each call creates or continues a conversation on the API channel, so every exchange lands in your inbox like any other conversation.
Prerequisites
- An API key with the
agent:chatscope (Authentication). - The agent must be enabled and deployed on the API channel — otherwise the endpoint returns
409. Enabling the MCP server turns the API channel on; you can also set it directly withPATCH /v1/agentand"deployed_channels": { "api": true }(scopeagent:write). - AI credits. Each reply is charged by the agent's model tier: Essential 1, Pro 4, Ultra 8 credits. Out of credits returns
403with codePLAN_LIMIT_REACHED; a workspace with no active plan returns402with the same code.
Calls use the chat rate tier: 20 requests per minute per key, 60 per workspace.
Send a message
curl https://api.asks.app/v1/agent/messages \
-H "Authorization: Bearer ask_live_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"message": "What is your return policy?",
"customer": { "email": "sam@example.com", "name": "Sam" }
}'messagestringrequiredThe customer's message.
conversation_idstringContinue an existing API-channel conversation. Omit to start a new one. Passing a conversation from another channel returns 400.
customerobjectOptional identifying info — email, phone, name, external_id. Used when starting a new conversation to create or match a customer record, so API conversations dedupe against the same person on other channels.
attachmentsarrayOptional attachments passed to the agent.
The response
{
"object": "agent_response",
"conversation_id": "cmc1a2b3c…",
"messages": ["We accept returns within 30 days of delivery…"],
"quick_replies": ["Start a return", "Talk to a human"],
"buttons": [{ "text": "Return portal", "url": "https://example.com/returns" }],
"images": [],
"sources": ["Returns & refunds policy"],
"escalated": false,
"credits_used": 1,
"model_tier": "essential"
}messages— the reply, as one or more message bubbles. Render them in order.quick_repliesandbuttons— suggested follow-ups and link buttons, when the agent produced them.sources— titles of the knowledge base content the reply cited.escalated—truewhen the agent handed the conversation to a human. Stop expecting AI replies and route the customer to your human channel; the conversation is already flagged in the Asks inbox. Pair this with theagent.escalatedwebhook to notify your team.credits_used— credits charged for this turn (0 when no billable reply was produced).
messages can come back empty with credits_used: 0 — for example when abuse protection blocks the conversation or a human takes it over mid-turn. Treat an empty array as "no reply", not as an error.
Multi-turn conversations
Pass the returned conversation_id on the next call and the agent keeps the full history:
const API = "https://api.asks.app/v1";
const headers = {
Authorization: `Bearer ${process.env.ASKS_API_KEY}`,
"Content-Type": "application/json",
};
async function ask(message, conversationId) {
const res = await fetch(`${API}/agent/messages`, {
method: "POST",
headers,
body: JSON.stringify({ message, conversation_id: conversationId }),
});
if (!res.ok) throw new Error(`Asks API ${res.status}`);
return res.json();
}
const first = await ask("Do you ship to Canada?");
const followUp = await ask("How much does it cost?", first.conversation_id);Store the conversation_id against your own user/session so a returning user continues the same thread.
Verify it works — after your first call, open the inbox and filter by the API channel. Your message and the agent's reply appear as a normal conversation your team can take over.
Errors to handle
| Status | Meaning |
|---|---|
402 | No active plan on the workspace (code PLAN_LIMIT_REACHED). |
403 | AI credit limit reached (code PLAN_LIMIT_REACHED), or the key lacks agent:chat (code insufficient_scope). |
409 | Agent disabled, or the API channel not enabled. |
429 | Chat rate limit hit — retry after Retry-After seconds. |
Full request and response schemas are in the Agent reference.