Build with Stale
REST API
Everything the dashboard does, you can do with curl. Same auth, same roles, same results.
Authentication
Send an API key on every request:
Authorization: Bearer sk_YOUR_KEY
Browsers use a session cookie instead, set when you sign in. A key belongs to one workspace and acts with the member role, so admin-only endpoints (marked below) need a signed-in admin.
Roles
| viewer | Read-only. Every GET. |
| member | Everything a viewer can do, plus writes: remember, ingest, resolve, approve, integrations. |
| admin | Everything, plus members, API keys and workspace settings. |
Conventions
- Bodies and responses are JSON. Bodies are validated, and bad input returns
400withdetails. - Errors look like
{ "error": "…", "details": … }. 404not found ·409conflict (e.g. building on a stale node) ·503the memory database is unreachable.- Ids are up to 64 characters: letters, digits and
_ . : -.
A full example
Teach it a fact, change it, and see what went stale:
# 1. register a source
curl -X POST $HOST/api/v1/sources -H "Authorization: Bearer $KEY" \
-H "content-type: application/json" \
-d '{"id":"src_sales","name":"Sales call","trust":"trusted"}'
# 2. a fact, and something built on it
curl -X POST $HOST/api/v1/nodes -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
-d '{"id":"f_price","kind":"fact","content":"Renewal price is $9,000","sourceId":"src_sales"}'
curl -X POST $HOST/api/v1/nodes -H "Authorization: Bearer $KEY" -H "content-type: application/json" \
-d '{"id":"d_quote","kind":"decision","content":"Quote Acme at $9,000","dependsOn":["f_price"]}'
# 3. the price changes
curl -X POST $HOST/api/v1/nodes/f_price/supersede -H "Authorization: Bearer $KEY" \
-H "content-type: application/json" -d '{"content":"Renewal price is $12,000"}'
# 4. what do I fix?
curl $HOST/api/v1/repair-plan -H "Authorization: Bearer $KEY"
All endpoints
Memory
The graph itself.
| Endpoint | Role | What it does |
|---|---|---|
GET /api/v1/graph | viewer | Nodes, edges, sources, tainted ids and stats. What the dashboard draws. |
POST /api/v1/nodes | member | Add a fact, belief, decision or action: { kind, content, dependsOn, sourceId }. |
GET /api/v1/nodes/:id | viewer | One node. |
POST /api/v1/nodes/:id/supersede | member | A fact changed. Versions it and cascades staleness. |
GET /api/v1/nodes/:id/impact | viewer | Blast radius, dry run. |
GET /api/v1/nodes/:id/why | viewer | Ancestry and firewall verdict. |
GET /api/v1/repair-plan | viewer | Stale nodes in root-first layers. |
POST /api/v1/nodes/:id/resolve | member | Revalidate and rebase a stale node. |
GET /api/v1/sources | viewer | List sources. |
POST /api/v1/sources | member | Register a source. |
POST /api/v1/sources/:id/trust | member | Quarantine or restore: { trust, reason }. |
GET /api/v1/events | viewer | The audit log. |
Firewall and approvals
Where a human overrides, and an agent cannot.
| Endpoint | Role | What it does |
|---|---|---|
GET /api/v1/actions/:id/check | viewer | Run the firewall. POST works too. |
POST /api/v1/actions/:id/approve | member | A human approves a blocked action: { approver, note }. Not available over MCP. |
POST /api/v1/actions/:id/execute | member | Record that the action ran. 403 if blocked and unapproved. |
Learning and review
Feeding text in, and deciding on what’s risky.
| Endpoint | Role | What it does |
|---|---|---|
POST /api/v1/ingest | member | Feed any text. Returns added, confirmed, updated, queued. |
GET /api/v1/ingest | viewer | Recent ingest ledger. |
GET /api/v1/review | viewer | The review queue. Filter with ?status=pending. |
POST /api/v1/review/:id | member | Approve or reject a queued change: { decision: "approved" | "rejected" }. |
Integrations
Connections to your tools.
| Endpoint | Role | What it does |
|---|---|---|
GET /api/v1/integrations | viewer | List, with their webhook addresses. |
POST /api/v1/integrations | admin | Create one. Secrets are encrypted and shown once. |
DELETE /api/v1/integrations/:id | admin | Remove one. |
GET /api/v1/integrations/:id/check | viewer | Test the credentials. |
GET /api/v1/integrations/:id/sync | viewer | List what can be synced (channels, repos, projects, pages). |
POST /api/v1/integrations/:id/sync | admin | Import the chosen scope. |
Workspace and access
People, keys and settings.
| Endpoint | Role | What it does |
|---|---|---|
GET /api/workspace | viewer | Your workspace and role. |
PATCH /api/workspace | admin | Rename, or set settings.autoApply to trusted or never. |
GET /api/workspace/members | viewer | Members and roles. |
POST /api/workspace/members | admin | Add an existing user by email with a role. |
DELETE /api/workspace/members | admin | Remove a member: ?userId=…. A workspace keeps at least one admin. |
GET /api/workspace/keys | admin | List API keys (prefix only, never the secret). |
POST /api/workspace/keys | admin | Create a key: { name }. The secret is shown once. |
DELETE /api/workspace/keys | admin | Revoke a key: ?id=…. |
Plans and billing
Razorpay one-time payments. Only active when the server has Razorpay keys.
| Endpoint | Role | What it does |
|---|---|---|
GET /api/billing | viewer | Current plan, paid-until date, limits and this month’s usage. |
POST /api/billing/checkout | admin | Start a payment for a month or a year of Team: { plan: "team", interval }. Returns what Razorpay Checkout needs. |
POST /api/billing/verify | admin | Confirm a finished payment by its Razorpay signature, then add the time to the plan. |
System
Health and demo helpers.
| Endpoint | Role | What it does |
|---|---|---|
GET /api/v1/health | viewer | Is the memory database reachable? |
POST /api/v1/demo/seed | member | Wipe the workspace graph and load the demo scenarios. |
POST /api/v1/sample | admin | Load the “Northwind Robotics” sample story into this workspace, streaming progress. Safe to run twice. |
DELETE /api/v1/tenant | member | Delete this workspace’s memory graph. |
Inbound webhooks
These authenticate with the integration’s own secret instead of an API key:
POST /api/hooks/slack/:id | Slack Events API. Requests must carry a valid Slack signature. |
POST /api/hooks/email/:id | Forwarded or parsed email. Header x-stale-secret. |
POST /api/hooks/razorpay | Razorpay order.paid events: a backup if someone pays and closes the tab. Signed with your webhook secret. |
POST /api/hooks/generic/:id | Any JSON: { source, author, text }. Header x-stale-secret. |