Users & agents
Delete the account
Close an account created with POST /v1/agents/init, using its own key. The account, every key, project, memory, fact, webhook and audit event goes. Korely keeps two things: the account's model-cost rows, by day, with no agent, memory or end user, and a record of the erasure (the account id, a keyed digest of its email when it has one, and the rows erased per table).
/v1/account?confirm=<account id>
SDK: korely.delete_account(confirm="<account id>"). An account created by
POST /v1/agents/init has no login: the key is the
account. This is how you close it. The delete is physical and cannot be undone, and the
key stops working as soon as the call returns. The
Glossary defines the words used across the docs.
This call deletes the whole account for good. DELETE /v1/account with confirm set to the account's id erases the whole account (every project, key, memory and fact) with an unconfined key of that account that has the admin permission (since 1.0.5; before, any key that could write). This applies to an account opened with POST /v1/agents/init and never used with a login (with a login the call answers 409). Give such a key only to code you trust. The project wall does not apply to this call. Use a throwaway account to try it.
An account you sign in to (the dashboard at agent.korely.ai) does not close with a key, so a key that ends up in a log cannot delete an account. Close it from the dashboard: Account, Close the account. That removes its data and keys too.
To erase one of your customers instead, use DELETE /v1/users/{end_user}/memories.
Authentication
HTTP header, required: Authorization: Bearer kor_live_.... Since 1.0.5 the key needs the admin permission (the API calls it a scope) and must not be confined to a project or to some end users. The key that POST /v1/agents/init returns has it from 1.0.5; the 28 init keys issued earlier have only memories:read and memories:write and can no longer close the account through the API.
A key without admin, or a confined key, answers 403 forbidden and nothing is deleted. Before 1.0.5 any key with memories:write could close the account, including a confined one. If you hold only an older init key, sign in to the dashboard with it (Account page), and close the account there: the account then has a login, and this call answers 409 account_has_login.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
confirm | string | Required | The id of the account you are deleting, typed: the tenant_id that GET /admin/whoami returns for the same key (at most 64 characters). Without it, or with anything else, the call answers 400 confirmation_required and nothing is deleted. The specification lists the parameter as optional; in practice the call refuses without it. |
Up to Korely 1.0.22, ?confirm=true was enough. From 1.0.23 it answers
400 confirmation_required, and the message says where the id is. The id has to be
read on purpose, so a key that leaked, or a script pointed at the wrong key, cannot close an
account with a flag. Read it with the same key, then send it back:
curl "https://api.korely.ai/admin/whoami" \ -H "Authorization: Bearer kor_live_..."# {"kind": "api_key", "name": "...", "tenant_id": "<account id>"}Example request
curl -X DELETE "https://api.korely.ai/v1/account?confirm=<account id>" \ -H "Authorization: Bearer kor_live_..."
The libraries ask for the same id: Python from korely-memory 0.2.0, Node.js from
0.2.0. The library reads GET /admin/whoami with the same key first and
sends the DELETE only when what you typed is a UUID equal to that id. A missing id,
True, "true" or another id deletes nothing and raises a
KorelyError with the code confirmation_required, whose message names the id to
type; only an answer with deleted: true counts as a deletion. Earlier versions send
confirm=true, which a 1.0.23 server refuses, and the new versions refuse to delete
against a server older than 1.0.23. On the command line:
korely delete-account --confirm <account id>; korely delete-account alone
prints the id to type, and --yes is no longer taken (exit code 2, nothing sent).
Response
200 OK. The rows the account had, by table, counted when it was closed (only tables that had rows). agent_llm_usage, when present, counts the cost rows that were kept without the account. The erasure is one database transaction: if it fails, the account stays whole and you can call again.
{ "deleted": true, "removed": { "agent_facts": 31, "agent_memories": 12, "audit_events": 58, "agent_api_keys": 1, "agent_rate_limits": 5, "hosted_accounts": 1, "hosted_usage_months": 1, "agent_llm_usage": 24, "agent_projects": 1 }}| Field | Type | Description |
|---|---|---|
deleted | boolean | Always true on a 200. |
removed | object | Rows the account had, by table name, as counted when it was closed. Only tables that had rows appear. |
Errors
| Status | Code | When |
|---|---|---|
400 | confirmation_required | confirm is missing or is not this account's id, true included (up to 1.0.22, true was enough). Nothing is deleted. |
401 | invalid_key | Missing or invalid kor_live_ key. |
403 | forbidden | The key has no admin scope, or it is confined to a project or to some end users (since 1.0.5). |
409 | account_has_login | The account has a login: close it from the dashboard (Account, Close the account). |
422 | invalid_request | confirm is longer than 64 characters. |
429 | rate_limit_exceeded | Per-minute, per-hour or per-day request limit. Carries Retry-After. |
503 | unavailable | The database did not answer, or the request waited past one of the store's deadlines. Retry after the seconds in Retry-After. |