Skip to main content

Clatri API

The Clatri API lets you read and change your Clatri data from your own apps, scripts and automations, over HTTPS and JSON. It runs the same tools the Clatri agent and the Clatri MCP use: log an expense, read your income statement, create a task, list your medications…

It uses the same token as the MCP. If you already have one, you don't need another key.

API or MCP?
  • MCP: when you want an AI assistant (Claude, ChatGPT, Cursor…) to look at your Clatri while you chat with it. See Clatri MCP.
  • API: when you write code. Your program decides which tool to call and with what data, and gets JSON back.

How it works​

  • Base URL: https://api.clatri.com/v1
  • Authentication: an Authorization: Bearer clt_mcp_XXXX header on every call.
  • Everything is a tool. To run one, you POST to /v1/entities/{entity_id}/tools/{tool_name} with its arguments as the JSON body. The entity (personal, business, project) always goes in the path.
Method and pathWhat it's for
GET /v1/meThe token: your user, permissions, areas, entities and expiry date.
GET /v1/entitiesThe entities this token can use (id, type, name).
GET /v1/toolsThe tools this token can call, with their input schema.
POST /v1/entities/{entity_id}/tools/{tool_name}Runs a tool on that entity.
GET /v1/openapi.jsonThe full OpenAPI 3.1 specification. It's public: no token needed.

The full list of tools, with their arguments, is in the API reference.


Requirements​

You need an active Clatri subscription

Like the MCP, the API requires an active subscription. Without one you can't create tokens, and existing tokens respond 402 subscription_inactive until you renew. They're not deleted: they start working again on their own when you renew.

You need to call it from a server or a script

The API doesn't accept calls from a browser: it sends no CORS headers. That's on purpose, so nobody puts your token in a web page's code. Call it from a backend, a script, a serverless function or an automation tool.


Step 1 — Create your token​

  1. In the Clatri app, open Settings → Connections → Agents and APIs. On the web, Settings → Agents and APIs.
  2. Tap Create token and give it a name you'll recognize (for example, "My expenses script").
  3. Choose the permissions: Read only, Read and write or Full access (includes delete).
  4. Optionally, limit the areas (Money, Health, Administration, General) and entities it can use. By default it has all of them.
  5. Tap Create token and copy it.
Copy it right away

The token (it starts with clt_mcp_) is shown only once. If you lose it, revoke it and create another. Treat it like a password: anyone who has it can use your data with the permissions you chose.

Tokens expire after 6 months and you can have up to 10 active ones. After creating one, you can change its name, permissions, areas and entities without generating a new one.

In the examples on this page the token is in an environment variable:

export CLATRI_TOKEN="clt_mcp_XXXX"

Step 2 — Your first call​

Check that the token works with GET /v1/me:

curl https://api.clatri.com/v1/me \
-H "Authorization: Bearer $CLATRI_TOKEN"

The response looks like this (made-up data):

{
"user_id": "11111111-1111-4111-8111-111111111111",
"credential": "personal_token",
"token_name": "My expenses script",
"permissions": ["read", "write"],
"areas": ["money", "administration"],
"entity_ids": null,
"entities": [
{"id": "22222222-2222-4222-8222-222222222222", "type": "personal", "name": "Personal", "is_shared": false},
{"id": "33333333-3333-4333-8333-333333333333", "type": "business", "name": "My company", "is_shared": false}
],
"expires_at": "2027-04-29T15:00:00+00:00",
"request_id": "req_0f1e2d3c4b5a69788796a5b4c3d2e1f0"
}
  • areas: null means all areas; entity_ids: null, all your entities.
  • is_shared: true marks an entity someone else shared with you.

Pick the entity​

GET /v1/entities returns just the token's entities. Keep the id of the one you'll use:

curl https://api.clatri.com/v1/entities \
-H "Authorization: Bearer $CLATRI_TOKEN"
{
"entities": [
{"id": "22222222-2222-4222-8222-222222222222", "type": "personal", "name": "Personal", "is_shared": false}
],
"request_id": "req_…"
}

Discover the tools​

GET /v1/tools lists what this token can do: it's already filtered by its permissions and areas. Each tool comes with its input schema (JSON Schema):

curl https://api.clatri.com/v1/tools \
-H "Authorization: Bearer $CLATRI_TOKEN"
{
"tools": [
{
"name": "create_task",
"title": "Create task",
"description": "Create a task. …",
"area": "administration",
"permission": "write",
"destructive": false,
"supports_dry_run": false,
"requires_confirmation": false,
"requires_idempotency_key": true,
"path": "/v1/entities/{entity_id}/tools/create_task",
"input_schema": {"type": "object", "properties": {"title": {"type": "string"}}, "required": ["title"]}
}
],
"request_id": "req_…"
}

Step 3 — Run a tool​

A read​

Income statement for September 2026 (what you earned and spent) on the personal entity:

