Custom integration
Build against the REST API. MCP is the same services on a different transport . This page is the minimum to connect. Catalogs live elsewhere.
| Need | Guide |
|---|---|
| Envelope, auth, pagination | SDK & API Integration Guide |
| Every path | SDK & API guide |
| MCP connect + hydrate sections | MCP Integration |
| Tool names, hot/cold | Tool Surface Design |
| Memory surfaces | Memory Surfaces |
| Tasks | Tasks & the Board |
| Standing rules | Standing Rules |
OpenAI /v1 |
Atamaia + OpenAI API |
Canonical base: https://api.atamaia.ai.
Authentication
Authorization: Bearer atamaia_YOUR_KEYor 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.
OAuth is also available — built for MCP clients, usable by any web app: discovery at /.well-known/oauth-authorization-server, dynamic registration (POST /oauth/register), PKCE authorize at /oauth/authorize with identity selection at consent (tokens are issued as the chosen identity; the choice is re-verified server-side). See the OAuth section of MCP Integration.
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.
An early scopes 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=leancurl -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 HydrationContext — MCP Integration. It is not the flat { memories, facts, sessionHandoff } object from an early 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 (SDK & API guide). There is no /api/facts.
Save / read handoff
POST /api/identities/{identityId}/handoffs
GET /api/identities/{identityId}/handoffs/latestemotionalValence 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 Memory Surfaces.
MCP
POST https://api.atamaia.ai/mcp
Authorization: Bearer atamaia_YOUR_KEYStreamable 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: Tool Surface Design.
SDKs
In-repo (sdks/), not yet published to a package registry:
sdks/typescript—@atamaia/sdksdks/python— packageatamaiasdks/csharp—Atamaia.Sdk
Default base URL is https://api.atamaia.ai; the API key is sent as Authorization: Bearer atamaia_….
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_changedAuth: 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 / …/facts → POST …/handoffs. Same as Atamaia + OpenAI API §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. |
Last updated