Documentation
API reference, MCP tools, and integration guides.
Get an API Key
Every snippet below expects a nams_... key. Replace the placeholder with your own.
Sign in to open your workspace - a default key is created for you, and the in-console Quick Start fills it into every snippet automatically. Or generate one on the API Keys page. Keys expire after 90 days.
REST: Make your first call
API keys work as Bearer tokens directly - no exchange step needed.
List entities
curl http://localhost:8080/v1/entities \ -H "Authorization: Bearer nams_YOUR_API_KEY"
1. Create a conversation
curl -X POST http://localhost:8080/v1/conversations \
-H "Content-Type: application/json" \
-H "Authorization: Bearer nams_YOUR_API_KEY" \
-d '{"userId": "user-1"}'
# Response: {"id": "conv-abc-123", ...}2. Add a message
curl -X POST http://localhost:8080/v1/conversations/CONV_ID/messages \
-H "Content-Type: application/json" \
-H "Authorization: Bearer nams_YOUR_API_KEY" \
-d '{"role": "user", "content": "John works at Acme Corp in Denver"}'3. Check extracted entities
curl http://localhost:8080/v1/entities \ -H "Authorization: Bearer nams_YOUR_API_KEY" # Returns entities extracted from your messages: # John (person), Acme Corp (organization), Denver (location)
Connect your agent
Install the nams-hooks plugin for your agent CLI - memory turns on automatically, with no manual MCP config. The agent gets all the NAMS memory, ontology, and workspace tools.
Installs nams-hooks as a Claude Code plugin. The plugin bundles the runtime, hook config, and a credential prompt for your API key.
claude plugin marketplace add neo4j-labs/nams-plugins@latest claude plugin install nams-hooks@nams-plugins
Then configure and reload it inside Claude Code:
/plugin configure nams-hooks@nams-plugins /reload-plugins
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
/nams-hooks:nams:workspace use <workspace-id-or-name>Installs nams-hooks as a Gemini extension from the latest release.
gemini extensions install https://github.com/neo4j-labs/nams-plugins --ref latest
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
/nams:workspace use <workspace-id-or-name>Adds the nams-plugins marketplace. Restart Codex, open /plugins, install “NAMS Hooks”, then /hooks to trust the bundled hooks.
codex plugin marketplace add neo4j-labs/nams-plugins@latest codex plugin marketplace list
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
$nams:workspace use <workspace-id-or-name>Installs the npm package and drops the hook shim into your project's .opencode/plugins.
npm install -g @neo4j-labs/nams-plugins cp "$(npm root -g)/@neo4j-labs/nams-plugins/templates/opencode/.opencode/plugins/nams-hooks.js" \ .opencode/plugins/nams-hooks.js
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
nams-hooks workspaces configure opencode --scope session --session-id <id> --workspace <name>Prefer a raw MCP client config (Claude Desktop, Cursor, Windsurf…)? See the Plugins or MCP Tools tab.
Prefer OAuth 2.0?
MCP clients that support OAuth can authenticate interactively with PKCE - no static key to manage. Discovery endpoints:
# Protected Resource Metadata (RFC 9728) http://localhost:9090/mcp/.well-known/oauth-protected-resource # Authorization Server Metadata (RFC 8414) http://localhost:9090/mcp/.well-known/oauth-authorization-server # Dynamic Client Registration (RFC 7591) POST http://localhost:9090/mcp/oauth/register
Access tokens are short-lived (1 hour); clients refresh automatically.
Base URLs
| API | http://localhost:8080/v1 |
| Auth | http://localhost:8080/v1/auth |
| MCP | http://localhost:9090/mcp |
Agent CLI plugins
The nams-hooks plugin wires NAMS memory straight into your agent CLI - every turn is captured and recalled automatically, no manual MCP config. One package supports Claude Code, Gemini CLI, Codex, and OpenCode.
Prerequisites: Node.js 20+, a NAMS API key, and a base URL (http://localhost:8080). A workspace ID is optional - with a single workspace the plugin auto-selects it.
Install
Pick your agent below. Each tab has the install command plus how to select a workspace.
Installs nams-hooks as a Claude Code plugin. The plugin bundles the runtime, hook config, and a credential prompt for your API key.
claude plugin marketplace add neo4j-labs/nams-plugins@latest claude plugin install nams-hooks@nams-plugins
Then configure and reload it inside Claude Code:
/plugin configure nams-hooks@nams-plugins /reload-plugins
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
/nams-hooks:nams:workspace use <workspace-id-or-name>Installs nams-hooks as a Gemini extension from the latest release.
gemini extensions install https://github.com/neo4j-labs/nams-plugins --ref latest
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
/nams:workspace use <workspace-id-or-name>Adds the nams-plugins marketplace. Restart Codex, open /plugins, install “NAMS Hooks”, then /hooks to trust the bundled hooks.
codex plugin marketplace add neo4j-labs/nams-plugins@latest codex plugin marketplace list
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
$nams:workspace use <workspace-id-or-name>Installs the npm package and drops the hook shim into your project's .opencode/plugins.
npm install -g @neo4j-labs/nams-plugins cp "$(npm root -g)/@neo4j-labs/nams-plugins/templates/opencode/.opencode/plugins/nams-hooks.js" \ .opencode/plugins/nams-hooks.js
Set NAMS_API_KEY (and NAMS_BASE_URL=http://localhost:8080) via the plugin's credential prompt, ~/.nams/config.json, or environment variables. Then pick a workspace:
nams-hooks workspaces configure opencode --scope session --session-id <id> --workspace <name>Configuration
Runtime config is JSON-first. Drop a user-local ~/.nams/config.json (or a project-local .nams/config.json):
{
"apiKey": "nams_...",
"workspaceId": "<workspace-id>",
"baseUrl": "http://localhost:8080"
}Environment variables (final overrides)
NAMS_API_KEY · NAMS_WORKSPACE_ID · NAMS_BASE_URL
Keep any file containing an API key gitignored. Prefer a manual MCP client config instead? See the MCP Tools tab. Full docs live in the nams-plugins repo.
Paste your API key in any endpoint's "Try it" panel to run requests against your workspace.
Authentication
Auth service base URL: https://nams.development.neo4jsandbox.com Returns the public RSA key(s) used to verify NAMS JWTs. Used by other services for token validation.
curl
curl 'http://localhost:8080/.well-known/jwks.json' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
JWKS format public key set
Auth service base URL: https://nams.development.neo4jsandbox.com List API keys owned by the authenticated user. Raw key values are never returned - only metadata (ID, label, created/revoked/expiry timestamps). Auth: requires a user token or an Admin API key (workspace:admin); workspace-bound data keys and MCP OAuth tokens are rejected with 403.
curl
curl 'http://localhost:8080/v1/auth/api-keys' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns keys array with id, label, createdAt, revokedAt, expiresAt
{
"keys": [
"..."
]
}No user in token
{
"error": "No user in token"
}Requires a user token or an Admin API key
{
"error": "Requires a user token or an Admin API key"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Generate a new API key owned by the authenticated user. The category selects the key's privilege and binding: "workspace" requires a workspaceId and produces a data-plane key bound to that workspace (scopes derived server-side, never workspace:admin); "admin" forbids workspaceId and produces an account-wide key with full scopes. Category defaults to "admin" when omitted. The raw key is returned once and also stored encrypted-at-rest for later reveal; it is bcrypt-validated on every request. Auth: requires a user token or an Admin API key (workspace:admin); workspace-bound data keys and MCP OAuth tokens are rejected with 403.
Request Body
{
"category": "string",
"label": "string",
"workspaceId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/auth/api-keys' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"label": ""
}'Responses
Key ID, raw key (save this), and label
{
"category": "string",
"id": "string",
"key": "string",
"label": "string",
"workspaceId": "string"
}Missing required fields
{
"error": "Missing required fields"
}No user in token
{
"error": "No user in token"
}Requires a user token or an Admin API key
{
"error": "Requires a user token or an Admin API key"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Revoke an API key by ID. The key is immediately invalidated - any active JWTs issued from it are blocklisted. This action is irreversible. Owner-only: only the user who owns the key can revoke it. Non-owners receive 404 (indistinguishable from a missing key) to prevent key-id enumeration. Auth: requires a user token or an Admin API key (workspace:admin); workspace-bound data keys and MCP OAuth tokens are rejected with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | API key ID |
curl
curl -X DELETE 'http://localhost:8080/v1/auth/api-keys/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns status: revoked
{
"status": "success"
}No user in token
{
"error": "No user in token"
}Requires a user token or an Admin API key
{
"error": "Requires a user token or an Admin API key"
}Key not found or not owned by caller
{
"error": "Key not found or not owned by caller"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Returns the decrypted raw API key value for keys created with encrypted storage. Owner-only: only the user who owns the key can reveal it. Non-owners receive 404 (indistinguishable from a missing key) to prevent credential disclosure and key-id enumeration. Returns 403 if the key grants a scope the calling credential does not hold (an identity-provider session is not limited this way), and 410 if the key was revoked or predates encrypted storage. Auth: requires a user token or an Admin API key (workspace:admin); workspace-bound data keys and MCP OAuth tokens are rejected with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | API key ID |
curl
curl 'http://localhost:8080/v1/auth/api-keys/{id}/reveal' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Key ID and decrypted raw key
{
"id": "string",
"key": "string"
}No user in token
{
"error": "No user in token"
}Requires a user token or an Admin API key, or the key is wider than the credential
{
"error": "Requires a user token or an Admin API key, or the key is wider than the credential"
}Key not found or not owned by caller
{
"error": "Key not found or not owned by caller"
}Key revoked or not revealable
{
"error": "Key revoked or not revealable"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Mint a new API key inheriting the old key's label and scopes, and atomically revoke the old one. The new raw key is returned exactly once in the response (and is also persisted encrypted-at-rest so it can be revealed again later). Owner-only: only the user who owns the key can rotate it. Non-owners receive 404 (indistinguishable from a missing key) to prevent key-id enumeration. Returns 403 if the key grants a scope the calling credential does not hold (an identity-provider session is not limited this way), and 410 if the key is revoked or expired. Auth: requires a user token or an Admin API key (workspace:admin); workspace-bound data keys and MCP OAuth tokens are rejected with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | API key ID to rotate |
curl
curl -X POST 'http://localhost:8080/v1/auth/api-keys/{id}/rotate' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
New key ID, new raw key (save this), and inherited label
{
"id": "string",
"key": "string",
"label": "string"
}No user in token
{
"error": "No user in token"
}Requires a user token or an Admin API key, or the key is wider than the credential
{
"error": "Requires a user token or an Admin API key, or the key is wider than the credential"
}Key not found or not owned by caller
{
"error": "Key not found or not owned by caller"
}Key is revoked or expired
{
"error": "Key is revoked or expired"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Validate an access token of the deployment's OpenID Connect identity provider and return the caller's workspaces. Creates the user on first login, backfills email and name from an optional id_token, auto-provisions a default workspace, and mints the user's database API key. By default each workspace also carries a per-workspace NAMS JWT; pass {"no_mint": true} in the body to receive workspace ids alone, which is what the dashboard does now that the proxy forwards the identity-provider token directly.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Authorization | header | string | required | Identity-provider Bearer token |
Request Body
{
"id_token": "string",
"no_mint": false
}curl
curl -X POST 'http://localhost:8080/v1/auth/exchange' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Returns workspaces array with workspace_id and token
{
"workspaces": [
"..."
]
}Invalid or missing token
{
"error": "Invalid or missing token"
}Internal error
{
"error": "Internal error"
}No identity provider configured
{
"error": "No identity provider configured"
}Auth service base URL: https://nams.development.neo4jsandbox.com List the MCP applications the user approved on the consent page, with the workspace and scopes of each approval. Auth: requires a console session; API keys and MCP OAuth tokens are rejected with 403.
curl
curl 'http://localhost:8080/v1/auth/oauth-grants' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"grants": [
"..."
]
}Requires a console session
{
"error": "Requires a console session"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Delete the user's approval of an MCP application. Its refresh tokens stop working, and it must ask for consent again. Access tokens it already holds stay valid until they expire (at most one hour). Auth: requires a console session; API keys and MCP OAuth tokens are rejected with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
clientId | path | string | required | OAuth client ID |
curl
curl -X DELETE 'http://localhost:8080/v1/auth/oauth-grants/{clientId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
No Content
Requires a console session
{
"error": "Requires a console session"
}No approval for this application
{
"error": "No approval for this application"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Handles OAuth2 authorization code flow. Exchanges the provider code for user info and returns a NAMS JWT. Currently returns 501 - implementation pending.
Request Body
{
"code": "string",
"provider": "string"
}curl
curl -X POST 'http://localhost:8080/v1/auth/oauth/callback' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"code": "",
"provider": ""
}'Responses
JWT token (when implemented)
Not implemented
{
"error": "Not implemented"
}Auth service base URL: https://nams.development.neo4jsandbox.com Exchange a refresh token for a new access token and rotated refresh token.
Request Body
{
"refresh_token": "string"
}curl
curl -X POST 'http://localhost:8080/v1/auth/refresh' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"refresh_token": ""
}'Responses
New access and refresh tokens
{
"refresh_token": "string",
"token": "string"
}Invalid request
{
"error": "Invalid request"
}Invalid or expired refresh token
{
"error": "Invalid or expired refresh token"
}Internal error
{
"error": "Internal error"
}Short-Term Memory (Conversations)
List conversations for the workspace, newest first (by updatedAt, then id). Returns metadata only (no message bodies), plus a display title and firstMessageSnippet per conversation. The title is read from the conversation's metadata "title" key (set metadata.title at creation to give a conversation a display name); firstMessageSnippet is the first message's content truncated to 120 characters. Both are empty strings when unset. Filter to one user's conversations with userId (exact match). Page with cursor: next_cursor is set whenever the page is full, and passing it back as cursor returns the conversations after that page. An empty next_cursor means there are no more; when the last page is exactly full, the request for the next one returns an empty list. Keep the same userId while paging.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | query | string | optional | Only conversations whose userId equals this value (exact, case-sensitive). Must not be empty when present. |
cursor | query | string | optional | Opaque cursor from a previous response's next_cursor |
limit | query | integer | optional | Max conversations to return (1-200, default 50) |
curl
curl 'http://localhost:8080/v1/conversations' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns conversations array and next_cursor
{
"conversations": [
"..."
],
"next_cursor": "string"
}invalid_limit when limit is outside 1..200, userId present but empty, or invalid cursor
{
"error": "invalid_limit when limit is outside 1..200, userId present but empty, or invalid cursor"
}Workspace not found
{
"error": "Workspace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Create a new conversation session. The ID is always server-assigned - an id supplied in the body is ignored, so callers must use the returned ID for all subsequent message, context, and search calls. The body is optional, and an empty body or null is treated as {}. Otherwise it must be a single JSON object carrying only userId, metadata or id; any other field (such as user_id), or data after the object, is rejected with 400 rather than dropped. Entity extraction runs asynchronously after messages are added. userId decides whose memory the extracted entities belong to; without it they are shared. It scopes data for a trusted backend and is not an access-control boundary.
Request Body
{
"metadata": {},
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/conversations' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Returns id, workspaceId, userId, metadata
{
"id": "string",
"metadata": {},
"userId": "string",
"workspaceId": "string"
}workspace_id required, an invalid request body, or an unknown field
{
"error": "workspace_id required, an invalid request body, or an unknown field"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Delete a conversation and everything it owns: its messages, observations, reflections, agent steps and the tool calls recorded against those steps. Entities extracted from the conversation are kept; only their links to the deleted nodes are removed. With purge=extracted, the same transaction also removes what was extracted only from this conversation, and the response reports how many entities, relationships and aliases it removed: - Entities whose every extraction source is in this conversation, together with their aliases. An entity is kept when it was created through the API or MCP, when another entity was merged into it, or when it has a relationship that the purge does not remove. - Relationships between entities whose every source message is in this conversation, unless they were created through the API or MCP. Relationships that survive stop listing this conversation's messages among their sources. Extracted data is identified through the messages it came from, so the purge must be requested on the delete that removes them: once a conversation has been deleted without it, its extracted data can no longer be told apart. A purge can wait briefly for an extraction running in the same workspace, so that extraction cannot attach a new mention to an entity the purge is removing. Any other purge value is rejected with 400 and deletes nothing. The delete is idempotent and returns 200 even when the conversation does not exist. Repeating it for a conversation that is already gone still removes any messages, observations, reflections, agent steps and tool calls left behind under that conversation ID.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
purge | query | string | optional | Also remove what was extracted only from this conversation |
curl
curl -X DELETE 'http://localhost:8080/v1/conversations/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns status: deleted, plus purged counts when purge=extracted
{
"purged": {
"aliases": "...",
"entities": "...",
"relationships": "..."
},
"status": "deleted"
}invalid_purge
{
"error": "invalid_purge",
"message": "purge must be \"extracted\" when given"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Get conversation metadata by ID.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
curl
curl 'http://localhost:8080/v1/conversations/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns id, workspaceId, userId, metadata, createdAt, updatedAt
{
"createdAt": "string",
"id": "string",
"metadata": {},
"updatedAt": "string",
"userId": "string",
"workspaceId": "string"
}Not found
{
"error": "Not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Get the structured context for an agent to build its prompt from. Returns three tiers: (1) reflections - highest-level compressed insights, (2) observations - mid-level summaries, (3) recentMessages - raw recent messages, each with its metadata. Call this before constructing an agent's system prompt.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
curl
curl 'http://localhost:8080/v1/conversations/{id}/context' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns reflections, observations, recentMessages arrays
{
"observations": [
"..."
],
"recentMessages": [
"..."
],
"reflections": [
"..."
]
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Per-unit extraction status for a conversation's messages (E6): status, last run, attempts, error.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
curl
curl 'http://localhost:8080/v1/conversations/{id}/extraction-status' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}List messages in a conversation, newest first, each with the metadata it was added with ({} when none). Use the limit parameter to control page size (default 50, max 200). There is no offset, so a conversation cannot be listed past its newest 200 messages.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
limit | query | integer | optional | Max messages to return (1-200, default 50) |
curl
curl 'http://localhost:8080/v1/conversations/{id}/messages' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns messages array
{
"messages": [
"..."
]
}invalid_limit
{
"error": "invalid_limit",
"max": 200,
"message": "limit must be an integer between 1 and 200"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Add a message to a conversation. Triggers asynchronous entity extraction via the memory worker. Role must be "user", "assistant", or "system". Optional metadata is an object of string values (at most 8192 bytes of keys and values combined), stored with the message and returned by the list, context and search endpoints.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
Request Body
{
"content": "string",
"metadata": {},
"role": "string"
}curl
curl -X POST 'http://localhost:8080/v1/conversations/{id}/messages' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"content": "",
"role": ""
}'Responses
Returns id, conversationId, role, content, metadata
{
"content": "string",
"conversationId": "string",
"id": "string",
"metadata": {},
"role": "string"
}Invalid role, missing fields, an unknown field, a non-string metadata value (the message names the field), or oversized metadata
{
"error": "Invalid role, missing fields, an unknown field, a non-string metadata value (the message names the field), or oversized metadata"
}Conversation not found
{
"error": "Conversation not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Add multiple messages to a conversation in a single request. Each message triggers async entity extraction independently. Maximum 100 messages per request, kept in request order. Each message takes the same optional metadata as the single add; one invalid message rejects the whole request and nothing is written.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
Request Body
{
"messages": [
"..."
]
}curl
curl -X POST 'http://localhost:8080/v1/conversations/{id}/messages/bulk' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"messages": [
{
"content": "",
"role": ""
}
]
}'Responses
Returns messages array with IDs
{
"messages": [
"..."
]
}Validation error (the message names the offending message's index), or an unknown field in the body or in a message
{
"error": "Validation error (the message names the offending message's index), or an unknown field in the body or in a message"
}Conversation not found
{
"error": "Conversation not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Search one conversation's messages by content. Uses vector similarity search when embeddings are available, falling back to a case-insensitive text match on content. searchType reports which path answered. limit applies to both paths. Each message carries its metadata and conversationId. Unknown body fields are rejected.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
Request Body
{
"limit": 0,
"query": "string"
}curl
curl -X POST 'http://localhost:8080/v1/conversations/{id}/search' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"query": ""
}'Responses
Returns messages array and searchType
{
"messages": [
"..."
],
"searchType": "vector"
}Missing or too long query (max 4096 characters), an unknown field, or invalid_limit when limit is outside 1..100
{
"error": "Missing or too long query (max 4096 characters), an unknown field, or invalid_limit when limit is outside 1..100"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Search messages by content across every conversation in the workspace, optionally narrowed to one conversation (conversationId) or to the conversations created with one userId, both by exact match; set together, a message must match both. Uses vector similarity search when embeddings are available, falling back to a case-insensitive text match on content when they are not or when the vector search finds nothing in scope. A filtered vector search scores every embedded message in its scope, so a match is never lost to nearer messages outside it. score is present on vector results only. Returns searchType field indicating which method was used. Each message carries its metadata and conversationId. userId scopes data for a trusted backend and is not an access-control boundary. Unknown body fields are rejected, so a misspelled filter cannot silently widen the search.
Request Body
{
"conversationId": "string",
"limit": 0,
"query": "string",
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/messages/search' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"query": ""
}'Responses
Returns messages array and searchType
{
"messages": [
"..."
],
"searchType": "vector"
}Missing or too long query (max 4096 characters), an unknown field, or invalid_limit when limit is outside 1..100
{
"error": "Missing or too long query (max 4096 characters), an unknown field, or invalid_limit when limit is outside 1..100"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Long-Term Memory (Knowledge Graph)
List entities in the knowledge graph, most recently updated first. Filter by type or by user using the optional query parameters. userId scopes data for a trusted backend and is not an access-control boundary.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
type | query | string | optional | Filter by type: person, organization, location, concept, tool, custom |
userId | query | string | optional | Only this user's entities (exact match); omit for every user's and the shared ones |
limit | query | integer | optional | Max entities to return (1-200, default 50) |
curl
curl 'http://localhost:8080/v1/entities' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns entities array
{
"entities": [
"..."
]
}invalid_limit
{
"error": "invalid_limit",
"max": 200,
"message": "limit must be an integer between 1 and 200"
}Workspace not found
{
"error": "Workspace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Create a new entity in the knowledge graph. Entities are automatically created during entity extraction, but can also be created manually. The name is first resolved against existing entities: a confident match merges onto the existing entity and returns 200 with resolution "merged" and merged_into, an uncertain one creates the entity with resolution "review_pending" and duplicate_of and queues the pair for review, and otherwise the entity is created with resolution "created". The type is validated against the workspace's active ontology, which rejects an undeclared type or a declared type missing a required property with 422 schema_violation. With userId the entity belongs to that user's memory and resolves only against that user's entities; without it the entity is shared and resolves only against shared ones. userId scopes data for a trusted backend and is not an access-control boundary.
Request Body
{
"description": "string",
"name": "string",
"properties": {},
"type": "string",
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/entities' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"name": "",
"type": ""
}'Responses
Merged onto an existing entity: id, resolution, merged_into, confidence
Returns id, name, type, description, resolution
{
"description": "string",
"id": "string",
"name": "string",
"type": "string",
"userId": "string"
}Missing required fields
{
"error": "Missing required fields"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}schema_violation: the type is undeclared or a required property is missing
{
"error": "schema_violation: the type is undeclared or a required property is missing"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}user_partition_not_ready: userId was given before this workspace's existing memory was assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: userId was given before this workspace's existing memory was assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Create multiple entities in one request (the bulk form of POST /v1/entities), max 100. Each entity goes through the same shared core as the single endpoint — ontology validation, resolve-before-create within its userId's memory, review-queue flagging, PII scrub, typed properties, embeddings — so behavior cannot drift. Each entity carries its own optional userId. Entities are processed in order and resolve against those created earlier in the same request, so an in-request duplicate merges instead of forking. A rejected or failed entity is reported in its result entry and never aborts the batch; the response always returns 200 with a per-entity results array.
Request Body
{
"entities": [
"..."
]
}curl
curl -X POST 'http://localhost:8080/v1/entities/bulk' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"entities": [
{
"name": "",
"type": ""
}
]
}'Responses
Per-entity results with created/merged/review_pending/failed counts
{
"created": 0,
"failed": 0,
"merged": 0,
"results": [
"..."
],
"review_pending": 0
}Empty or oversized batch
{
"error": "Empty or oversized batch"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}user_partition_not_ready: an entity names a userId before this workspace's existing memory was assigned to users; retry after Retry-After seconds; nothing is written; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: an entity names a userId before this workspace's existing memory was assigned to users; retry after Retry-After seconds; nothing is written; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Find entities by name using the resolver's identity semantics — case-, punctuation- and corporate-suffix-insensitive matching plus alias lookup — so the result answers "would creating this entity dedupe onto something?". Because entity resolution is type-strict, the same name may match several entities of different types; all matches are returned, ordered deterministically (direct name matches before alias matches, then confidence descending, then oldest first). Entities that were merged away resolve to their canonical target. An empty result is 200 with an empty list.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
name | query | string | required | Entity name to look up (resolver-normalized before matching) |
type | query | string | optional | Narrow to one entity type (case-insensitive) |
userId | query | string | optional | Only this user's entities (exact match), judged on the canonical entity |
limit | query | integer | optional | Maximum matches to return (1-100, default 25) |
curl
curl 'http://localhost:8080/v1/entities/by-name' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Ordered matches; empty when none
{
"entities": [
"..."
]
}Missing name parameter, or invalid_limit when limit is outside 1..100
{
"error": "Missing name parameter, or invalid_limit when limit is outside 1..100"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Tenant database failure
{
"error": "Tenant database failure",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Returns the count of canonical (non-merged) entities in the workspace, or in one user's memory with userId. A cheap signal the Memory Browser polls to surface a "new entities available" refresh affordance without re-fetching the full graph.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | query | string | optional | Only this user's entities (exact match) |
curl
curl 'http://localhost:8080/v1/entities/count' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns count
Missing workspace_id
{
"error": "Missing workspace_id"
}Workspace not found
{
"error": "Workspace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Get the entity graph as nodes and edges for visualization, used by the Memory Browser in the dashboard. Only canonical entities are nodes: merged-away entities are excluded, and each edge's endpoints resolve to their canonical entity, so a relationship absorbed by a merge re-attaches to the visible entity. Every edge carries a stable, deterministic id. Merge plumbing (MERGED_REL, SAME_AS) is excluded. With userId, only that user's entities and the relationships among them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | optional | Max nodes to return (1-1000, default 250) |
userId | query | string | optional | Only this user's entities (exact match) |
curl
curl 'http://localhost:8080/v1/entities/graph' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns nodes and edges arrays
{
"edges": [
"..."
],
"nodes": [
{}
]
}invalid_limit
{
"error": "invalid_limit",
"max": 200,
"message": "limit must be an integer between 1 and 200"
}Workspace not found
{
"error": "Workspace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Search entities by name or description. Uses vector similarity search when embeddings are available. When the vector path cannot answer (no embedding service, no vector index, or no vector hits) it falls back to a case-insensitive text match on name and description, ranked by the entity fulltext index when present. searchType reports which path answered. limit applies to both paths. userId narrows every path to one user's entities by exact match, and a user with a small share of the workspace still gets their matches; it scopes data for a trusted backend and is not an access-control boundary. Unknown body fields are rejected, so a misspelled filter cannot silently widen the search.
Request Body
{
"limit": 0,
"query": "string",
"type": "string",
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/entities/search' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"query": ""
}'Responses
Returns entities array and searchType
{
"entities": [
"..."
],
"searchType": "vector"
}Missing query, an unknown field, or invalid_limit when limit is outside 1..100
{
"error": "Missing query, an unknown field, or invalid_limit when limit is outside 1..100"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Delete an entity and all its relationships from the knowledge graph.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Entity ID |
curl
curl -X DELETE 'http://localhost:8080/v1/entities/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns status: deleted
{
"status": "success"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Get entity details including all relationships. Each relationship carries the edge's stable id (for one created through POST /v1/relationships, the id that call returned) and its type as relationshipType (relType is a deprecated alias that always equals it). It is reported relative to this entity: direction is "out" for (entity)-[relationshipType]->(target) and "in" for (target)-[relationshipType]->(entity), and the target* fields always describe the other entity. Merge plumbing (SAME_AS, MERGED_REL) is excluded. Only a completed merge redirects an endpoint (pending, rejected and skipped review pairs redirect nothing): a merged-away endpoint is reported as the entity it was merged into, and edges left on entities merged into this one are included. An entity merged without a SAME_AS link to the entity it was merged into, such as a redirected review, has no link to follow, so its edges are omitted at both ends and the list can be incomplete around it. An edge that resolves back to this entity is dropped. There is one relationship per distinct (direction, relationshipType, targetId), outgoing before incoming, then by relationshipType and target name; when merges leave several edges stating one, the edge between the canonical entities themselves is reported, then the one with the lowest id. relationships is an empty array when there are none. With userId, an entity outside that user's memory is not found, and only relationships to that user's entities are returned.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Entity ID |
userId | query | string | optional | Only within this user's memory (exact match) |
curl
curl 'http://localhost:8080/v1/entities/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns entity fields and relationships array
{
"confidence": 0,
"createdAt": "string",
"description": "string",
"id": "string",
"name": "string",
"relationships": [
"..."
],
"sourceStage": "string",
"type": "string",
"updatedAt": "string",
"userId": "string"
}Not found, or not this user's
{
"error": "Not found, or not this user's"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Update an entity's name or description.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Entity ID |
Request Body
{
"description": "string",
"name": "string"
}curl
curl -X PUT 'http://localhost:8080/v1/entities/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Returns status: updated
{
"status": "success"
}Invalid request
{
"error": "Invalid request"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Provide feedback on entity quality. userScore is a float 0-1 representing confidence. confirmed=true marks the entity as human-verified.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Entity ID |
Request Body
{
"confirmed": false,
"userScore": 0
}curl
curl -X PUT 'http://localhost:8080/v1/entities/{id}/feedback' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Returns id, updated: true
{
"id": "string",
"updated": false
}Invalid request
{
"error": "Invalid request"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Get cross-conversation history - all messages that mention this entity, across all conversations in the workspace. With userId, an entity outside that user's memory has no history, and only that user's conversations are read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Entity ID |
userId | query | string | optional | Only within this user's memory (exact match) |
curl
curl 'http://localhost:8080/v1/entities/{id}/history' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns entityId and mentions array
{
"entityId": "string",
"mentions": [
{}
]
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Merge the source entity into a target entity. All relationships are transferred to the target. A SAME_AS relationship is created for provenance. The source entity is not deleted but becomes inert. Both entities must belong to the same user's memory (or both be shared); otherwise 422 cross_user_merge. While the workspace's existing memory is still being assigned to users, merges answer 503 user_partition_not_ready with Retry-After.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Source entity ID |
Request Body
{
"targetId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/entities/{id}/merge' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"targetId": ""
}'Responses
Returns status: merged, sourceId, targetId
{
"sourceId": "string",
"status": "merged",
"targetId": "string"
}Missing targetId or attempted self-merge
{
"error": "Missing targetId or attempted self-merge"
}Target entity not found
{
"error": "Target entity not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}cross_user_merge: the entities belong to different users (or one is shared)
{
"error": "cross_user_merge: the entities belong to different users (or one is shared)",
"message": "string"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error
{
"error": "Internal error"
}user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Returns a node's neighborhood across all memory labels (Entity, Message, Conversation, Observation, Reflection, AgentStep, ToolCall, ReasoningTrace, Tool), plus the complete canonical-resolved relationships among the resulting nodes and loadedIds. Optional depth is 1..3 (default 1); selection views use 3 to include connected short-term, long-term, and reasoning memory. Paths traverse only memory nodes and exclude merge plumbing (MERGED_REL/SAME_AS). New neighbors are capped at 200, nearest first and then most recently updated, with truncation metadata. Omitting loadedIds is the same as an empty list. Provenance edges are included, with paired EXTRACTED_FROM metadata collapsed onto MENTIONS/INFLUENCED. With userId, the anchor, every intermediate node, and returned nodes must belong to that user.
Request Body
{
"depth": 0,
"loadedIds": [
"string"
],
"nodeId": "string",
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/graph/expand' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Returns nodes, edges and truncated metadata
{
"edges": [
"..."
],
"nodes": [
"..."
],
"truncated": {
"nodeId": "...",
"shown": "...",
"total": "..."
}
}Missing workspace_id or nodeId, depth outside 1..3, or loadedIds exceeds cap
{
"error": "Missing workspace_id or nodeId, depth outside 1..3, or loadedIds exceeds cap"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Create a typed, directed relationship between two entities. The type is validated against the workspace's relation allowlist, which includes every relationship type the active ontology declares: unknown types are written as the fallback type (RELATED_TO) with the original name preserved in the predicate field — never silently. When the ontology declares the type, its declared source/target entity types are enforced: an endpoint pair the ontology does not cover returns 422 ontology_violation under a strict ontology (the body lists the pairs it does declare) and collapses to the fallback type otherwise; when the endpoints fit, the edge is stored under the ontology's own spelling (depends_on is stored as DEPENDS_ON). Types the ontology does not declare are judged by the workspace's stored allowed_types alone and never rejected on this ground. The extraction pipeline is stricter by design: there a relation that fits no declaration is dropped, while an API call is told its write did not land. confidence defaults to 1.0. properties values must be scalars or arrays of scalars, and the server-owned keys (id, confidence, method, predicate, firstSeenAt, lastSeenAt) are rejected. The write is idempotent per (source, type, target): re-asserting an existing relationship updates lastSeenAt, averages confidence, and re-applies properties. Both entities must belong to the same user's memory (or both be shared), and to userId's when it is given; otherwise 422 cross_user_relationship. userId scopes data for a trusted backend and is not an access-control boundary. Every relationship carries a UUID id, which a re-assert returns unchanged and GET /v1/entities/{id} reports for the relationship from both ends. Requires the entities:write scope.
Request Body
{
"confidence": 0,
"properties": {},
"relationshipType": "string",
"sourceId": "string",
"targetId": "string",
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/relationships' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"relationshipType": "",
"sourceId": "",
"targetId": ""
}'Responses
Existing relationship re-asserted (idempotent match)
{
"confidence": 1,
"created": true,
"id": "string",
"predicate": "",
"relationshipType": "WORKS_AT",
"sourceId": "string",
"targetId": "string"
}Relationship created
{
"confidence": 1,
"created": true,
"id": "string",
"predicate": "",
"relationshipType": "WORKS_AT",
"sourceId": "string",
"targetId": "string"
}Missing fields, bad confidence, or reserved/malformed properties
{
"error": "Missing fields, bad confidence, or reserved/malformed properties"
}Source or target entity not found in this workspace
{
"error": "Source or target entity not found in this workspace"
}Cardinality violation: the type is declared to-one and the source already has a different target; or the workspace database was removed (database_unavailable) or deprovisioned - reprovision or update the external connection
{
"error": "Cardinality violation: the type is declared to-one and the source already has a different target; or the workspace database was removed (database_unavailable) or deprovisioned - reprovision or update the external connection"
}ontology_violation: the active ontology is strict and declares no relationship of this type between these endpoint types; or cross_user_relationship: the entities belong to different users, or not to userId
{
"error": "ontology_violation: the active ontology is strict and declares no relationship of this type between these endpoint types; or cross_user_relationship: the entities belong to different users, or not to userId"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Tenant database failure
{
"error": "Tenant database failure",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}user_partition_not_ready: userId was given before this workspace's existing memory was assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: userId was given before this workspace's existing memory was assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Create multiple typed relationships in one request (the bulk form of POST /v1/relationships), max 100. Each edge is upserted through the same shared core as the single endpoint, so type validation, predicate fallback, to-one cardinality and the same-user rule behave identically; each edge carries its own optional userId. A bad edge (missing fields, cardinality violation, unknown entity, entities of different users) is reported in its result entry and never aborts the batch; an accepted request always returns 200 with a per-edge results array. A successful entry carries the relationship's id, the same one POST /v1/relationships would return.
Request Body
{
"relationships": [
"..."
]
}curl
curl -X POST 'http://localhost:8080/v1/relationships/bulk' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"relationships": [
{
"relationshipType": "",
"sourceId": "",
"targetId": ""
}
]
}'Responses
Per-edge results with created/reasserted/failed counts
{
"created": 0,
"failed": 0,
"reasserted": 0,
"results": [
"..."
]
}Empty or oversized batch
{
"error": "Empty or oversized batch"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Tenant database failure
{
"error": "Tenant database failure",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}user_partition_not_ready: an edge names a userId before this workspace's existing memory was assigned to users; retry after Retry-After seconds; nothing is written; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: an edge names a userId before this workspace's existing memory was assigned to users; retry after Retry-After seconds; nothing is written; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Entity Resolution Review
The pending queue holds only pairs whose two entities share at least one neighbouring entity; a pending pair nothing in the graph connects is left out until something does.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | optional | Page size (1-200, default 50) |
offset | query | integer | optional | Pagination offset (default 0) |
band | query | string | optional | Filter the pending queue to one band: type_conflict | similarity (default: all; ignored for status=decided) |
status | query | string | optional | pending (default) | decided (confirmed/redirected/rejected, with reviewedAt/reviewedBy) |
curl
curl 'http://localhost:8080/v1/reviews' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
invalid_limit
{
"error": "invalid_limit",
"max": 200,
"message": "limit must be an integer between 1 and 200"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
batchId | path | string | required | Batch id returned by POST /v1/reviews/bulk |
curl
curl -X POST 'http://localhost:8080/v1/reviews/batch/{batchId}/reopen' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Only pairs in the pending queue are candidates: pairs whose two entities share at least one neighbouring entity. Pairs whose entities belong to different users (or a user's and a shared one) are never merged: they are skipped and counted in excludedCrossUser, in the dry-run preview and in the result. While the workspace's existing memory is still being assigned to users, the call (dry run included) answers 503 user_partition_not_ready with Retry-After.
Request Body
{
"action": "string",
"dryRun": false,
"includeEntangled": false,
"includeTypeConflicts": false,
"minConfidence": 0
}curl
curl -X POST 'http://localhost:8080/v1/reviews/bulk' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"action": ""
}'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The pending queue holds only pairs whose two entities share at least one neighbouring entity; a pending pair nothing in the graph connects is left out until something does.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
minSize | query | integer | optional | Only return clusters with at least this many entities (default 3) |
curl
curl 'http://localhost:8080/v1/reviews/clusters' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The survivor and every merged entity must belong to the same user's memory (or all be shared); otherwise nothing is merged and the call answers 422 cross_user_merge. While the workspace's existing memory is still being assigned to users, it answers 503 user_partition_not_ready with Retry-After.
Request Body
{
"mergeIds": [
"string"
],
"resolvedType": "string",
"survivorId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/reviews/clusters/resolve' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"mergeIds": [],
"survivorId": ""
}'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}cross_user_merge: the entities belong to different users (or one is shared)
{
"error": "cross_user_merge: the entities belong to different users (or one is shared)",
"message": "string"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The pending queue holds only pairs whose two entities share at least one neighbouring entity; a pending pair nothing in the graph connects is left out until something does. Every pending figure counts that queue.
curl
curl 'http://localhost:8080/v1/reviews/stats' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
Workspace not found
{
"error": "Workspace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The pending queue holds only pairs whose two entities share at least one neighbouring entity; a pending pair nothing in the graph connects is left out until something does.
curl
curl 'http://localhost:8080/v1/reviews/stats/pending' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
{pending: n}; an unprovisioned workspace has no reviews and returns {pending: 0} rather than 503
Workspace not found
{
"error": "Workspace not found"
}Workspace database removed (database_unavailable) - reprovision or update the external connection. Unlike the other tenant-scoped reads, a deprovisioned workspace does NOT 409 here: the badge answers 200 {pending: 0} for every unprovisioned state (see below)
{
"error": "Workspace database removed (database_unavailable) - reprovision or update the external connection. Unlike the other tenant-scoped reads, a deprovisioned workspace does NOT 409 here: the badge answers 200 {pending: 0} for every unprovisioned state (see below)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable)
{
"error": "Workspace database unreachable (db_unreachable)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}A confirm, or a redirect onto mergeInto, never merges two users' entities (or a user's and a shared one): it is refused with 422 cross_user_merge. Such a pair can only predate the per-user partition migration, and can still be rejected. While that migration is still running, a confirm or redirect answers 503 user_partition_not_ready with Retry-After.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
pairId | path | string | required | Pair ID (hash of sourceId→targetId) |
Request Body
{
"action": "string",
"mergeInto": "string",
"resolvedType": "string",
"skipReason": "string",
"sourceId": "string",
"targetId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/reviews/{pairId}/decision' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"action": "",
"sourceId": "",
"targetId": ""
}'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}cross_user_merge: the entities belong to different users (or one is shared)
{
"error": "cross_user_merge: the entities belong to different users (or one is shared)",
"message": "string"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready: the workspace's existing memory is still being assigned to users; retry after Retry-After seconds; or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
pairId | path | string | required | Pair ID (hash of sourceId→targetId) |
Request Body
{
"sourceId": "string",
"targetId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/reviews/{pairId}/reopen' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"sourceId": "",
"targetId": ""
}'Responses
OK
Pair not found
{
"error": "Pair not found"
}Source entity has since been merged elsewhere; or the workspace database was removed (database_unavailable) or deprovisioned - reprovision or update the external connection
{
"error": "Source entity has since been merged elsewhere; or the workspace database was removed (database_unavailable) or deprovisioned - reprovision or update the external connection"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Ontologies
List system templates and workspace-owned ontologies. The active ontology is flagged.
curl
curl 'http://localhost:8080/v1/ontologies' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"ontologies": [
"..."
]
}Internal Server Error
Request Body
{
"message": "string",
"ontology": {
"domain": "...",
"entity_types": "...",
"extraction_aliases": "...",
"relationships": "..."
},
"validation_mode": "string"
}curl
curl -X POST 'http://localhost:8080/v1/ontologies' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"ontology": {}
}'Responses
Created
{
"created_at": "string",
"created_by": "string",
"id": "string",
"message": "string",
"ontology_id": "string",
"parent_version_id": "string",
"revision": 0,
"schema_hash": "string",
"schema_json": "string",
"semver_tag": "string",
"validation_mode": "string"
}Conflict
Unprocessable Entity
Get the workspace's currently active ontology version and its parsed body.
curl
curl 'http://localhost:8080/v1/ontologies/active' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"ontology": {
"domain": "...",
"entity_types": "...",
"extraction_aliases": "...",
"relationships": "..."
},
"version": {
"created_at": "...",
"created_by": "...",
"id": "...",
"message": "...",
"ontology_id": "...",
"parent_version_id": "...",
"revision": "...",
"schema_hash": "...",
"schema_json": "...",
"semver_tag": "...",
"validation_mode": "..."
}
}Internal Server Error
Request Body
{
"version_id": "string"
}curl
curl -X POST 'http://localhost:8080/v1/ontologies/active' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"version_id": ""
}'Responses
OK
{
"created_at": "string",
"created_by": "string",
"id": "string",
"message": "string",
"ontology_id": "string",
"parent_version_id": "string",
"revision": 0,
"schema_hash": "string",
"schema_json": "string",
"semver_tag": "string",
"validation_mode": "string"
}Not Found
Convert an Arrows / Neo4j Data Importer / RDF / GraphQL / Cypher / LinkML / native document into a native ontology draft. Supply either content (inline) or url (fetched server-side, SSRF-guarded, https only). Returns the draft and conversion warnings; does not persist.
Request Body
{
"content": "string",
"format": "string",
"url": "string"
}curl
curl -X POST 'http://localhost:8080/v1/ontologies/import' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
{
"detected_format": "string",
"ontology": {
"domain": "...",
"entity_types": "...",
"extraction_aliases": "...",
"relationships": "..."
},
"suggested_name": "string",
"warnings": [
"..."
]
}Bad Request
Request Entity Too Large
Unprocessable Entity
Too Many Requests
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
job_id | path | string | required | Migration job ID |
curl
curl 'http://localhost:8080/v1/ontologies/migrations/{job_id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"completed_at": "string",
"created_at": "string",
"created_by": "string",
"error_message": "string",
"errored": 0,
"id": "string",
"ontology_id": "string",
"processed": 0,
"spec": {
"batch_size": "...",
"dedup_by_name": "...",
"dry_run": "...",
"from_version_id": "...",
"to_version_id": "...",
"type_mappings": "..."
},
"started_at": "string",
"status": "string",
"total": 0,
"updated_at": "string",
"workspace_id": "string"
}Not Found
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
job_id | path | string | required | Migration job ID |
curl
curl -X POST 'http://localhost:8080/v1/ontologies/migrations/{job_id}/pause' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
No Content
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
job_id | path | string | required | Migration job ID |
curl
curl -X POST 'http://localhost:8080/v1/ontologies/migrations/{job_id}/resume' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
No Content
curl
curl 'http://localhost:8080/v1/ontologies/pending-types' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
Request Body
{
"ontology": {
"domain": "...",
"entity_types": "...",
"extraction_aliases": "...",
"relationships": "..."
},
"text": "string"
}curl
curl -X POST 'http://localhost:8080/v1/ontologies/preview' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"text": ""
}'Responses
OK
{
"entities": [
"..."
],
"relationships": [
"..."
],
"resolution_summary": {
"auto_merge": "...",
"new": "...",
"review": "...",
"total_candidates": "..."
}
}Too Many Requests
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
curl
curl -X DELETE 'http://localhost:8080/v1/ontologies/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
No Content
Forbidden
Not Found
Get one ontology (system or workspace-owned) and its version history.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
curl
curl 'http://localhost:8080/v1/ontologies/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"record": {
"created_at": "...",
"created_by": "...",
"deleted_at": "...",
"description": "...",
"id": "...",
"is_system": "...",
"name": "...",
"source_sha": "...",
"workspace_id": "..."
},
"versions": [
"..."
]
}Not Found
Internal Server Error
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
Request Body
{
"message": "string",
"ontology": {
"domain": "...",
"entity_types": "...",
"extraction_aliases": "...",
"relationships": "..."
},
"validation_mode": "string"
}curl
curl -X PUT 'http://localhost:8080/v1/ontologies/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"ontology": {}
}'Responses
OK
{
"created_at": "string",
"created_by": "string",
"id": "string",
"message": "string",
"ontology_id": "string",
"parent_version_id": "string",
"revision": 0,
"schema_hash": "string",
"schema_json": "string",
"semver_tag": "string",
"validation_mode": "string"
}Forbidden
Not Found
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | System template name |
curl
curl -X POST 'http://localhost:8080/v1/ontologies/{id}/clone' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Created
{
"created_at": "string",
"created_by": "string",
"id": "string",
"message": "string",
"ontology_id": "string",
"parent_version_id": "string",
"revision": 0,
"schema_hash": "string",
"schema_json": "string",
"semver_tag": "string",
"validation_mode": "string"
}Not Found
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
from | query | integer | required | From revision |
to | query | integer | required | To revision |
curl
curl 'http://localhost:8080/v1/ontologies/{id}/diff' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"entity_types": {
"added": "...",
"modified": "...",
"removed": "...",
"renamed": "..."
},
"from_revision": 0,
"mode_change": {
"from": "...",
"to": "..."
},
"relationships": {
"added": "...",
"removed": "..."
},
"to_revision": 0
}Not Found
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
Request Body
{
"spec": {
"batch_size": "...",
"dedup_by_name": "...",
"dry_run": "...",
"from_version_id": "...",
"to_version_id": "...",
"type_mappings": "..."
}
}curl
curl -X POST 'http://localhost:8080/v1/ontologies/{id}/migrate' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"spec": {}
}'Responses
Accepted
{
"completed_at": "string",
"created_at": "string",
"created_by": "string",
"error_message": "string",
"errored": 0,
"id": "string",
"ontology_id": "string",
"processed": 0,
"spec": {
"batch_size": "...",
"dedup_by_name": "...",
"dry_run": "...",
"from_version_id": "...",
"to_version_id": "...",
"type_mappings": "..."
},
"started_at": "string",
"status": "string",
"total": 0,
"updated_at": "string",
"workspace_id": "string"
}Bad Request
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
curl
curl 'http://localhost:8080/v1/ontologies/{id}/pending-types' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
ptId | path | string | required | Pending Type ID |
Request Body
{
"target": "string"
}curl
curl -X POST 'http://localhost:8080/v1/ontologies/{id}/pending-types/{ptId}/map' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"target": ""
}'Responses
OK
{
"created_at": "string",
"created_by": "string",
"id": "string",
"message": "string",
"ontology_id": "string",
"parent_version_id": "string",
"revision": 0,
"schema_hash": "string",
"schema_json": "string",
"semver_tag": "string",
"validation_mode": "string"
}Not Found
Unprocessable Entity
Get one specific revision of an ontology.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Ontology ID |
revision | path | integer | required | Revision number |
curl
curl 'http://localhost:8080/v1/ontologies/{id}/versions/{revision}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"created_at": "string",
"created_by": "string",
"id": "string",
"message": "string",
"ontology_id": "string",
"parent_version_id": "string",
"revision": 0,
"schema_hash": "string",
"schema_json": "string",
"semver_tag": "string",
"validation_mode": "string"
}Not Found
Internal Server Error
Observational Memory
List compressed observations for a conversation. Observations are auto-generated summaries of message windows, created by the memory worker after sufficient messages accumulate.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
limit | query | integer | optional | Max observations to return (1-200, default 50) |
curl
curl 'http://localhost:8080/v1/conversations/{id}/observations' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns observations array
{
"observations": [
"..."
]
}invalid_limit
{
"error": "invalid_limit",
"max": 200,
"message": "limit must be an integer between 1 and 200"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}List reflections for a conversation. Reflections are higher-level insights synthesized from multiple observations. Each new reflection supersedes the previous.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Conversation ID |
curl
curl 'http://localhost:8080/v1/conversations/{id}/reflections' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns reflections array
{
"reflections": [
"..."
]
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Reasoning Memory
Get a detailed explanation of a reasoning step including its tool calls and the entities it influenced.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
stepId | path | string | required | Step ID |
curl
curl 'http://localhost:8080/v1/reasoning/explain/{stepId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns step details, toolCalls, and influencedEntities
{
"actionTaken": "string",
"conversationId": "string",
"createdAt": "string",
"id": "string",
"influencedEntities": [
"..."
],
"reasoning": "string",
"result": "string",
"toolCalls": [
"..."
]
}Step not found
{
"error": "Step not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Get the reasoning chain that influenced the creation of an entity - which steps and tool calls contributed to it.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
entityId | path | string | required | Entity ID |
curl
curl 'http://localhost:8080/v1/reasoning/provenance/{entityId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns entityId and provenance chain
{
"entityId": "string",
"steps": [
{}
]
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}List reasoning steps for a conversation. The conversation_id query parameter is required.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
conversation_id | query | string | required | Conversation ID |
curl
curl 'http://localhost:8080/v1/reasoning/steps' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns steps array
{
"steps": [
"..."
]
}Missing conversation_id
{
"error": "Missing conversation_id"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Record a reasoning step taken by an agent. Captures the agent's thought process (reasoning), the action it decided to take (actionTaken), and optionally the result. With traceId the step hangs under that trace at the next step number (stepNumber in the response) and its conversation is the trace's, so conversationId may be omitted; a conversationId that disagrees with the trace's is refused. Without traceId the step belongs to the conversation alone, as every step did before traces existed.
Request Body
{
"actionTaken": "string",
"conversationId": "string",
"metadata": {},
"reasoning": "string",
"result": "string",
"traceId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/reasoning/steps' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"actionTaken": "",
"reasoning": ""
}'Responses
Returns id, conversationId, reasoning, actionTaken, result, and traceId plus stepNumber under a trace
{
"actionTaken": "string",
"conversationId": "string",
"id": "string",
"reasoning": "string",
"result": "string",
"stepNumber": 0,
"traceId": "string"
}Missing required fields, or a conversationId that disagrees with the trace
{
"error": "Missing required fields, or a conversationId that disagrees with the trace"
}Conversation or trace not found
{
"error": "Conversation or trace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Reasoning steps like the query, each with its trace's task and outcome beside it: past thoughts on similar problems, not just past tasks. Vector similarity over the steps' thought, action and observation when the embedding service answers (searchType vector, each step with its score), a case-insensitive text match over the same three fields otherwise. userId narrows the search to that user's conversations; successOnly keeps steps of traces that reported success, which excludes a step recorded without a trace; minScore drops vector hits below it. limit is 1-50, default 10.
Request Body
{
"limit": 10,
"minScore": 0.7,
"query": "preview the refund",
"successOnly": false,
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/reasoning/steps/search' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Returns steps and searchType
{
"searchType": "vector",
"steps": [
"..."
]
}Missing or too long query, invalid_limit, a minScore outside 0..1, or an unknown field
{
"error": "Missing or too long query, invalid_limit, a minScore outside 0..1, or an unknown field"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Record a tool invocation. input and output are JSON-encoded strings (not objects). status is one of pending, success (default), failure, error, timeout, cancelled; the legacy completed/failed are accepted and rewritten. Each call counts on its tool's registry node, which GET /v1/reasoning/tools/stats reads. stepId links the call to its reasoning step (a step that does not exist leaves it unlinked), messageId to the message that triggered it, and touchedEntityIds record the entities it touched as TOUCHED edges from the step.
Request Body
{
"durationMs": 150,
"error": "upstream timed out",
"input": "{\"query\":\"project status\"}",
"messageId": "string",
"output": "{\"results\":[\"r1\",\"r2\"]}",
"status": "success",
"stepId": "string",
"toolName": "web_search",
"touchedEntityIds": [
"string"
]
}curl
curl -X POST 'http://localhost:8080/v1/reasoning/tool-calls' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"input": "",
"toolName": ""
}'Responses
Returns id, stepId, toolName, status
{
"id": "string",
"status": "string",
"stepId": "string",
"toolName": "string"
}Missing required fields, object-valued input/output, or an invalid status
{
"error": "Missing required fields, object-valued input/output, or an invalid status"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Per-tool counters kept as tool calls are recorded: total, successful (status success) and failed (failure, error, timeout) calls, the success rate, the average duration and the last use, most-called first. toolName narrows to one tool. Counters are monotonic: deleting a conversation does not decrement them.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
toolName | query | string | optional | Only this tool |
curl
curl 'http://localhost:8080/v1/reasoning/tools/stats' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns tools
{
"tools": [
"..."
]
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Get the full reasoning trace for a conversation - all steps and their tool calls, in order.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
conversationId | path | string | required | Conversation ID |
curl
curl 'http://localhost:8080/v1/reasoning/trace/{conversationId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Returns conversationId, steps with nested toolCalls
{
"conversationId": "string",
"steps": [
"..."
],
"toolCalls": [
"..."
]
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Traces in the workspace, newest first by default. Filter to one conversation with conversationId, to one user's with userId (exact match), to those that reported success with successOnly=true, and to a startedAt window with since and until (RFC 3339). Order with orderBy (startedAt, completedAt) and orderDir (asc, desc). Page with limit (1-100, default 20) and offset; hasMore says whether another page follows.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
conversationId | query | string | optional | Only this conversation's traces |
userId | query | string | optional | Only this user's traces (exact match) |
successOnly | query | boolean | optional | Only traces that reported success |
since | query | string | optional | Traces started at or after this RFC 3339 time |
until | query | string | optional | Traces started at or before this RFC 3339 time |
orderBy | query | string | optional | startedAt (default) or completedAt |
orderDir | query | string | optional | desc (default) or asc |
limit | query | integer | optional | Page size, 1-100 (default 20) |
offset | query | integer | optional | Traces to skip (default 0) |
curl
curl 'http://localhost:8080/v1/reasoning/traces' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Returns traces and hasMore
{
"hasMore": false,
"traces": [
"..."
]
}A bad filter, order, limit or offset
{
"error": "A bad filter, order, limit or offset"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Start a trace for a task under a conversation. The task is embedded for similarity search when the embedding service answers; otherwise the trace is still found by text. The trace takes its conversation's userId, so user-scoped reads match it exactly. triggeredByMessageId links the trace to the message that initiated it; a message that does not exist leaves the trace unlinked. Record steps against the trace with POST /v1/reasoning/steps {traceId}, and finish it with POST /v1/reasoning/traces/{traceId}/complete.
Request Body
{
"conversationId": "string",
"metadata": {},
"task": "Return everything from order ORD-6014",
"triggeredByMessageId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/reasoning/traces' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"conversationId": "",
"task": ""
}'Responses
The trace, started and not yet complete
{
"completedAt": "string",
"conversationId": "string",
"errorKind": "string",
"id": "string",
"metadata": {},
"metrics": {},
"outcome": "string",
"score": 0,
"startedAt": "string",
"success": false,
"task": "string",
"updatedAt": "string",
"userId": "string"
}Missing conversationId or task, a task over 2000 characters, metadata over its limit, or an unknown field
{
"error": "Missing conversationId or task, a task over 2000 characters, metadata over its limit, or an unknown field"
}Conversation not found
{
"error": "Conversation not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Past traces whose task is like the query, each with its steps and their tool calls, so an agent can recall how a similar task went before acting. Vector similarity over the traces' tasks when the embedding service answers (searchType vector, each trace with its score), a case-insensitive text match on the task otherwise (searchType text). userId and conversationId narrow the traces searched by exact match; successOnly keeps traces that reported success; minScore drops vector hits below it. limit is 1-20, default 5.
Request Body
{
"conversationId": "string",
"limit": 5,
"minScore": 0.7,
"query": "return an order",
"successOnly": false,
"userId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/reasoning/traces/similar' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Returns traces and searchType
{
"searchType": "vector",
"traces": [
"..."
]
}Missing or too long query, invalid_limit, a minScore outside 0..1, or an unknown field
{
"error": "Missing or too long query, invalid_limit, a minScore outside 0..1, or an unknown field"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The trace with its steps in step order, each with its tool calls in time order, tool output included.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
traceId | path | string | required | Trace ID |
curl
curl 'http://localhost:8080/v1/reasoning/traces/{traceId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
The trace and its steps
{
"completedAt": "string",
"conversationId": "string",
"errorKind": "string",
"id": "string",
"metadata": {},
"metrics": {},
"outcome": "string",
"score": 0,
"startedAt": "string",
"steps": [
"..."
],
"success": false,
"task": "string",
"updatedAt": "string",
"userId": "string"
}Trace not found
{
"error": "Trace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Record how a trace ended and stamp completedAt. Any subset of outcome, success, errorKind and metrics may be sent; an omitted field is left unchanged and an empty body still marks the trace complete. relatedEntityIds are recorded as TOUCHED edges from the trace's last step, so an audit read reaches them in one hop. This is the client's own account of the run.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
traceId | path | string | required | Trace ID |
Request Body
{
"errorKind": "no_results",
"metrics": {},
"outcome": "Refund previewed; customer confirmed",
"relatedEntityIds": [
"string"
],
"success": true
}curl
curl -X POST 'http://localhost:8080/v1/reasoning/traces/{traceId}/complete' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
The completed trace
{
"completedAt": "string",
"conversationId": "string",
"errorKind": "string",
"id": "string",
"metadata": {},
"metrics": {},
"outcome": "string",
"score": 0,
"startedAt": "string",
"success": false,
"task": "string",
"updatedAt": "string",
"userId": "string"
}A text over its limit or an unknown field
{
"error": "A text over its limit or an unknown field"
}Trace not found
{
"error": "Trace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Record the message that initiated a trace, for a trace started before the message was known. Idempotent.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
traceId | path | string | required | Trace ID |
Request Body
{
"messageId": "string"
}curl
curl -X PUT 'http://localhost:8080/v1/reasoning/traces/{traceId}/message' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"messageId": ""
}'Responses
Returns traceId and messageId
Missing messageId
{
"error": "Missing messageId"
}Trace or message not found
{
"error": "Trace or message not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Per-User Memory
Delete everything stored for one end user, identified by userId: every conversation created with that userId, with everything it owns (messages, observations, reflections, agent steps and the tool calls recorded against those steps), and every entity in that user's memory, with its aliases and all of its relationships. Shared entities and other users' memory are untouched; a shared entity extracted from this user's conversations stays and loses only its links to the deleted messages, steps and tool calls. Memory is removed in batches, each committed as it goes. When a user holds more than one call can remove in time, the response has status: "incomplete" and the counts removed so far; repeat the call until status is deleted. The call is idempotent: once it has completed, repeating it removes nothing and returns zero counts. Repeating it also removes what an extraction already running for one of the user's messages wrote after the call returned. userId is compared exactly, as on every other surface, and is required: a missing, empty or repeated userId is rejected with 400 and deletes nothing. While the workspace's existing memory is still being assigned to users, the call answers 503 user_partition_not_ready with a Retry-After header and deletes nothing. userId scopes data for a trusted backend and is not an access-control boundary. Requires both memory:write and entities:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | query | string | required | The user whose memory to delete (exact match) |
curl
curl -X DELETE 'http://localhost:8080/v1/memory' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
status deleted or incomplete, with the counts this call removed
{
"deleted": {
"agentSteps": "...",
"aliases": "...",
"conversations": "...",
"entities": "...",
"messages": "...",
"observations": "...",
"reasoningTraces": "...",
"reflections": "...",
"relationships": "...",
"toolCalls": "..."
},
"status": "deleted",
"userId": "alice"
}invalid_user_id
{
"error": "invalid_user_id",
"message": "exactly one non-empty userId is required"
}Workspace not found
{
"error": "Workspace not found"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Internal error (cypher_error or internal)
{
"error": "Internal error (cypher_error or internal)",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}user_partition_not_ready (retry after Retry-After seconds) or db_unreachable; also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "user_partition_not_ready (retry after Retry-After seconds) or db_unreachable; also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Skill Generation
The public key, as a JWKS, that verifies the attestation.jws in a published skill package offline. Unauthenticated. The key set is empty when attestation signing is not configured.
curl
curl 'http://localhost:8080/.well-known/skill-attest-jwks.json' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
JWKS
jwks unavailable
{
"error": "jwks unavailable"
}List the workspace's skills with their latest-version summary. Each item carries attested: whether the served version was signed at publish time. Requires skills:read.
curl
curl 'http://localhost:8080/v1/skills' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Report which gated skill features this deployment enables (distillation, composition, autosuggest, attestationConfigured) and the publish-gate thresholds (groundingThreshold, coverageThreshold), so a client can hide unavailable actions instead of meeting a 501. Configuration only, no database access. Requires skills:read.
curl
curl 'http://localhost:8080/v1/skills/capabilities' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
Validate the scope, create a distillation run with status queued and enqueue it; poll GET /v1/skills/runs/{id} for progress. scope.type is required, one of workspace, conversations, entity, ontology_class or time, and the optional userId filter composes with any type. There is no implicit workspace default: omitting the type returns 400. Requires skills:write.
Request Body
{
"batchId": "string",
"nameHint": "string",
"procedureFormat": "string",
"scope": {
"conversationIds": "...",
"entityId": "...",
"focusEntityIds": "...",
"from": "...",
"nameHint": "...",
"ontologyClass": "...",
"to": "...",
"type": "...",
"userId": "..."
},
"skillId": "string"
}curl
curl -X POST 'http://localhost:8080/v1/skills/generate' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Run enqueued; returns runId
scope.type required
{
"error": "scope.type required"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}feature_disabled (skill_distillation)
Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Audit the workspace's skills: steps and claims that lost their grounding, skills with no validation component, the drifted set, and two reuse signals. reuseCandidates are skill groups sharing a sub-procedure-sized subset of grounding sources, a signal to compose; duplicateSkills are groups whose grounding is largely coextensive (overlapRatio of at least 0.8 of the smaller skill), a signal to archive one. Each group carries skillIds, skillNames, sharedSourceCount, sampleSources and overlapRatio. Requires skills:read.
curl
curl 'http://localhost:8080/v1/skills/governance' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}List the workspace's published skills, each with its name, served version, digest, whether it is attested and a download URL: the discovery surface for agentskills.io-compatible runtimes. Requires skills:read.
curl
curl 'http://localhost:8080/v1/skills/published' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Apply one approve or reject decision to up to 100 skills. Ids are deduplicated, preserving order. Per-skill semantics match the single review endpoint, and a skill that cannot be reviewed is reported in its own result row rather than failing the request. Requires skills:write.
Request Body
{
"decision": "string",
"feedback": "string",
"skillIds": [
"string"
]
}curl
curl -X POST 'http://localhost:8080/v1/skills/review/bulk' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
empty list, more than 100 skills, or an invalid decision
{
"error": "empty list, more than 100 skills, or an invalid decision"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}List the workspace's recent distillation and scan runs, newest first. Each row carries the same fields as GET /v1/skills/runs/{id}, plus kind, batchId and skillDeleted (true when the run's skill was deleted after the run). Requires skills:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | optional | Max runs to return (1-100, default 20) |
batchId | query | string | optional | Filter to the runs of one Create-all batch |
curl
curl 'http://localhost:8080/v1/skills/runs' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
invalid_limit
{
"error": "invalid_limit",
"max": 200,
"message": "limit must be an integer between 1 and 200"
}Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Poll a distillation run's status, progress, and final grounding and coverage scores. Requires skills:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Run ID |
curl
curl 'http://localhost:8080/v1/skills/runs/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Segment the scoped memory into candidate procedure sub-scopes without generating any skill; poll the returned run, whose result lists the candidates. Requires skills:write.
Request Body
{
"scope": {
"conversationIds": "...",
"entityId": "...",
"focusEntityIds": "...",
"from": "...",
"nameHint": "...",
"ontologyClass": "...",
"to": "...",
"type": "...",
"userId": "..."
}
}curl
curl -X POST 'http://localhost:8080/v1/skills/scan' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Scan enqueued; returns runId
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}feature_disabled (skill_distillation or skill_autosuggest)
Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Permanently delete a skill of any status, draft or published, with all its versions. The memory the skill was distilled from is not changed, and its distillation runs stay in the activity list with skillDeleted set. A published skill leaves the published feed; copies already downloaded are not affected. Returns 409 skill_has_callers while another skill's procedure calls it, and 409 distillation_in_progress while a distillation run for it is still in flight. Requires skills:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
curl
curl -X DELETE 'http://localhost:8080/v1/skills/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
{status: deleted, skillId}
skill not found
{
"error": "skill not found"
}{code: skill_has_callers, callers: [{id, name}]} or {code: distillation_in_progress, runIds}; also the workspace database removed (database_unavailable) or deprovisioned (workspace_not_provisioned)
The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request - only its owner can fix it: check that it is running and that the connection on the Database page is correct"
}Internal error
{
"error": "Internal error"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}A skill, its rendered SKILL.md and its version history. The response adds attested and coherenceCommunities (the number of step communities the distiller detected), and each versions[] entry carries attested and reviewFeedback. Requires skills:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
curl
curl 'http://localhost:8080/v1/skills/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The skill package as an inline zip: SKILL.md, references/*.md and provenance.json, plus attestation.jws when the version was signed at publish time. Defaults to the served version: the published one, else the latest. Requires skills:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
version | query | string | optional | Skill version ID |
curl
curl 'http://localhost:8080/v1/skills/{id}/download' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Compare a version's recorded provenance against the live graph and flag claims whose source nodes were deleted or merged, a signal to re-distill. Defaults to the served version: the published one, else the latest. Requires skills:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
version | query | string | optional | Skill version ID |
curl
curl 'http://localhost:8080/v1/skills/{id}/drift' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Validate a proposed edit ({ops, version?}) against the served version's graph and return {valid, errors, steps}. Never mutates. Requires skills:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
curl
curl -X POST 'http://localhost:8080/v1/skills/{id}/edit' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Re-validate the edit ops against the served version and, on success, enqueue a run that applies them and cuts a new in_review version; the published version keeps serving until the new one is reviewed. Returns {runId, status}; an invalid edit returns 400 {valid: false, errors}. Requires skills:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
curl
curl -X POST 'http://localhost:8080/v1/skills/{id}/edit/commit' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Edit enqueued; returns runId
invalid edit
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}feature_disabled (skill_distillation)
Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Resolve each claim of a skill version to the decisions, entities and messages that grounded it. Defaults to the served version: the published one, else the latest. Requires skills:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
version | query | string | optional | Skill version ID |
curl
curl 'http://localhost:8080/v1/skills/{id}/explain-provenance' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Lift a contiguous set of steps of the served version into a new sub-procedure skill, referenced from the parent by a call step. Asynchronous: returns a runId to poll. Requires skills:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
curl
curl -X POST 'http://localhost:8080/v1/skills/{id}/extract-subprocedure' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Extraction enqueued; returns runId
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}feature_disabled (skill_distillation, or skill_composition when composition is off)
Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Publish the latest version. It must be review-approved (409 otherwise), and every sub-procedure it calls must itself be published (409 otherwise). When an attestation key is configured, publishing signs a detached JWS over the version digest. Requires skills:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
curl
curl -X POST 'http://localhost:8080/v1/skills/{id}/publish' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
not approved
The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The human-review gate: approve or reject the latest version. An approved version may then be published; a rejected skill returns to draft. A decision is accepted only while the latest version is pending review, so a second review returns 409. Requires skills:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
Request Body
{
"decision": "string",
"feedback": "string"
}curl
curl -X POST 'http://localhost:8080/v1/skills/{id}/review' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
not pending review
The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Re-ground a single drifted step of the latest version, for example re-pointing a merged entity, under the workspace lock, and cut a patch version that leaves the other reviewed steps untouched. Asynchronous: returns a runId to poll. Requires skills:write.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
stepId | path | string | required | Step ID |
curl
curl -X POST 'http://localhost:8080/v1/skills/{id}/steps/{stepId}/repair' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Repair enqueued; returns runId
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}feature_disabled (skill_distillation)
Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Verify a version's stored attestation against the attestation public key and confirm it binds the version's current digest, which detects tampering or a stale attestation. Returns verified, plus reason, versionId and digest. Defaults to the served version: the published one, else the latest. The key is also published at /.well-known/skill-attest-jwks.json for offline verification. Requires skills:read.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | Skill ID |
version | query | string | optional | Skill version ID |
curl
curl 'http://localhost:8080/v1/skills/{id}/verify' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned ({error: workspace_not_provisioned, status: deprovisioned}) - reprovision or update the external connection",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct
{
"error": "The workspace's external database failed the request (external_database_error) - only its owner can fix it: check that it is running and that the connection on the Database page is correct",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace database unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Query Console
Runs caller-supplied Cypher against the tenant's graph database with Neo4j's READ access mode. Writes are rejected server-side. Returns one page of up to 1000 rows starting at offset, at most 10,000 rows deep: hasMore reports rows past the page, and nextOffset is where the next page starts when it is within reach. Each page re-runs the statement, so add ORDER BY for a stable order across pages. A page ends early when its rows reach 16 MB, and a row larger than that is refused with code result_too_large, as is a whole result larger than that from a database older than Neo4j 2025.12, which cannot stream. stats are zero unless the statement finished within the page. To read past row 10,000, add SKIP to the statement. Requires the memory:read scope.
Request Body
{
"cypher": "string",
"offset": 0,
"params": {}
}curl
curl -X POST 'http://localhost:8080/v1/query' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"cypher": ""
}'Responses
Returns columns, rows, stats
{
"columns": [
"string"
],
"hasMore": false,
"nextOffset": 0,
"offset": 0,
"rows": [
{}
],
"stats": {}
}Invalid query or offset, write operation attempted, Cypher error, or result too large
{
"code": "result_too_large",
"error": "Invalid query or offset, write operation attempted, Cypher error, or result too large"
}Workspace database removed (database_unavailable), or workspace deprovisioned
{
"error": "Workspace database removed (database_unavailable), or workspace deprovisioned",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}The workspace's external database failed the request (external_database_error)
{
"error": "The workspace's external database failed the request (external_database_error)"
}Internal error
{
"error": "Internal error"
}Workspace still provisioning (workspace_not_provisioned); or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error
{
"error": "Workspace still provisioning (workspace_not_provisioned); or the workspace database is unreachable (db_unreachable); also returned as {error: workspace_not_provisioned, status, statusMessage} while the workspace is pending/provisioning/error",
"message": "the workspace database is unreachable or has been removed; reprovision it or update the external connection",
"status": "deprovisioned",
"statusMessage": "provisioning failed: quota exceeded",
"workspaceId": "b3f1c2d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d"
}Workspace Management
Join the workspace of the invitation that the invite token belongs to, with the invited role. Any signed-in user who holds the token can accept it, once. Requires a user token; an API key is refused.
Request Body
{
"token": "string"
}curl
curl -X POST 'http://localhost:8080/v1/invitations/accept' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
{
"invitation": {
"createdAt": "...",
"email": "...",
"expiresAt": "...",
"id": "...",
"invitedBy": "...",
"invitedByName": "...",
"inviteeUserId": "...",
"role": "...",
"status": "...",
"workspaceId": "...",
"workspaceName": "..."
},
"status": "accepted",
"workspace_id": "string"
}token is required
{
"error": "token is required"
}user token required
{
"error": "user token required"
}invitation not found or no longer open
{
"error": "invitation not found or no longer open"
}Return the invitation the invite token belongs to without accepting it, so the holder can see the workspace, inviter and role before joining. Requires a user token; an API key is refused.
Request Body
{
"token": "string"
}curl
curl -X POST 'http://localhost:8080/v1/invitations/lookup' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
{
"invitation": {
"createdAt": "...",
"email": "...",
"expiresAt": "...",
"id": "...",
"invitedBy": "...",
"invitedByName": "...",
"inviteeUserId": "...",
"role": "...",
"status": "...",
"workspaceId": "...",
"workspaceName": "..."
}
}token is required
{
"error": "token is required"
}user token required
{
"error": "user token required"
}invitation not found or no longer open
{
"error": "invitation not found or no longer open"
}Return the invitations the authenticated user can accept: those addressed to the user's Auth0 subject or verified email, still pending and not expired, for workspaces the user is not yet a member of.
curl
curl 'http://localhost:8080/v1/users/me/invitations' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"invitations": [
"..."
]
}no user identity
{
"error": "no user identity"
}Join the workspace with the invited role. The invitation must be addressed to the caller's Auth0 subject or verified email. Accepting never changes the role of an existing member. Requires a user token; an API key is refused.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invitationId | path | string | required | Invitation ID |
curl
curl -X POST 'http://localhost:8080/v1/users/me/invitations/{invitationId}/accept' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"invitation": {
"createdAt": "...",
"email": "...",
"expiresAt": "...",
"id": "...",
"invitedBy": "...",
"invitedByName": "...",
"inviteeUserId": "...",
"role": "...",
"status": "...",
"workspaceId": "...",
"workspaceName": "..."
},
"status": "accepted",
"workspace_id": "string"
}user token required
{
"error": "user token required"
}invitation not found or no longer open
{
"error": "invitation not found or no longer open"
}Close an invitation addressed to the caller. Requires a user token.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invitationId | path | string | required | Invitation ID |
curl
curl -X POST 'http://localhost:8080/v1/users/me/invitations/{invitationId}/decline' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"status": "updated"
}user token required
{
"error": "user token required"
}invitation not found or no longer open
{
"error": "invitation not found or no longer open"
}List the workspaces the authenticated user is a member of. A workspace-bound API key returns only its bound workspace; an admin key or user token returns all. Requires no workspace:admin scope.
curl
curl 'http://localhost:8080/v1/users/me/workspaces' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"workspaces": [
"..."
]
}no user identity
{
"error": "no user identity"
}Remove the caller's own membership. Any member can leave; the last owner cannot. Requires a user token.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId | path | string | required | Workspace ID |
curl
curl -X DELETE 'http://localhost:8080/v1/users/me/workspaces/{workspaceId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"status": "updated"
}the last owner cannot leave
{
"error": "the last owner cannot leave"
}user token required
{
"error": "user token required"
}not a member of this workspace
{
"error": "not a member of this workspace"
}Delete the current workspace. Owner only, with a user token. A user's last remaining workspace cannot be deleted. A managed workspace's database is deleted with it, permanently. While a database copy, snapshot restore or move onto the managed pool runs, the delete is refused with 409 copy_in_progress. If the tenant's access to it cannot be removed, the workspace is kept and the call answers 503; once access is removed the call succeeds, and a database Aura does not delete at once is queued and retried by the worker.
curl
curl -X DELETE 'http://localhost:8080/v1/workspace' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"status": "updated"
}cannot delete the only workspace you own
{
"error": "cannot delete the only workspace you own"
}insufficient workspace role
{
"error": "insufficient workspace role"
}workspace not found
{
"error": "workspace not found"
}copy_in_progress
{
"error": "copy_in_progress"
}database_delete_failed
{
"error": "database_delete_failed"
}Return details for the workspace identified by the X-Workspace-Id header.
curl
curl 'http://localhost:8080/v1/workspace' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"createdAt": "string",
"dbMode": "managed",
"id": "string",
"managedDbInactivityDays": 0,
"name": "string",
"plan": "string",
"status": "active",
"statusMessage": "string"
}no workspace identity
{
"error": "no workspace identity"
}workspace not found
{
"error": "workspace not found"
}Rename the current workspace. Names are unique per owner. Requires the workspace:admin scope and a user token whose workspace role is owner or admin — an API key is rejected with 403.
Request Body
{
"name": "renamed-workspace"
}curl
curl -X PUT 'http://localhost:8080/v1/workspace' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
{
"status": "updated"
}invalid request body
{
"error": "invalid request body"
}insufficient workspace role
{
"error": "insufficient workspace role"
}name_taken (includes existing_workspace_id)
{
"error": "name_taken (includes existing_workspace_id)"
}List the snapshots the workspace's database can be restored from, newest first. A snapshot is written when a managed database is deleted after a period without activity, and is kept until expiresAt. Restore one with POST /v1/workspace/provision {"restoreFromArchive": "<id>"}. Requires a user token or Admin key whose workspace role is owner or admin.
curl
curl 'http://localhost:8080/v1/workspace/archives' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"archives": [
"..."
]
}insufficient workspace role
{
"error": "insufficient workspace role"
}Return the workspace's database mode and connection info. The password is never included. Managed mode returns connections.rw once the database exists; external mode returns a single connection object instead. Whether the database serves is the workspace's status (GET /v1/workspace).
curl
curl 'http://localhost:8080/v1/workspace/database' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"connection": {
"database": "...",
"expiresAt": "...",
"password": "...",
"uri": "...",
"username": "..."
},
"connections": {
"ro": "...",
"rw": "..."
},
"mode": "managed"
}Unauthorized
{
"error": "Unauthorized"
}workspace not found
{
"error": "workspace not found"
}Switch the workspace between a managed database and an external Neo4j. Switching to external tests the connection and creates the schema before anything is stored; on failure the workspace keeps its current mode. Switching to managed provisions synchronously, reusing the workspace's previous managed database while it still exists. Data is not copied: use the database copy endpoints for that. Requires a user token whose workspace role is owner or admin.
Request Body
{
"connection": {
"database": "...",
"expiresAt": "...",
"password": "...",
"uri": "...",
"username": "..."
},
"mode": "external"
}curl
curl -X PUT 'http://localhost:8080/v1/workspace/database' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
{
"mode": "managed",
"reused": false,
"status": "active"
}invalid mode or connection, or external_target_not_allowed (a host that serves this service's managed databases)
{
"error": "invalid mode or connection, or external_target_not_allowed (a host that serves this service's managed databases)"
}insufficient workspace role, or workspace_limit_reached
{
"error": "insufficient workspace role, or workspace_limit_reached"
}workspace not found, or being deleted
{
"error": "workspace not found, or being deleted"
}copy_in_progress, database_in_use (another workspace uses or is copying into that database), database_busy, external_database (switched back to external while provisioning), or managed_provisioning_disabled (mode managed on a deployment with no managed databases)
{
"error": "copy_in_progress, database_in_use (another workspace uses or is copying into that database), database_busy, external_database (switched back to external while provisioning), or managed_provisioning_disabled (mode managed on a deployment with no managed databases)"
}external database connection failed
{
"error": "external database connection failed"
}too_many_attempts (external connection attempts are limited per user)
{
"error": "too_many_attempts (external connection attempts are limited per user)"
}external database schema init failed
{
"error": "external database schema init failed"
}switched to managed, but provisioning did not finish (retry); workspace_limit_unavailable; external_target_busy (another request is adopting that database; retry); or external_target_unverified (retry)
{
"error": "switched to managed, but provisioning did not finish (retry); workspace_limit_unavailable; external_target_busy (another request is adopting that database; retry); or external_target_unverified (retry)"
}Return the most recent database-copy job for the workspace (the optional data copy that runs when switching database mode), or 204 with no body when none exists. Polled by the dashboard for progress. status switched_empty means the switch completed into an empty managed database because the copy failed, and the source external database still holds the data; failureMessage accompanies the failure states. Requires a user token whose workspace role is owner or admin.
curl
curl 'http://localhost:8080/v1/workspace/database/copy' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"createdAt": "string",
"failureMessage": "string",
"id": "string",
"phase": "copying",
"sourceMode": "managed",
"statementsExecuted": 420,
"statementsTotal": 1000,
"status": "running",
"targetMode": "external",
"updatedAt": "string",
"wipeDestination": false,
"workspaceId": "string"
}no database copy for this workspace
Enqueue a copy of the workspace's data into its new database. It runs as a background job and does not switch the mode up front: the switch is the copy's final step. Preflight is re-run server-side. wipeDestination must be true to overwrite a non-empty destination. Returns 409 copy_in_progress when a copy is already running, 409 destination_not_empty when a wipe is needed but not confirmed, and 422 when preflight fails. Requires a user token whose workspace role is owner or admin.
Request Body
{
"connection": {
"database": "...",
"expiresAt": "...",
"password": "...",
"uri": "...",
"username": "..."
},
"targetMode": "external",
"wipeDestination": false
}curl
curl -X POST 'http://localhost:8080/v1/workspace/database/copy' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Accepted
{
"id": "string",
"status": "pending",
"targetMode": "external"
}targetMode is required, or external_target_not_allowed
{
"error": "targetMode is required, or external_target_not_allowed"
}insufficient workspace role, or workspace_limit_reached
{
"error": "insufficient workspace role, or workspace_limit_reached"
}copy_in_progress, destination_not_empty, database_in_use, database_busy, or managed_provisioning_disabled (this deployment has no managed databases)
{
"error": "copy_in_progress, destination_not_empty, database_in_use, database_busy, or managed_provisioning_disabled (this deployment has no managed databases)"
}preflight failed
{
"error": "preflight failed"
}too_many_attempts
{
"error": "too_many_attempts"
}workspace_limit_unavailable, external_target_busy or external_target_unverified (retry)
{
"error": "workspace_limit_unavailable, external_target_busy or external_target_unverified (retry)"
}Check, without enqueuing anything, whether the workspace's data can be copied into the database it is switching to. external→managed verifies the source is reachable and has APOC, which the export needs; managed→external tests the destination and reports its node count, which drives the wipe confirmation. connection is required only for targetMode external. canCopy is the one flag to read, with reason set when it is false; a read error against the destination reports canCopy false, never an empty database, so a non-empty destination is never silently overwritten. Requires a user token whose workspace role is owner or admin.
Request Body
{
"connection": {
"database": "...",
"expiresAt": "...",
"password": "...",
"uri": "...",
"username": "..."
},
"targetMode": "managed"
}curl
curl -X POST 'http://localhost:8080/v1/workspace/database/copy/preflight' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
{
"canCopy": true,
"destNodeCount": 1234,
"destReachable": false,
"direction": "external_to_managed",
"reason": "string",
"requiresWipe": false,
"sourceHasApoc": false,
"sourceReachable": false
}targetMode is required, or external_target_not_allowed
{
"error": "targetMode is required, or external_target_not_allowed"
}managed_provisioning_disabled (this deployment has no managed databases)
{
"error": "managed_provisioning_disabled (this deployment has no managed databases)"
}too_many_attempts
{
"error": "too_many_attempts"
}external_target_unverified (retry)
{
"error": "external_target_unverified (retry)"
}Return the database configuration with the password included. Requires a user token whose workspace role is owner or admin — an API key is rejected with 403, so a leaked key cannot read the database password. Every reveal is audit-logged.
curl
curl 'http://localhost:8080/v1/workspace/database/credentials' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"connection": {
"database": "...",
"expiresAt": "...",
"password": "...",
"uri": "...",
"username": "..."
},
"connections": {
"ro": "...",
"rw": "..."
},
"mode": "managed"
}insufficient workspace role
{
"error": "insufficient workspace role"
}workspace not found
{
"error": "workspace not found"
}Export the workspace database's schema and data as a Cypher script (apoc.export.cypher.all), returned as a file attachment. The database must have APOC installed. Requires a user token whose workspace role is owner or admin.
curl
curl -X POST 'http://localhost:8080/v1/workspace/database/export' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
Cypher script
"string"
insufficient workspace role
{
"error": "insufficient workspace role"
}export failed, for example because APOC is missing
{
"error": "export failed, for example because APOC is missing"
}Replay a .cypher script, such as one from the export endpoint, against the workspace database. Statements run one at a time in autocommit and execution stops at the first failure, so the import is not atomic: statements before the failing one stay committed. Restore into an empty database. Limits: 10 MB and 10,000 statements. Requires a user token whose workspace role is owner or admin.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
file | formData | file | required | Cypher script |
curl
curl -X POST 'http://localhost:8080/v1/workspace/database/import' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"durationMs": 5321,
"statementsExecuted": 412,
"statementsSkipped": 3,
"stats": {
"labelsAdded": "...",
"labelsRemoved": "...",
"nodesCreated": "...",
"nodesDeleted": "...",
"propertiesSet": "...",
"relationshipsCreated": "...",
"relationshipsDeleted": "...",
"skipped": "..."
}
}missing file, unparseable script or too many statements
{
"error": "missing file, unparseable script or too many statements"
}insufficient workspace role
{
"error": "insufficient workspace role"
}a statement failed
{
"cypherCode": "Neo.ClientError.Schema.ConstraintValidationFailed",
"error": "a statement failed",
"statementIndex": 17,
"statementSnippet": "string"
}Test reachability of an external Neo4j connection without storing anything. The URI is SSRF-validated. uri, username and password are required; a blank database resolves to the instance's home database. A connection that fails returns 200 with success false; a rejected URI returns 400. A host that serves this service's managed databases is refused with 400 external_target_not_allowed. Connection attempts to external databases (this test, the switch to external and the copy preflight and start) are limited per user; past the limit they return 429 too_many_attempts. Requires a user token whose workspace role is owner or admin.
Request Body
{
"database": "neo4j",
"password": "secret",
"uri": "neo4j+s://abc123.databases.neo4j.io",
"username": "neo4j"
}curl
curl -X POST 'http://localhost:8080/v1/workspace/database/test' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
{
"error": "connection failed",
"success": false
}invalid uri, or external_target_not_allowed
{
"error": "invalid uri, or external_target_not_allowed"
}insufficient workspace role, or not a user token
{
"error": "insufficient workspace role, or not a user token"
}too_many_attempts
{
"error": "too_many_attempts"
}external_target_unverified (retry)
{
"error": "external_target_unverified (retry)"
}Return the workspace's open invitations, newest first. An invitation past its expiry has status expired. Requires a user token whose workspace role is owner or admin.
curl
curl 'http://localhost:8080/v1/workspace/invitations' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"invitations": [
"..."
]
}insufficient workspace role
{
"error": "insufficient workspace role"
}Close a pending invitation so it can no longer be accepted. Requires a user token whose workspace role is owner or admin.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
invitationId | path | string | required | Invitation ID |
curl
curl -X DELETE 'http://localhost:8080/v1/workspace/invitations/{invitationId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"status": "updated"
}insufficient workspace role
{
"error": "insufficient workspace role"
}invitation not found
{
"error": "invitation not found"
}Return all members of the workspace.
curl
curl 'http://localhost:8080/v1/workspace/members' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"members": [
"..."
]
}Unauthorized
{
"error": "Unauthorized"
}Invite a user to the workspace by email or Auth0 subject (user_id), or change an existing member's role. A user who is not a member becomes one only by accepting the invitation, so this call never adds a member directly. The answer is the same whether or not the invitee has an account. An email invitation can be accepted by a user whose Auth0 email is that address and verified; a user_id invitation by that user. Either can also be accepted with invite_token, by any signed-in user who holds it, so send the token only to the invitee. Inviting the same target again replaces the earlier invitation. Invitations expire after 7 days. Requires a user token whose workspace role is owner or admin. Only an owner can change another owner's role, and the last owner cannot be demoted.
Request Body
{
"email": "ivy@example.com",
"role": "developer",
"user_id": "auth0|65f1c2d4e5f6a7b8c9d0e1f2"
}curl
curl -X POST 'http://localhost:8080/v1/workspace/members' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
an existing member's role was changed
{
"status": "updated"
}an invitation was created
{
"invitation": {
"createdAt": "...",
"email": "...",
"expiresAt": "...",
"id": "...",
"invitedBy": "...",
"invitedByName": "...",
"inviteeUserId": "...",
"role": "...",
"status": "...",
"workspaceId": "...",
"workspaceName": "..."
},
"invite_token": "string",
"invite_url": "https://memory.neo4jlabs.com/invite/3f9a…",
"status": "invited"
}role is required and must be admin, developer or viewer; give exactly one of email or user_id
{
"error": "role is required and must be admin, developer or viewer; give exactly one of email or user_id"
}insufficient workspace role, or an owner-protection rule
{
"error": "insufficient workspace role, or an owner-protection rule"
}Remove a user from the workspace. Requires a user token whose workspace role is owner or admin. The last owner cannot be removed.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
userId | path | string | required | User ID |
curl
curl -X DELETE 'http://localhost:8080/v1/workspace/members/{userId}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
{
"status": "updated"
}cannot remove the last owner of a workspace
{
"error": "cannot remove the last owner of a workspace"
}insufficient workspace role
{
"error": "insufficient workspace role"
}Create the workspace's managed database and answer once it serves, usually within a minute, occasionally two or three. When the request budget runs out while the database is still starting, the call answers 202 with retry=true: call again, with the same body, and that call continues where this one stopped. Idempotent: a workspace whose database already answers returns at once, and a call cut short (client timeout, disconnect) is completed by the next one, which reuses the work already done. To bring back a database deleted for inactivity, name one of GET /v1/workspace/archives in restoreFromArchive. The call then answers status "restoring": the new database is filled from the snapshot in the background, writes are refused with 503 writes_paused until it finishes, and GET /v1/workspace reports "active" (or "error" with a statusMessage) when it does. A call without a body on a workspace with a restore that has not started cancels it. Requires a user token or Admin key whose workspace role is owner or admin.
Request Body
{
"restoreFromArchive": "Jm9xk2Lr0a8Q"
}curl
curl -X POST 'http://localhost:8080/v1/workspace/provision' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
status is active, or restoring when a snapshot is being loaded
{
"adopted": false,
"message": "string",
"retry": false,
"status": "active"
}status is provisioning and retry is true: call again
{
"adopted": false,
"message": "string",
"retry": false,
"status": "active"
}invalid_body
{
"error": "invalid_body"
}insufficient workspace role
{
"error": "insufficient workspace role"
}workspace not found, or archive_not_found
{
"error": "workspace not found, or archive_not_found"
}external_database, copy_in_progress (a restore is already running), restore_not_allowed (the workspace has a database), or managed_provisioning_disabled (this deployment has no managed databases)
{
"error": "external_database, copy_in_progress (a restore is already running), restore_not_allowed (the workspace has a database), or managed_provisioning_disabled (this deployment has no managed databases)"
}provisioning_failed (retry) or no_capacity
{
"error": "provisioning_failed (retry) or no_capacity"
}Return the workspace's typed-relation allowlist configuration, falling back to system defaults when unset, plus what the workspace's active ontology contributes. allowed_types is what the workspace stored and the only field PUT writes; ontology_types is what the active ontology declares, derived on every read; effective_allowed_types is their union and the set a relationship write is judged against. A type outside it collapses onto fallback_type, with the original name kept in the edge's predicate property. ontology_types is omitted when the workspace has no active ontology or the lookup failed.
curl
curl 'http://localhost:8080/v1/workspace/relations' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"allowed_types": [
"string"
],
"custom_descriptions": {},
"effective_allowed_types": [
"string"
],
"enabled": true,
"fallback_type": "RELATED_TO",
"min_confidence": 0.5,
"ontology_types": [
"string"
]
}Unauthorized
{
"error": "Unauthorized"
}Set the workspace's typed-relation allowlist. The body is merged on top of the system defaults, so a partial body is safe. Entries in allowed_types are case-insensitive and normalized to UPPER_SNAKE_CASE; entries containing characters outside [A-Za-z0-9_-/.,] are dropped at validation. Types declared by the workspace's active ontology are added automatically at read time and should not be listed here: sending them stores a snapshot that stops tracking the ontology once it is edited. Requires a user token whose workspace role is owner or admin — an API key is rejected with 403 user token required, even one carrying workspace:admin.
Request Body
{
"allowed_types": [
"string"
],
"custom_descriptions": {},
"enabled": true,
"fallback_type": "RELATED_TO",
"min_confidence": 0.5
}curl
curl -X PUT 'http://localhost:8080/v1/workspace/relations' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
The stored config plus the resulting effective allowlist
{
"allowed_types": [
"string"
],
"custom_descriptions": {},
"effective_allowed_types": [
"string"
],
"enabled": true,
"fallback_type": "RELATED_TO",
"min_confidence": 0.5,
"ontology_types": [
"string"
]
}Malformed body
{
"error": "Malformed body"
}No workspace identity
{
"error": "No workspace identity"
}Requires a user token with the owner or admin workspace role
{
"error": "Requires a user token with the owner or admin workspace role"
}Bring back a workspace whose database failed or was deleted after the inactivity window. Identical to POST /v1/workspace/provision: synchronous, idempotent, and a workspace whose database still answers is left as it is. Requires a user token or Admin key whose workspace role is owner or admin.
curl
curl -X POST 'http://localhost:8080/v1/workspace/reprovision' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
status is active
{
"adopted": false,
"message": "string",
"retry": false,
"status": "active"
}status is provisioning and retry is true: call again
{
"adopted": false,
"message": "string",
"retry": false,
"status": "active"
}insufficient workspace role
{
"error": "insufficient workspace role"
}external_database, or managed_provisioning_disabled (this deployment has no managed databases)
{
"error": "external_database, or managed_provisioning_disabled (this deployment has no managed databases)"
}provisioning_failed (retry) or no_capacity
{
"error": "provisioning_failed (retry) or no_capacity"
}Return the workspace's entity-resolution configuration, falling back to system defaults when unset.
curl
curl 'http://localhost:8080/v1/workspace/resolution' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"auto_merge_threshold": 0.92,
"embedding_weight": 0.6,
"enabled": true,
"fuzzy_min_score": 0.5,
"fuzzy_weight": 0.4,
"review_threshold": 0.78,
"semantic_min_score": 0.55,
"top_k": 25,
"type_strict": true
}Unauthorized
{
"error": "Unauthorized"
}Set the workspace's entity-resolution thresholds. The body is merged on top of the system defaults, so a partial body is safe. Validation auto-corrects pathological combinations: a review_threshold above auto_merge_threshold resets both to defaults rather than storing a band that can never be entered, and embedding_weight and fuzzy_weight are renormalized to sum to 1. Requires a user token whose workspace role is owner or admin — an API key is rejected with 403 user token required, even one carrying workspace:admin.
Request Body
{
"auto_merge_threshold": 0.92,
"embedding_weight": 0.6,
"enabled": true,
"fuzzy_min_score": 0.5,
"fuzzy_weight": 0.4,
"review_threshold": 0.78,
"semantic_min_score": 0.55,
"top_k": 25,
"type_strict": true
}curl
curl -X PUT 'http://localhost:8080/v1/workspace/resolution' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
The stored config, after validation
{
"auto_merge_threshold": 0.92,
"embedding_weight": 0.6,
"enabled": true,
"fuzzy_min_score": 0.5,
"fuzzy_weight": 0.4,
"review_threshold": 0.78,
"semantic_min_score": 0.55,
"top_k": 25,
"type_strict": true
}Malformed body
{
"error": "Malformed body"
}No workspace identity
{
"error": "No workspace identity"
}Requires a user token with the owner or admin workspace role
{
"error": "Requires a user token with the owner or admin workspace role"
}Create a new workspace with status "pending". A managed workspace has no database until POST /v1/workspace/provision, which callers chain straight after this one. Workspace names are unique per owner.
Request Body
{
"name": "my-workspace"
}curl
curl -X POST 'http://localhost:8080/v1/workspaces' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Created
{
"id": "string",
"name": "string",
"status": "pending"
}name is required
{
"error": "name is required"
}workspace_limit_reached
{
"error": "workspace_limit_reached"
}name_taken (includes existing_workspace_id)
{
"error": "name_taken (includes existing_workspace_id)"
}workspace_limit_unavailable: the managed-workspace limit could not be checked; retry
{
"error": "workspace_limit_unavailable: the managed-workspace limit could not be checked; retry"
}Feedback
Persists a feedback submission (bug, feature request, question, or general) to the operational database with auto-captured context.
Request Body
{
"clientErrors": [
"..."
],
"clientMeta": {},
"contactEmail": "string",
"context": {
"apiVersion": "...",
"appVersion": "...",
"capturedAt": "...",
"connection": "...",
"deviceMemory": "...",
"devicePixelRatio": "...",
"hardwareConcurrency": "...",
"languages": "...",
"locale": "...",
"online": "...",
"pageUrl": "...",
"perf": "...",
"referrer": "...",
"route": "...",
"screen": "...",
"theme": "...",
"timezone": "...",
"userAgent": "...",
"userAgentData": "...",
"viewport": "...",
"workspaceDbMode": "...",
"workspaceId": "...",
"workspaceRole": "...",
"workspaceStatus": "..."
},
"message": "string",
"rating": 0,
"sentiment": "string",
"type": "string"
}curl
curl -X POST 'http://localhost:8080/v1/feedback' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"message": "",
"type": ""
}'Responses
Created
validation error
{
"error": "validation error"
}payload too large
{
"error": "payload too large"
}rate limited
{
"error": "rate limited"
}feature disabled
{
"error": "feature disabled"
}Returns whether in-app feedback submission is enabled for this deployment.
curl
curl 'http://localhost:8080/v1/feedback/config' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
{\"enabled\": true}
System and Releases
Published release notes, newest first. Unauthenticated; serves a compile-time constant.
curl
curl 'http://localhost:8080/v1/changelog' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"released": "string",
"releases": [
"..."
],
"version": "string"
}Report the health of each NAMS service and the state of the background processing queues: length, consumer lag, pending entries and a sample of recent entries with sensitive fields removed. Used by the dashboard's status view. Requires the memory:read scope.
curl
curl 'http://localhost:8080/v1/status' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
services and streams
Unauthorized
{
"error": "Unauthorized"
}Release version and build commit of the running service. Unauthenticated. The version only moves when a release carries user-facing news, so commit is the field that identifies a deployment.
curl
curl 'http://localhost:8080/v1/version' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"commit": "string",
"environment": "string",
"released": "string",
"version": "string"
}Connecting to the MCP Server
The MCP server uses Streamable HTTP transport and is available at http://localhost:9090/mcp. Pick your client below for a copy-paste config.
Claude Desktop's config does not accept a remote URL directly. Use the mcp-remote stdio bridge for static API keys, or open Settings -> Connectors -> Add custom connector for OAuth.
~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows)
{
"mcpServers": {
"nams-memory": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"http://localhost:9090/mcp",
"--header",
"Authorization:Bearer ${NAMS_API_KEY}"
],
"env": {
"NAMS_API_KEY": "nams_YOUR_API_KEY"
}
}
}
}Save, fully quit Claude Desktop (Cmd/Ctrl+Q), reopen it. The nams-memory server appears under the tools (hammer) icon. Ask: 'List the NAMS memory tools you have.'
Windows note: keep 'Authorization:Bearer' with no space -- mcp-remote arguments break on whitespace there.
Anthropic's CLI coding agent. Native streamable-HTTP MCP and OAuth discovery.
Run from any project directory:
claude mcp add --transport http --scope project nams \ http://localhost:9090/mcp \ --header "Authorization: Bearer nams_YOUR_API_KEY"
Start a session with `claude`, run `/mcp`, confirm `nams` is connected. Omit --header to use OAuth instead -- the first /mcp call opens a browser for PKCE.
OpenAI's terminal coding agent. Recent versions support remote streamable-HTTP MCP servers natively via TOML.
Edit ~/.codex/config.toml and add a server table.
[mcp_servers.nams] url = "http://localhost:9090/mcp" bearer_token_env_var = "NAMS_API_KEY"
Set NAMS_API_KEY in your shell, start a new Codex session, run `/mcp` to confirm `nams` is loaded. Older Codex installs are stdio-only -- wrap with `npx -y mcp-remote` instead.
Google's terminal coding agent. Use httpUrl (not url -- url silently routes through SSE, which this server does not expose).
Edit ~/.gemini/settings.json (or run `gemini mcp add -s user nams ...`):
{
"mcpServers": {
"nams": {
"httpUrl": "http://localhost:9090/mcp",
"headers": {
"Authorization": "Bearer $NAMS_API_KEY"
},
"timeout": 5000
}
}
}Set NAMS_API_KEY in your shell, restart any active Gemini session, run `/mcp`. Omit `headers` to trigger OAuth discovery on the server's 401 response.
GitHub's terminal coding agent. Native streamable-HTTP MCP -- add via `/mcp add` or edit the config file. Each server needs an explicit "type": "http".
Edit ~/.copilot/mcp-config.json:
{
"mcpServers": {
"nams": {
"type": "http",
"url": "http://localhost:9090/mcp",
"headers": {
"Authorization": "Bearer ${NAMS_API_KEY}"
}
}
}
}Set NAMS_API_KEY in your shell, run `/mcp` to confirm `nams` is listed (no restart needed). This is the standalone `copilot` CLI, not the older `gh copilot` extension.
AI code editor. Native streamable HTTP and OAuth discovery.
Edit ~/.cursor/mcp.json (global) or .cursor/mcp.json (project root):
{
"mcpServers": {
"nams": {
"url": "http://localhost:9090/mcp",
"headers": {
"Authorization": "Bearer ${env:NAMS_API_KEY}"
}
}
}
}Set NAMS_API_KEY in your shell, reload Cursor (Cmd/Ctrl+Shift+P -> Developer: Reload Window). Open Settings -> MCP and confirm `nams` is connected. Drop `headers` to use OAuth.
Codeium's Cascade-powered editor. Uses serverUrl (not url) for remote MCP endpoints.
Edit ~/.codeium/windsurf/mcp_config.json:
{
"mcpServers": {
"nams": {
"serverUrl": "http://localhost:9090/mcp",
"headers": {
"Authorization": "Bearer ${env:NAMS_API_KEY}"
}
}
}
}Set NAMS_API_KEY in your shell, reload Windsurf or hit Cascade -> MCP servers -> Refresh. Confirm `nams` is connected. Omit `headers` for OAuth.
The agentic terminal. Add via Settings -> AI -> MCP servers -> Add (Streamable HTTP / URL), not a CLI flag. A single server is a bare object -- no mcpServers wrapper.
Settings -> AI -> MCP servers -> Add -> Streamable HTTP or SSE Server (URL):
{
"nams": {
"url": "http://localhost:9090/mcp",
"headers": {
"Authorization": "Bearer nams_YOUR_API_KEY"
}
}
}Warp sends header values verbatim -- paste your real key. Save, start the server from the same panel, then ask Agent Mode 'What memory tools do you have?'
After connecting, your agent will have access to all the NAMS memory, ontology, and workspace tools listed below. Each tool requires the scope shown in its row. An admin API key carries every scope, including workspace:admin; a workspace key (or OAuth login) carries only the data-plane scopes, so the workspace:admin tools are unavailable to it.
Short-Term Memory
| Tool | Description | Parameters | Required Scope |
|---|---|---|---|
memory_create_conversation | Create a new conversation session for tracking agent interactions. Entities extracted from it belong to user_id's memory. | user_id (optional) | memory:write |
memory_add_messages | Add multiple messages to a conversation in bulk. Triggers async entity extraction. | conversation_id, messages (array of {role, content}) | memory:write |
memory_get_context | Get the three-tier context: reflections, observations, and recent messages | conversation_id | memory:read |
memory_search_messages | Search messages by content in one conversation, or across the workspace when conversation_id is omitted, optionally only one user's conversations (exact user_id match); each hit includes its conversationId. Vector similarity when available, otherwise case-insensitive text matching; searchType in the result says which answered. | query, conversation_id (optional), user_id (optional), limit (optional, 1-100, default 20) | memory:read |
memory_get_extraction_status | Report entity-extraction status for a conversation's messages: per-message status (pending/processing/done/error), attempts, last run time, and a summary count by status. | conversation_id, workspace_id (optional) | memory:read |
Long-Term Memory
| Tool | Description | Parameters | Required Scope |
|---|---|---|---|
memory_search_entities | Search the knowledge graph for entities by name and description, optionally of one type or only one user's (exact user_id match). Vector similarity when available, otherwise case-insensitive text matching; searchType in the result says which answered. Without a query, lists entities. | query (optional), type (optional), user_id (optional), limit (optional, 1-100, default 20) | entities:read |
memory_get_entity | Get details for a specific entity including its relationships, each with its direction (out/in) relative to the entity. With user_id, an entity outside that user's memory is not found, and only relationships to that user's entities are listed. | entity_id, user_id (optional) | entities:read |
memory_get_entity_by_name | Look up entities by exact name (normalized, alias-aware), merged entities resolved to their canonical target. With user_id, only that user's entities. | name, type (optional), user_id (optional), limit (optional, 1-100, default 25) | entities:read |
memory_add_entity | Add entities to the knowledge graph, resolved against existing ones. With user_id they belong to that user's memory and merge only with that user's entities. | entities (array of {name, type, description?}), user_id (optional) | entities:write |
memory_get_entity_history | Get cross-conversation history - all messages that mention an entity | entity_id, user_id (optional) | entities:read |
memory_create_relation | Create a typed relationship between two entities. Type is validated against the workspace's allowlist; unknown types collapse to RELATED_TO with the original name stored as a predicate property. Both entities must belong to the same user (or both be shared). | relations (array of {source_id, target_id, type, confidence?}), user_id (optional), workspace_id (optional) | entities:write |
memory_review_queue | List pending entity-resolution SAME_AS pairs the resolver flagged as likely duplicates but didn't auto-merge - they need human review. | limit (optional, 1..100), workspace_id (optional) | entities:read |
memory_resolve_entity | Apply a decision to a pending SAME_AS pair: 'confirm' merges source into target; 'reject' marks the pair as not-a-match. Two users' entities are never merged. | source_id, target_id, action (confirm/reject), workspace_id (optional) | entities:write |
Reasoning Memory
| Tool | Description | Parameters | Required Scope |
|---|---|---|---|
memory_start_trace | Start a reasoning trace for a task under a conversation; record steps against it and complete it when the task ends | conversation_id, task, metadata (optional), message_id (optional) | reasoning:write |
memory_record_step | Record a reasoning step taken by an agent during a conversation; with trace_id, numbered under that trace | conversation_id or trace_id, reasoning, action_taken, result/metadata (optional) | reasoning:write |
memory_record_tool_call | Record a tool invocation made by an agent; counts on the tool's registry node | tool_name, input, step_id (optional), output/status/duration_ms/error/message_id/touched_entity_ids (optional) | reasoning:write |
memory_complete_trace | Complete a reasoning trace: its outcome, success, error category, metrics and touched entities | trace_id, outcome/success/error_kind/metrics/related_entity_ids (optional) | reasoning:write |
memory_get_trace | Get the full reasoning trace for a conversation, or one trace by id with its steps in order | conversation_id or trace_id | reasoning:read |
memory_find_similar_traces | Find past traces whose task is like a query, each with its outcome and steps - recall before acting | query, user_id/conversation_id/success_only/min_score/limit (optional) | reasoning:read |
memory_list_traces | List traces by conversation, user, success and time window, ordered and paged | conversation_id/user_id/success_only/since/until/order_by/order_dir/limit/offset (optional) | reasoning:read |
memory_search_steps | Search past reasoning steps by thought, action and observation, each with its trace's task and outcome | query, user_id/success_only/min_score/limit (optional) | reasoning:read |
memory_tool_stats | Per-tool call counters: total, successful, failed, success rate, average duration, last use | tool_name (optional) | reasoning:read |
memory_explain_decision | Get a detailed explanation of a reasoning step including tool calls and influenced entities | step_id | reasoning:read |
Ontology
| Tool | Description | Parameters | Required Scope |
|---|---|---|---|
memory_ontology_list | List ontologies in the workspace - system templates plus workspace-owned ontologies. The active one is flagged. | (none) | ontology:read |
memory_ontology_get | Get one ontology (system or workspace-owned) and its full version history | id | ontology:read |
memory_ontology_get_active | Get the workspace's active ontology version and parsed body (auto-binds nams-default if unbound) | (none) | memory:read |
memory_ontology_create | Create a new workspace ontology with an initial revision (create-context-graph YAML shape) | name, body | ontology:write |
memory_ontology_update | Update a workspace ontology - produces a new immutable revision. System templates are protected. | id, body | ontology:write |
memory_ontology_activate | Switch the workspace's active ontology to a given version; future entity writes validate against it | id, version | ontology:write |
memory_ontology_clone | Clone a system template into the workspace as an editable copy (fresh id, revision 1) | id | ontology:write |
memory_pending_types_list | List pending entity types extraction proposed that the active ontology has not yet declared | ontology (optional) | ontology:read |
memory_pending_type_map | Accept a pending entity type by mapping its surface form onto a declared entity-type label | surface_form, entity_type | ontology:write |
Workspace Management
| Tool | Description | Parameters | Required Scope |
|---|---|---|---|
workspace_list | List all workspaces the calling user is a member of | (none) | workspace:admin |
workspace_get | Fetch a single workspace's details | workspace_id | workspace:admin |
workspace_create | Create a workspace (idempotent by name). A managed workspace starts pending: call workspace_provision next. | name, db_mode (managed/external), uri/database/username/password (external only) | workspace:admin |
workspace_update | Update a workspace's metadata (currently rename) | workspace_id, name (optional) | workspace:admin |
workspace_delete | Soft-delete a workspace; for managed workspaces, also deletes the database | workspace_id | workspace:admin |
workspace_provision | Create a managed workspace's database. Idempotent; when it answers retry=true the database is still starting, so call it again | workspace_id | workspace:admin |
workspace_reprovision | Give a managed workspace whose database was removed a new, empty one. Same contract as workspace_provision | workspace_id | workspace:admin |
workspace_set_external_db | Switch a workspace to an external Neo4j instance (e.g. Aura). Tests and initializes before persisting. | workspace_id, uri, database, username, password | workspace:admin |
workspace_get_database | Get database connection info for a workspace - mode, URI, database, username (never the password) | workspace_id | workspace:admin |
Skills
| Tool | Description | Parameters | Required Scope |
|---|---|---|---|
skill_generate | Distill a scoped slice of workspace memory into a portable, provenance-grounded Agent Skill. Asynchronous: returns a runId to poll with skill_run_status. | scope_type (workspace/conversations/entity/ontology_class/time), conversation_ids/entity_id/ontology_class/from/to (per scope), name_hint/skill_id/procedure_format (optional) | skills:write |
skill_run_status | Get the status and progress of a skill distillation run | run_id | skills:read |
skill_list | List the distilled skills in a workspace with their latest-version summary | (none) | skills:read |
skill_get | Get a skill's metadata, its rendered SKILL.md, and its version history | skill_id | skills:read |
skill_explain_provenance | Explain why a skill recommends what it does: resolve each claim and procedure step to the source decisions, entities, and messages that grounded it | skill_id, version_id (optional) | skills:read |
skill_governance | Audit the workspace's skill library as a graph (AIP corpus governance): ungrounded steps, skills missing a success-criteria component, shared sub-procedure reuse candidates, and the drifted set | (none) | skills:read |
skill_review | Approve or reject the latest version of a skill (the human-review gate before publishing) | skill_id, decision (approve/reject), feedback (optional) | skills:write |
skill_publish | Publish a skill's latest version. Requires the version to be review-approved; 409s if a called sub-procedure is unpublished. | skill_id | skills:write |
skill_delete | Permanently delete a skill of any status, draft or published, with all its versions. Source memory is not changed. Refused while another skill calls it or a distillation run for it is in progress. | skill_id | skills:write |
skill_execute | Produce a guarded DRY-RUN execution plan for a published skill's procedure graph. Does NOT invoke any tool; gated by SKILL_EXECUTION_ENABLED with a default-deny tool allowlist. | skill_id, version_id (optional) | skills:read |
skill_extract_subprocedure | Extract steps of a skill's served version into a new reusable sub-procedure skill, replacing them with a single CALLS step (AIP composition). Asynchronous: returns a runId to poll with skill_run_status. | skill_id, step_ids, name (optional) | skills:write |
skill_drift | Report whether a skill has drifted from current memory (drift status, stale-claim count, last-checked time) as persisted by the periodic drift reconciler. | skill_id | skills:read |
skill_edit | Validate a proposed edit to a skill's procedure graph against the graph invariants without mutating anything (dry run). Returns {valid, errors, steps}. | skill_id, ops (reorder/retype/edit_criterion/remove), version (optional) | skills:write |
skill_list_published | List the workspace's published skills (discovery): name, served version, digest, procedure format, and whether the package is cryptographically attested. | (workspace-scoped) | skills:read |
Node Types
| Label | Description |
|---|---|
| Conversation | A conversation session between an agent and user |
| Message | A single message within a conversation (user, assistant, or system) |
| Entity | A named entity in the knowledge graph (person, org, location, etc.) |
| ReasoningTrace | One task's execution record under a conversation: the task, its steps in order, and the outcome the client reported |
| AgentStep | A reasoning step recording the agent's thought process; numbered within its trace when recorded under one |
| ToolCall | A record of a tool invocation made during a reasoning step |
| Tool | The registry node for one tool name, carrying its call counters |
| Observation | A compressed summary generated from a window of messages |
| Reflection | A higher-level insight synthesized from multiple observations |
| Skill | A distilled, provenance-grounded Agent Skill (agentskills.io SKILL.md package). Lifecycle: draft, in_review, published, archived. Carries an extra :Subprocedure label when it is a called sub-procedure. |
| SkillVersion | An immutable version of a skill; holds rendered artifacts, the quality report, and procedureFormat ('graph' or 'prose') |
| SkillComponent | A content component of a skill version (kind: procedure, domain_model, exemplar, success_criteria, anti_pattern) |
| SkillStep | A typed step of the AIP Procedure Graph (kind: script, description, or call). A call step delegates to a sub-procedure Skill via CALLS. |
| DistillationRun | A record of a skill-distillation run (status: queued, snapshot_pinned, extracting, synthesizing, validating, packaging, succeeded, failed) |
Relationships
| Type | From | To |
|---|---|---|
HAS_MESSAGE | Conversation | Message |
HAS_STEP | Conversation | AgentStep |
HAS_TRACE | Conversation | ReasoningTrace |
HAS_STEP | ReasoningTrace | AgentStep |
USED_TOOL | AgentStep | ToolCall |
INSTANCE_OF | ToolCall | Tool |
INITIATED_BY | ReasoningTrace | Message |
TRIGGERED_BY | ToolCall | Message |
MENTIONS | Message | Entity |
INFLUENCED | AgentStep | Entity |
TOUCHED | AgentStep | Entity |
HAS_OBSERVATION | Conversation | Observation |
HAS_REFLECTION | Conversation | Reflection |
HAS_VERSION | Skill | SkillVersion |
HAS_COMPONENT | SkillVersion | SkillComponent |
HAS_STEP | SkillVersion | SkillStep |
GROUNDED_IN | SkillStep | AgentStep / ToolCall / Message / Entity / Observation / Reflection |
CALLS | SkillStep | Skill |
DERIVED_BY | SkillVersion | DistillationRun |
DISTILLED_FROM | SkillVersion | AgentStep / ToolCall / Message / Entity / Observation / Reflection |
SUPERSEDES | SkillVersion | SkillVersion |
Entity Types
| Type | Description |
|---|---|
| person | People, contacts, team members |
| organization | Companies, teams, groups |
| location | Cities, countries, addresses |
| concept | Ideas, topics, technologies |
| tool | Software tools, APIs, services |
| custom | User-defined entity types |