Integrations

REST API

Call your chatbots from your own software over HTTP. Issue keys, ask questions, keep multi-turn conversations, and revoke access at any time. Pro plan only.

This is the opposite of the API Keys page, which stores your keys for providers like OpenAI. Here you get a key that your server sends to us.

Creating a Key

  1. In the company admin panel, open Developer.
  2. Click New API key.
  3. Give it a name you'll recognise later (e.g. Support portal), optionally pin it to a single chatbot, and set a rate limit.
  4. Copy the key. It is shown once and cannot be retrieved again — only a hash of it is stored, so nobody, including us, can read it back.

If you lose a key, revoke it and create another. Revoking takes effect immediately.

Pinning a key to one chatbot is the safer choice for a key that ships inside another product — it can never be pointed at a different chatbot, even if the calling code is changed.

Authentication

Send the key as a Bearer token on every request:

Authorization: Bearer aimy_sk_your_key_here
Never call this API from a browser. Anyone who can load the page can read the key out of it. Calls must come from your server. There is no CORS header, so browsers will refuse the request anyway.

Asking a Question

POST https://aimy.com.my/chat/api/v1/chat

curl -X POST https://aimy.com.my/chat/api/v1/chat \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "message": "What is the refund policy?",
        "chatbot_id": 170
      }'

Request fields:

  • messagerequired. Up to 8000 characters.
  • chatbot_id — required unless the key is pinned to a chatbot. Get the ids from GET /api/v1/chatbots.
  • conversation_id — optional. Omit it to start a new conversation; the response returns one. Pass the same value again to continue that conversation.

A successful response:

{
  "success": true,
  "answer": "Refunds are available within 30 days ...",
  "conversation_id": "8f2c1a7b9d0e4f6a1b2c3d4e",
  "chatbot": { "id": 170, "name": "Support Bot" },
  "citations": [ { "name": "policy.pdf", "page": 4, "snippet": "..." } ],
  "sources":   [ { "document": "policy.pdf", "page": 4, "preview": "...", "score": 0.81 } ]
}
citations and sources follow the Sources switch on the chatbot's row in the Chatbots page. With it off, both arrays come back empty — the fields are always present, so your code never has to check whether the key exists.

Multi-turn Conversations

Pass the conversation_id you got back on the first call, and the chatbot remembers what was said:

// First call - no conversation_id
{"message": "Do you ship to Sabah?"}
  -> {"answer": "Yes ...", "conversation_id": "8f2c1a7b9d0e4f6a1b2c3d4e"}

// Follow-up - same conversation_id
{"message": "How long does it take?",
 "conversation_id": "8f2c1a7b9d0e4f6a1b2c3d4e"}

You may also supply your own id (1–64 characters, letters, digits, _ or -) — your own ticket or session number, for instance. Conversations appear in History labelled with the key's name.

Listing Your Chatbots

GET https://aimy.com.my/chat/api/v1/chatbots

curl https://aimy.com.my/chat/api/v1/chatbots \
  -H "Authorization: Bearer YOUR_KEY"
{
  "success": true,
  "pinned": false,
  "chatbots": [
    { "id": 170, "name": "Support Bot", "active": true, "documents": 12 }
  ]
}

pinned: true means the key is locked to the one chatbot listed, and you can omit chatbot_id when asking questions.

Errors

Every failure has the same shape. Branch on code — the message is for humans and may be reworded.

{
  "success": false,
  "error": { "code": "rate_limited", "message": "Too many requests..." }
}
StatusCodeMeaning
400invalid_requestMissing or malformed field
401unauthorizedKey missing, invalid, or revoked
402quota_exceededYour account is out of tokens, or has no active plan
403forbidden_planThe API isn't included in your plan
403chatbot_not_allowedThis key is pinned to a different chatbot
404chatbot_not_foundNo such chatbot in your company
409chatbot_inactiveThe chatbot is switched off
429rate_limitedToo many requests — see Retry-After
503busyUnder load; retry shortly

Rate Limits

Each key has its own limit, set when you create it (60 requests per minute by default, adjustable up to 6000). Every response carries:

  • X-RateLimit-Limit — the key's limit
  • X-RateLimit-Remaining — how many are left in the current minute

A 429 also carries Retry-After in seconds. Rate limits are separate from your plan's token quota — you can be inside your rate limit and still hit quota_exceeded.

Usage & Auditing

The Developer page shows each key's last-used time and its call count over the last 30 days. Answers count toward your plan's token usage exactly like any other channel, and every conversation is saved to History.

Treat a key like a password. Keep it in an environment variable or a secrets manager — never in client-side code, a public repository, or a mobile app.