Agent chat API
Guides

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:chat scope (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 with PATCH /v1/agent and "deployed_channels": { "api": true } (scope agent:write).
  • AI credits. Each reply is charged by the agent's model tier: Essential 1, Pro 4, Ultra 8 credits. Out of credits returns 403 with code PLAN_LIMIT_REACHED; a workspace with no active plan returns 402 with the same code.

Calls use the chat rate tier: 20 requests per minute per key, 60 per workspace.

Send a message

Terminal
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" }
  }'
messagestringrequired

The customer's message.

conversation_idstring

Continue an existing API-channel conversation. Omit to start a new one. Passing a conversation from another channel returns 400.

customerobject

Optional 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.

attachmentsarray

Optional attachments passed to the agent.

The response

JSON
{
  "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_replies and buttons — suggested follow-ups and link buttons, when the agent produced them.
  • sources — titles of the knowledge base content the reply cited.
  • escalatedtrue when 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 the agent.escalated webhook 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:

JavaScript
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

StatusMeaning
402No active plan on the workspace (code PLAN_LIMIT_REACHED).
403AI credit limit reached (code PLAN_LIMIT_REACHED), or the key lacks agent:chat (code insufficient_scope).
409Agent disabled, or the API channel not enabled.
429Chat rate limit hit — retry after Retry-After seconds.

Full request and response schemas are in the Agent reference.