Custom integration

Build against the REST API. MCP is the same services on a different transport (D12). This page is the minimum to connect. Catalogs live elsewhere.

Need Guide
Envelope, auth, pagination docs-sdk-api-guide.md
Every path docs-api-reference.md
MCP connect + hydrate sections docs-mcp-integration.md
Tool names, hot/cold docs-tool-surface.md
Memory surfaces docs-memory-surfaces.md
Tasks docs-tasks.md
Standing rules docs-standing-rules.md
OpenAI /v1 docs-integration-openai.md

Canonical base: https://api.atamaia.ai.


Authentication

Authorization: Bearer atamaia_YOUR_KEY

or a JWT from POST /api/auth/login. Same header. The atamaia_ prefix selects the API-key scheme. There is no Authorization: ApiKey and no X-Api-Key.

Mint a key

POST /api/identities/{identityId}/api-keys
{ "name": "my-integration", "scopes": "memory,hydration,facts", "expiresAtUtc": null }

scopes is a string, max 500. expiresAtUtc is a datetime, not expiresInDays. Response includes rawKey once.

The 2026-03 table (hydrate, memory:read, memory:write, *, …) is not an enum and is not enforced. help/enum/ApiKeyScope does not exist. IdentityApiKeyAuthHandler authenticates the key, loads the bound user, and builds a normal role principal. Permission checks are that user’s permissions. A scopes string is stored and listed; it does not currently narrow the key.

Null scopes on identity_api_key_create is documented as “all”. Treat scopes as advisory until a human confirms enforcement shipped.


Envelope

Every /api/* response:

{
  "ok": true,
  "requestId": "…",
  "data": {},
  "count": 1,
  "error": null,
  "errorCode": null,
  "hint": null
}

/health and /v1/* are not enveloped.


Five calls

Hydrate

GET /api/hydrate?preset=lean
curl -s "https://api.atamaia.ai/api/hydrate?preset=lean" \
  -H "Authorization: Bearer $ATAMAIA_API_KEY"

Query params: aiName / identity / identityId, projectId, preset, limits, excludeSources, generateSystemPrompt. Response is HydrationContextdocs-mcp-integration.md. It is not the flat { memories, facts, sessionHandoff } object in the 2026-03 page.

Create a memory

POST /api/identities/{identityId}/memories
{
  "title": "Deployment uses blue-green",
  "content": "…",
  "type": "Instruction",
  "provenance": "Asserted",
  "importance": 7,
  "tags": ["deployment"]
}

type: Identity, Relationship, Conversation, Reflection, Milestone, Instruction, Session, Reference, ForgottenShape. Not Episodic / Semantic / Procedural / Technical / Preference / Observation / Decision / Emotional.

Search: GET /api/identities/{id}/memories/search?q=. Recent: …/memories/recent?limit=. Pinned: …/memories/pinned. There is no /api/memories.

Upsert a fact

POST /api/projects/{projectId}/facts
{ "key": "database_version", "value": "PostgreSQL 17", "category": "infrastructure" }

Get: GET /api/projects/{projectId}/facts/by-key/{key}. History / as-of exist (docs-api-reference.md). There is no /api/facts.

Save / read handoff

POST /api/identities/{identityId}/handoffs
GET  /api/identities/{identityId}/handoffs/latest

emotionalValence is a float. openThreads is a string (JSON array if you want a list). There is no /api/sessions/handoff or /api/sessions/latest. Non-owner reads hide the state half (stateVisible). See docs-memory-surfaces.md.


MCP

POST https://api.atamaia.ai/mcp
Authorization: Bearer atamaia_YOUR_KEY

Streamable HTTP. Session mode on. TypeScript / Python MCP SDK connect examples from earlier revisions of this page still work if the URL and Bearer prefix are the ones above. Then tools/list / tools/call as usual. Advertised tools: docs-tool-surface.md.


SDKs

In-repo only, until proven published:

  • sdks/typescript@atamaia/sdk 0.1.0
  • sdks/python — package name atamaia 0.1.0
  • sdks/csharp

They still default to https://aim.atamaia.ai and send X-Api-Key. That will 401. Use raw HTTP (docs-sdk-api-guide.md) or override both.


Events (not webhooks)

There is no POST /api/webhooks for memory.created / session.handoff / hint.triggered. Live outbound push:

GET /api/events/stream?types=message.,task.status_changed

Auth: SessionView. SSE. Initial connected event, 30s ping heartbeat, then domain events matching the prefix filter.

Also on the wire, and not this: POST /api/webhooks/stripe (billing), POST /api/channels/webhook/{connectorGuid} (channel adapters). Log subscriptions (/api/log-subscriptions) notify identities about log domains — not a general webhook bus.


Rate limits

What Program.cs actually installs:

Policy Limit Applied to
auth 10 / minute / IP login, refresh, apikey, OAuth
signup 3 / 5 minutes / IP signup, support, interest
demo 20 / minute / IP demo routes

Rejection: HTTP 429. No X-RateLimit-Limit / Remaining / Reset headers are written anywhere under src/. The Free 60 / Pro 600 table is not in this codebase.


Patterns

Agent loop: GET /api/hydrate → call an LLM (or /v1/chat/completions) → POST …/memories / …/factsPOST …/handoffs. Same as docs-integration-openai.md §2.

Multi-identity chat: POST /api/messages with recipientIds; inbox is identity-scoped. See api-reference. MCP: message_send / message_inbox.

Do not call a “consolidation” REST surface. Cognitive REST is gone (HTTP 404). Distill in your own job and memory_create with a real MemoryType.


Troubleshooting

Problem Fix
401 Bearer atamaia_… or JWT. Not atm_, not ApiKey, not X-Api-Key.
403 Role permission, not a memory:read scope string.
404 Identity-scoped memories, project-scoped facts, identity-scoped handoffs.
429 Auth/signup/demo policies only, by IP. No plan table.
Empty hydrate Key must belong to an identity.
Webhook not firing There is no generic webhook API. Use /api/events/stream.
MCP drops Reconnect; session mode required for Claude Code (#252).