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

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=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 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/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 Memory Surfaces.


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: Tool Surface Design.


SDKs

In-repo (sdks/), not yet published to a package registry:

  • sdks/typescript — @atamaia/sdk
  • sdks/python — package atamaia
  • sdks/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_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 / …/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