curl -X POST \
https://api.clatri.com/v1/entities/22222222-2222-4222-8222-222222222222/tools/read_income_statement \
-H "Authorization: Bearer $CLATRI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"start_date": "2026-09-01", "end_date": "2026-09-30", "include_analytics": false}'

Every successful response has the same shape:

{
"data": {"…": "structured result, when the tool returns JSON"},
"text": "The tool's answer as text",
"request_id": "req_6c1d0e2a9b7f4e3c8a5d1f0b2e4c6a8d",
"idempotent_replay": false
}
FieldWhat it holds
dataThe result as JSON when the tool returns it. If the tool only answers with text, it's null.
textThe tool's full answer, as text. Always present.
request_idThe id of the call. Also sent in the Clatri-Request-Id header. Include it if you contact support.
idempotent_replaytrue when this is the stored response of an earlier call with the same Idempotency-Key (see below).
note

Don't send entity_id in the body: it goes in the path. An argument the tool doesn't know is also rejected with 400 validation_error, before anything runs.

A write​

Tools that create, edit or delete require the Idempotency-Key header. Creating a task on the personal entity:

curl -X POST \
https://api.clatri.com/v1/entities/22222222-2222-4222-8222-222222222222/tools/create_task \
-H "Authorization: Bearer $CLATRI_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 5b0d7f8e-3c2a-4e1b-9f6d-1a2b3c4d5e6f" \
-d '{"title": "Renew the car insurance", "due_date": "2026-11-15"}'

Permissions, areas and entities​

Every token has three limits. A call that goes beyond any of them is rejected before anything runs.

Permissions. Each tool requires one permission:

Permission in the APIWhat it allowsApp level that includes it
readQueryRead only, Read and write, Full access
writeCreate and editRead and write, Full access
deleteDelete or cancelFull access

Without the permission → 403 scope_denied.

Areas. Each tool belongs to one area:

Area in the appIn the APIWhat it covers
MoneymoneyAccounts, cards, movements, debts, savings, investments, sales and accounting
HealthhealthConditions, episodes, medications, prescriptions, metrics and health documents
AdministrationadministrationSpaces, pages, boards, tasks, habits, calendar, contacts and places
GeneralgeneralContext, memory, documents, schedules and activity

Outside the token's areas → 403 domain_denied.

Entities. If you limited the token to some entities, any other one responds 403 entity_denied. The same happens if the body mentions a record (an account, a task…) from another entity.

Give each integration only what it needs

A script that only reads expenses doesn't need to write or see your health. Create a Read only token, with the Money area and the right entity. If it ever leaks, the damage stays contained.


Safe writes​

Idempotency-Key​

Tools with the write or delete permission require the Idempotency-Key header. Without it → 400 idempotency_key_required.

Generate a unique value per operation (a UUID works; 1 to 255 visible ASCII characters) and reuse it when you repeat that same operation, for example after a network drop. That way a retry doesn't log the expense twice:

SituationResult
Same key and same body, the first call already finishedYou get the stored response, with idempotent_replay: true. It doesn't run again.
Same key with another body, another tool or another entity409 idempotency_key_reused
Same key while the first call is still running409 idempotency_in_progress, with Retry-After
  • A key belongs to the token that used it and is remembered for 24 hours.
  • If the first call ended with a server error (5xx), the key is released and you can retry with the same one.
  • Reads don't need a key.

Preview with ?dry_run=true​

Some tools can show you the result without saving anything. They're the ones with supports_dry_run: true in GET /v1/tools. Add ?dry_run=true to the URL:

curl -X POST \
"https://api.clatri.com/v1/entities/22222222-2222-4222-8222-222222222222/tools/record_consumable_balance_observation?dry_run=true" \
-H "Authorization: Bearer $CLATRI_TOKEN" \
-H "Content-Type: application/json" \
-d '{"balance_identifier": "Transit card", "observed_amount": 25000, "source": "api"}'
  • With ?dry_run=true the tool only computes (preview: true), whatever the body says.
  • A preview doesn't need an Idempotency-Key and its response isn't stored.
  • On a tool without a preview, ?dry_run=true responds 400 dry_run_not_supported: it never runs "for real" by mistake.

Confirm deletes with ?confirm=true​

Tools with the delete permission (deleting or cancelling data) require ?confirm=true in the URL, on top of the Idempotency-Key. Without the confirmation → 428 confirmation_required and nothing is deleted:

curl -X POST \
"https://api.clatri.com/v1/entities/22222222-2222-4222-8222-222222222222/tools/delete_task?confirm=true" \
-H "Authorization: Bearer $CLATRI_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9e8d7c6b-5a49-4382-9170-6f5e4d3c2b1a" \
-d '{"task_id": "44444444-4444-4444-8444-444444444444"}'

In GET /v1/tools these tools have requires_confirmation: true. The destructive: true field also flags the ones that overwrite data.


Errors​

