Korely

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

DELETE /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

ParameterTypeRequiredDescription
confirmstringRequiredThe 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:

Terminal window
curl "https://api.korely.ai/admin/whoami" \
-H "Authorization: Bearer kor_live_..."
# {"kind": "api_key", "name": "...", "tenant_id": "<account id>"}

Example request

Terminal window
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
}
}
FieldTypeDescription
deletedbooleanAlways true on a 200.
removedobjectRows the account had, by table name, as counted when it was closed. Only tables that had rows appear.

Errors

StatusCodeWhen
400confirmation_requiredconfirm is missing or is not this account's id, true included (up to 1.0.22, true was enough). Nothing is deleted.
401invalid_keyMissing or invalid kor_live_ key.
403forbiddenThe key has no admin scope, or it is confined to a project or to some end users (since 1.0.5).
409account_has_loginThe account has a login: close it from the dashboard (Account, Close the account).
422invalid_requestconfirm is longer than 64 characters.
429rate_limit_exceededPer-minute, per-hour or per-day request limit. Carries Retry-After.
503unavailableThe database did not answer, or the request waited past one of the store's deadlines. Retry after the seconds in Retry-After.