Getting started
The Kaily API lets your own code drive Kaily. This first release covers your API keys and your AI agents; helpdesk resources follow in later releases.
Everything is served from a single base URL:
https://api.kaily.ai/v1
JSON in, JSON out. Paths are kebab-case, response fields are snake_case, and timestamps are ISO-8601 in UTC.
1. Create a key
Only Owners and Admins can see this section.
Open Settings → Developers in the Kaily console and create an API key. Name it after whatever will use it — "Warehouse sync", "Acme CRM bridge" — optionally restrict it to specific AI agents, and tick the permissions it needs. Permissions are called scopes; see Authentication and permissions for the full list and the ready-made presets.
2. Copy the secret — it is shown once
When the key is created, the full credential is displayed once. Kaily stores only a one-way hash of the secret, so it genuinely cannot be shown again. If you lose it, revoke the key and create another.
A credential looks like this:
kly_<env>_<prefix>_<secret>
The prefix part is a public lookup handle — it is what the console shows in the key list, and it is safe to log. The final secret segment is the part that is verified against the stored hash. Treat the whole string as a password.
3. Make your first request
curl https://api.kaily.ai/v1/me \
-H "Authorization: Bearer kly_live_a1b2c3d4e5f6_s3cr3tvalue"
{
"data": {
"id": "key-4Zx9Lp",
"name": "Production sync",
"description": "Two-way sync with our CRM",
"prefix": "kly_live_a1b2c3d4e5f6",
"scopes": ["aiagents:read", "aiagents:write"],
"rate_limit_per_minute": 120,
"last_used_at": "2026-08-26T09:12:44.000Z",
"expires_at": null
}
}
GET /v1/me is the fastest way to see what a key can actually do: which scopes it carries and its per-minute rate limit. It is the one endpoint that needs no particular scope — any valid key can call it.
One header, and only in the header
Authentication is a single header:
Authorization: Bearer kly_<env>_<prefix>_<secret>
That is the whole of it. There is no second id header to send — the key identifies itself.
Credentials in the query string are rejected. If a request carries authorization, access_token, api_key, apikey or token as a query parameter, Kaily refuses it with 403 access_denied before doing anything else. This is deliberate: query strings end up in access logs, proxy logs and browser history, and an API key does not belong in any of them.
# Rejected with 403 — never do this
curl "https://api.kaily.ai/v1/ai-agents?api_key=kly_live_a1b2c3d4e5f6_s3cr3tvalue"
Rotating a key with no downtime
Keys are independent of each other, so rotation is straightforward:
- Create a second key with the same scopes.
- Deploy it.
- Confirm traffic has moved using
last_used_aton the old key. - Revoke the old one.
Nothing else is affected, because nothing is attached to a key beyond the key itself.
You can also run several keys at once for least privilege — a read-only key for an analytics job alongside a read-write key for a sync service, so a mistake in reporting cannot write anything.
A first real call
List the AI agents in your account:
curl "https://api.kaily.ai/v1/ai-agents?limit=10" \
-H "Authorization: Bearer kly_live_a1b2c3d4e5f6_s3cr3tvalue"
{
"data": [
{
"id": "cop-7Hs2Kd",
"name": "Support bot",
"enabled": true,
"created_at": "2026-08-01T10:00:00.000Z"
}
],
"meta": { "limit": 10, "next": null, "has_more": false }
}
Create one:
curl -X POST https://api.kaily.ai/v1/ai-agents \
-H "Authorization: Bearer kly_live_a1b2c3d4e5f6_s3cr3tvalue" \
-H "Content-Type: application/json" \
-d '{ "name": "Warehouse assistant" }'
Disable one without losing its history:
curl -X PUT https://api.kaily.ai/v1/ai-agents/cop-7Hs2Kd/enabled \
-H "Authorization: Bearer kly_live_a1b2c3d4e5f6_s3cr3tvalue" \
-H "Content-Type: application/json" \
-d '{ "enabled": false }'
Agents are disabled, never deleted — that keeps their conversation history intact.
What this release covers
This is the first release of the API. It covers API keys and AI agents: listing, reading, creating and updating your agents, reading their stats, and describing your own key with GET /v1/me.
Helpdesk resources — threads, messages, contacts and the rest — arrive in later releases. The API reference is generated from the running service, so it is always the authoritative list of what you can call today.
Rate limits
Limits are applied per key over a rolling 60-second window, so one key's backfill cannot starve another key in the same organisation. Every response carries the current state:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Requests allowed per minute for this key |
X-RateLimit-Remaining | Requests left in the current window |
X-RateLimit-Reset | Unix seconds at which the window resets |
Retry-After | Seconds to wait. Sent only on a 429 |
Read your own ceiling from rate_limit_per_minute in GET /v1/me. If you need more, ask support — it is a configuration change, not a deploy.
Where to go next
- Authentication and permissions — every scope, the presets, and how a 403 tells you what was missing
- Pagination — cursors, and how to walk every page
- Errors — the error envelope and the full code list
- API reference — the full endpoint list, generated from the running API