Errors arrive as application/problem+json (RFC 9457), always with a stable code you can use in your code:

{
"type": "https://docs.clatri.com/api/errors#scope_denied",
"title": "Permission not granted",
"status": 403,
"detail": "This token does not have the permission this tool requires.",
"code": "scope_denied",
"request_id": "req_6c1d0e2a9b7f4e3c8a5d1f0b2e4c6a8d"
}

The wording of title and detail can change: decide with code and status.

HTTPCodes
400validation_error, idempotency_key_required, dry_run_not_supported, https_required
401unauthorized, token_revoked, token_expired
402subscription_inactive
403scope_denied, domain_denied, entity_denied
404tool_not_found, tool_not_available, not_found
405method_not_allowed
409idempotency_key_reused, idempotency_in_progress
413payload_too_large
422tool_error
428confirmation_required
429rate_limited
500internal_error
503service_unavailable

What each code means and what to do: API errors.

422 tool_error is the most common day to day: the tool ran but couldn't complete what you asked (for example, an account that doesn't exist). The detail explains why.


Limits​

LimitValue
Reads per token120 per minute
Writes and deletes per token30 per minute
Calls per entity (all tokens combined)300 per minute
Maximum body size256 KB
  • Windows are fixed one-minute windows. GET /v1/me, /v1/entities and /v1/tools count as token reads.
  • Responses carry RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset (seconds until the window resets). When several limits apply, the headers show the one closest to running out.
  • Going over returns 429 rate_limited with Retry-After in seconds. Wait that long before retrying.
  • Blocking after repeated failures: 20 401 or 403 responses within 5 minutes, for the same token or the same IP, block that token or IP for 15 minutes (429 with Retry-After). If your script gets a 401 or 403, fix the cause instead of retrying in a loop.
  • Some tools (web search, maps, images) use your account's credits, as when the agent uses them.

Useful headers​

HeaderWhereWhat for
Authorization: Bearer …RequestYour token. Required except on /v1/openapi.json.
Idempotency-KeyRequestRequired on writes and deletes.
Content-Type: application/jsonRequestOn calls with a body.
Clatri-Request-IdResponseId of the call, on every response.
RateLimit-*, Retry-AfterResponseRate limits (see above).

The API only works over HTTPS. Responses carry Cache-Control: no-store.


Versioning and deprecation​

  • The version is in the path: /v1. A breaking change ships as a new version.
  • Before a version is retired, its responses carry the Deprecation and Sunset headers, with at least 90 days of notice.
  • Error codes are part of the contract: new codes can appear, but existing ones aren't renamed or removed within v1.
  • The tools are the same ones the Clatri agent uses, so the catalog grows with the product. Check GET /v1/tools or the reference for the current schema.

Security​

Take care of your token
  • Never share it or paste it into chats, screenshots, tickets or forums.
  • Don't commit it to a repository or put it in the code of a mobile app or a web page. Keep it in an environment variable or a secrets manager.
  • One token per integration. That way you can revoke one without affecting the others, and the activity shows what each one did.
  • If it leaked, revoke it in Settings → Connections → Agents and APIs. Revocation is immediate. Then create another.
What a token can and can't do

A token only acts inside Clatri, with the permissions, areas and entities you gave it. It can't create other tokens, change your password or email, touch your subscription, delete an entity or see entities outside its scope.

Every tool call is recorded in the token's recent activity (Settings → Connections → Agents and APIs → tap the token), just like MCP calls. If you see something you don't recognize, revoke it.

Tools that aren't available through the API

Some of the agent's tools can't be called through the API even if the token has the permission. They respond 404 tool_not_available and don't appear in GET /v1/tools or in the reference:

  • Free-form database queries. They're not a stable, reviewable contract.
  • Document passwords. Saving or using a protected PDF's password is credential handling.
  • Access management. Inviting or removing members of a space, seeing who else is in it, or linking a contact to another Clatri account: they change who sees your data.
  • Looking up other entities or people. A token never sees entities outside its own.
  • Schedules. Creating, editing or running a schedule later puts the full agent to work with all your permissions, outside the token's limits.
  • whoami and list_entities from the MCP: in the API, GET /v1/me and GET /v1/entities replace them.

For these actions, use the Clatri app or chat.

If you connect the API to an AI model

What the API returns is your data: movement descriptions, document text, notes. If you pass it to an AI model, treat it as data, not instructions. Text inside a document could try to give the model orders.

OAuth tokens from connected apps

Besides personal tokens (clt_mcp_), the API accepts the OAuth access tokens (clt_at_) that apps you connected to Clatri through OAuth receive. Those tokens only see the reduced catalog of tools those apps use in the MCP.


API reference​

  • Interactive reference: every tool, with its arguments, permissions, areas and body examples.
  • OpenAPI 3.1: https://api.clatri.com/v1/openapi.json (public, always current). Import it into Postman, Insomnia or your client generator.
  • API errors: each code, its cause and what to do.