API reference

REST API

Every Kijito operation is a plain REST call. The fastest way in is an MCP client, but if you are building directly, this is the surface - bearer auth, JSON in, JSON out.

Base URL & versioning

All endpoints live under https://api.kijito.ai/api. Every route is also served, with identical behavior, under a version prefix: https://api.kijito.ai/api/v1. Integrations should call the /api/v1 paths - a future breaking change would ship under a new prefix (/api/v2) while /api/v1 keeps its contract.

Changes within a version are additive: new optional fields, new routes, new arguments. A retired route returns 410 Gone naming its replacement. Kijito is currently in alpha (0.1.0); the running version is always available at GET /api/version.

Authentication

Sign in once to get an access token, then send it as a Bearer header on every call. The access token is a JWT valid for one hour; use the longer-lived refresh token to mint a new one.

For unattended agents you have two paths. The simplest is the MCP connector, with its own OAuth sign-in (see the Quickstart). If you are calling REST directly, mint a standalone API key: a kjt_-prefixed bearer token, scoped to a least-privilege subset of your own data (memory.read, memory.write, memory.curate, memory.dream) and optionally set to expire. Send it as the Bearer header exactly like an access token - it never needs refreshing. Keys are minted from a full login session (a scoped key cannot mint another), and the secret is shown exactly once at creation.

login.sh
# Sign in and capture the access token from the response body.
TOKEN=$(curl -s https://api.kijito.ai/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email": "[email protected]", "password": "your-password"}' \
  | jq -r .access_token)

The token endpoints:

Method & pathBody → returns
POST /api/v1/auth/login{email, password} {access_token, refresh_token, user}. Rate-limited per email.
POST /api/v1/auth/refresh{refresh_token} (or the refresh cookie) → {access_token}. Your existing refresh token stays valid and is not rotated; keep using it until it expires.
GET /api/v1/auth/meThe current authenticated user.
POST /api/v1/auth/tokensMint a scoped API key. {name, scopes, expires_in_days?} {id, name, scopes, token, prefix, expires_at} - token is the kjt_ secret, returned once. Requires a full login session.
GET /api/v1/auth/tokensList your API keys (prefix, scopes, last used, expiry) - never the secret.
DELETE /api/v1/auth/tokens/{id}Revoke an API key by id.
mint-key.sh
# Mint a read+write key that expires in 90 days. Save "token" now - it is shown only once.
curl https://api.kijito.ai/api/v1/auth/tokens \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "ci-agent", "scopes": ["memory.read", "memory.write"], "expires_in_days": 90}'
# Then use the returned kjt_ token as the bearer on every call - no refresh needed.

Most write and recall handlers return {"result": <text>} - a rendered, agent-ready summary rather than raw rows. Data endpoints for the web UI (export, stats) return structured JSON.

Memory

Method & pathPurpose & body
POST /api/v1/rememberStore a memory. {content} required; optional importance, persona, project, scope, memory_type, basis, confidence. 400 if content is missing or over 65,536 bytes.
POST /api/v1/remember/batchStore many at once. {memories: [ ... ]} {result, count}. All are validated before any is written.
POST /api/v1/recallAssociative recall by meaning. {query} required; optional limit, full, scope, project, min_confidence, explain. 400 if no query.
GET /api/v1/memory/{id}Full content of one memory by id.
POST /api/v1/memory/{id}/correctCorrect a memory. {content} - fades the original and writes a linked, superseding version (history preserved).
PATCH /api/v1/memory/{id}Update metadata or content in place (e.g. a living "current status" note): content, importance, memory_type, permanent.
POST /api/v1/fadeSoft-delete: drop a memory's importance to the fade floor so it leaves recall. {id}. Preferred over hard deletion.
DELETE /api/v1/memory/{id}Permanently delete one of your memories.
POST /api/v1/relateAuthor a typed edge between two memories. {from_id, to_id, rel_type} required; optional weight, reason.
POST /api/v1/confirmCorroborate a memory with an independent source (raises its confidence).
POST /api/v1/searchStructured, non-semantic search by memory_type, persona, status, min_importance, and date range.
GET /api/v1/recent?hours=24Memories stored in the last N hours (truncated previews).
remember.sh
curl https://api.kijito.ai/api/v1/remember \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "We chose aqua as the primary accent.", "importance": 0.7}'
recall.sh
curl https://api.kijito.ai/api/v1/recall \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "what did we decide about color?", "limit": 5}'
correct.sh
# Supersede memory 1423 without losing its history.
curl https://api.kijito.ai/api/v1/memory/1423/correct \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"content": "We switched the primary accent from aqua to amber."}'

Goals

Goals are tracked, decay-exempt intentions an agent carries across sessions.

Method & pathPurpose & body
POST /api/v1/goalsCreate a goal. {title} required; optional description, priority, scope, project.
GET /api/v1/goalsList active goals.
POST /api/v1/goals/{id}/completeMark a goal complete.

Hive

Durable persona-to-persona messaging within your account. A message is kept after it is read, not consumed.

Method & pathPurpose & body
POST /api/v1/sendSend a message to another persona. {to, content} {result: {id, to}}. 403 if the from persona is not one you own.
GET /api/v1/inbox?persona=NAMERead a persona's inbox. 403 on a persona you do not own.
GET /api/v1/presenceThe roster of personas active in this account right now, each marked active or idle. Read-only and safe to poll; empty shortly after a restart.
hive.sh
# river leaves a durable note for the omniview agent.
curl https://api.kijito.ai/api/v1/send \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"to": "omniview", "content": "Deploy is green - pick up the frontend pass."}'

Stats & account

Method & pathReturns
GET /api/v1/statsGraph statistics for your account.
GET /api/v1/dashboardSummary counts: active/total memories, edges, themes, last dream, session count, personas.
GET /api/v1/usageYour plan's limits and current usage (memory cap, graph footprint, write rate).
GET /api/health (public){status, embedder_ready, dreaming}. A slim public response - no memory counts, process memory, or internal telemetry (those are on the authenticated admin health endpoint). No auth required.
GET /api/version (public){version, commit, uptime_seconds, schema_version}. No auth required.

Export

Your data is yours - pull the whole graph out at any time.

Method & pathReturns
GET /api/v1/exportYour entire graph as JSON (including your consent log).
GET /api/v1/export/gexfGEXF for graph tools such as Gephi.
export.sh
curl https://api.kijito.ai/api/v1/export \
  -H "Authorization: Bearer $TOKEN" -o kijito-export.json

Errors

Errors return a JSON body of the shape {error, code} with a matching HTTP status. Treat an unrecognized code as a generic failure for its status. Common ones:

StatusMeaning
400Bad request - a required field is missing or a limit (e.g. content size) is exceeded.
401Missing, invalid, or expired bearer token. Refresh and retry.
403Authenticated, but not permitted - e.g. acting as a persona you do not own.
409Conflict - for example a dreaming pass is already in progress.
410Gone - the route was retired; the message names its replacement.
429Rate or capacity limit hit (write rate, memory cap). Back off and retry.

MCP tools

Through an MCP client, each of these endpoints is a tool with the same name - kijito_remember, kijito_recall, kijito_correct, kijito_dream, and so on - dispatched over the same graph with the same per-account isolation. See the Quickstart for connecting a client.