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 https://nams.development.neo4jsandbox.com/v1/entities \ -H "Authorization: Bearer nams_YOUR_API_KEY"
1. Create a conversation
curl -X POST https://nams.development.neo4jsandbox.com/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 https://nams.development.neo4jsandbox.com/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 https://nams.development.neo4jsandbox.com/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=https://nams.development.neo4jsandbox.com) 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=https://nams.development.neo4jsandbox.com) 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=https://nams.development.neo4jsandbox.com) 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=https://nams.development.neo4jsandbox.com) 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) https://nams.development.neo4jsandbox.com/mcp/.well-known/oauth-protected-resource # Authorization Server Metadata (RFC 8414) https://nams.development.neo4jsandbox.com/mcp/.well-known/oauth-authorization-server # Dynamic Client Registration (RFC 7591) POST https://nams.development.neo4jsandbox.com/mcp/oauth/register
Access tokens are short-lived (1 hour); clients refresh automatically.
Base URLs
| API | https://nams.development.neo4jsandbox.com/v1 |
| Auth | https://nams.development.neo4jsandbox.com/v1/auth |
| MCP | https://nams.development.neo4jsandbox.com/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 (https://nams.development.neo4jsandbox.com). 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=https://nams.development.neo4jsandbox.com) 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=https://nams.development.neo4jsandbox.com) 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=https://nams.development.neo4jsandbox.com) 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=https://nams.development.neo4jsandbox.com) 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": "https://nams.development.neo4jsandbox.com"
}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 'https://nams.development.neo4jsandbox.com/.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 are rejected with 403.
curl
curl 'https://nams.development.neo4jsandbox.com/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 are rejected with 403.
Request Body
{
"category": "string",
"label": "string",
"workspaceId": "string"
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/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 are rejected with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | API key ID |
curl
curl -X DELETE 'https://nams.development.neo4jsandbox.com/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 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 are rejected with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | API key ID |
curl
curl 'https://nams.development.neo4jsandbox.com/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
{
"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"
}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. Auth: requires a user token or an Admin API key (workspace:admin); workspace-bound data keys are rejected with 403.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | required | API key ID to rotate |
curl
curl -X POST 'https://nams.development.neo4jsandbox.com/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
{
"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"
}Key is already revoked
{
"error": "Key is already revoked"
}Internal error
{
"error": "Internal error"
}Auth service base URL: https://nams.development.neo4jsandbox.com Validate an Auth0 Bearer token via JWKS 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 Auth0 token directly.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
Authorization | header | string | required | Auth0 Bearer token |
Request Body
{
"id_token": "string",
"no_mint": false
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/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"
}Auth0 exchange not configured
{
"error": "Auth0 exchange not configured"
}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 'https://nams.development.neo4jsandbox.com/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
{
"client_id": "string",
"refresh_token": "string"
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 the 1-hop neighborhood of a node (any memory label: Entity, Message, Conversation, Observation, Reflection, AgentStep, ToolCall) plus the complete, canonical-resolved set of relationships among the resulting node set (the new neighbors together with loadedIds), for the Memory Browser. Omitting loadedIds is the same as sending an empty list. Provenance edges (MENTIONS/INFLUENCED, with the paired EXTRACTED_FROM metadata collapsed in) are included; merge plumbing (MERGED_REL/SAME_AS) is excluded. New neighbors are capped at 200, with truncation metadata rather than a silent drop. With userId, a node outside that user's memory expands to nothing, and only nodes in that user's memory (their entities, and their conversations with what those hold) are returned.
Request Body
{
"loadedIds": [
"string"
],
"nodeId": "string",
"userId": "string"
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/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, or loadedIds exceeds cap
{
"error": "Missing workspace_id or nodeId, 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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/v1/ontologies/migrations/{job_id}/resume' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
No Content
curl
curl 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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.
Request Body
{
"actionTaken": "string",
"conversationId": "string",
"reasoning": "string",
"result": "string"
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/v1/reasoning/steps' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{
"actionTaken": "",
"conversationId": "",
"reasoning": ""
}'Responses
Returns id, conversationId, reasoning, actionTaken, result
{
"actionTaken": "string",
"conversationId": "string",
"id": "string",
"reasoning": "string",
"result": "string"
}Missing required fields
{
"error": "Missing required fields"
}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"
}Record a tool invocation made by an agent during a reasoning step. Optionally link to a step via stepId. input and output must be JSON-encoded strings, not objects. Pre-serialize structured payloads before sending (e.g. "input": "{\"query\":\"foo\"}", not "input": {"query":"foo"}). The graph stores them as scalar string properties on the :ToolCall node. Status values: pending, success (default), failure, error, timeout, cancelled. Legacy completed/failed are accepted and rewritten to success/failure.
Request Body
{
"durationMs": 150,
"input": "{\"query\":\"project status\"}",
"output": "{\"results\":[\"r1\",\"r2\"]}",
"status": "success",
"stepId": "string",
"toolName": "web_search"
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/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
{
"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"
}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 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 'https://nams.development.neo4jsandbox.com/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"
}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 'https://nams.development.neo4jsandbox.com/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": "...",
"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 'https://nams.development.neo4jsandbox.com/.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 'https://nams.development.neo4jsandbox.com/v1/skills' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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"
}feature_disabled (skill_distillation)
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 'https://nams.development.neo4jsandbox.com/v1/skills/governance' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
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 'https://nams.development.neo4jsandbox.com/v1/skills/published' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
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 'https://nams.development.neo4jsandbox.com/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"
}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 'https://nams.development.neo4jsandbox.com/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"
}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 'https://nams.development.neo4jsandbox.com/v1/skills/runs/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
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 'https://nams.development.neo4jsandbox.com/v1/skills/scan' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Scan enqueued; returns runId
feature_disabled (skill_distillation or skill_autosuggest)
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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/download' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/drift' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/edit' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/edit/commit' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Edit enqueued; returns runId
invalid edit
feature_disabled (skill_distillation)
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/explain-provenance' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/extract-subprocedure' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Extraction enqueued; returns runId
feature_disabled (skill_distillation, or skill_composition when composition is off)
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/publish' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
not approved
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/review' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
OK
not pending review
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/steps/{stepId}/repair' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
Repair enqueued; returns runId
feature_disabled (skill_distillation)
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 'https://nams.development.neo4jsandbox.com/v1/skills/{id}/verify' \
-H 'Authorization: Bearer nams_YOUR_API_KEY'Responses
OK
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 'https://nams.development.neo4jsandbox.com/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
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 'https://nams.development.neo4jsandbox.com/v1/users/me/workspaces' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"workspaces": [
"..."
]
}no user identity
{
"error": "no user identity"
}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 'https://nams.development.neo4jsandbox.com/v1/workspace' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"status": "updated"
}cannot delete your only workspace
{
"error": "cannot delete your only workspace"
}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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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
{
"error": "invalid mode or connection"
}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, or external_database (switched back to external while provisioning)
{
"error": "copy_in_progress, database_in_use (another workspace uses or is copying into that database), database_busy, or external_database (switched back to external while provisioning)"
}external database connection failed
{
"error": "external database connection failed"
}external database schema init failed
{
"error": "external database schema init failed"
}switched to managed, but provisioning did not finish (retry); workspace_limit_unavailable; or external_target_busy (another request is adopting that database; retry)
{
"error": "switched to managed, but provisioning did not finish (retry); workspace_limit_unavailable; or external_target_busy (another request is adopting that database; 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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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
{
"error": "targetMode is required"
}insufficient workspace role, or workspace_limit_reached
{
"error": "insufficient workspace role, or workspace_limit_reached"
}copy_in_progress, destination_not_empty, database_in_use or database_busy
{
"error": "copy_in_progress, destination_not_empty, database_in_use or database_busy"
}preflight failed
{
"error": "preflight failed"
}workspace_limit_unavailable or external_target_busy (retry)
{
"error": "workspace_limit_unavailable or external_target_busy (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 'https://nams.development.neo4jsandbox.com/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
{
"error": "targetMode is required"
}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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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.
Request Body
{
"database": "neo4j",
"password": "secret",
"uri": "neo4j+s://abc123.databases.neo4j.io",
"username": "neo4j"
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/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
{
"error": "invalid uri",
"success": false
}Return all members of the workspace.
curl
curl 'https://nams.development.neo4jsandbox.com/v1/workspace/members' \ -H 'Authorization: Bearer nams_YOUR_API_KEY'
Responses
OK
{
"members": [
"..."
]
}Unauthorized
{
"error": "Unauthorized"
}Add a user to the workspace, or change an existing member's role. 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
{
"role": "developer",
"user_id": "auth0|65f1c2d4e5f6a7b8c9d0e1f2"
}curl
curl -X POST 'https://nams.development.neo4jsandbox.com/v1/workspace/members' \
-H 'Authorization: Bearer nams_YOUR_API_KEY' \
-H 'Content-Type: application/json' \
--data '{}'Responses
Created
{
"status": "updated"
}user_id and role are required, or role is not admin, developer or viewer
{
"error": "user_id and role are required, or role is not admin, developer or viewer"
}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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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), or restore_not_allowed (the workspace has a database)
{
"error": "external_database, copy_in_progress (a restore is already running), or restore_not_allowed (the workspace has a database)"
}provisioning_failed (retry), no_capacity, or managed_provisioning_disabled
{
"error": "provisioning_failed (retry), no_capacity, or managed_provisioning_disabled"
}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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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
{
"error": "external_database"
}provisioning_failed (retry), no_capacity, or managed_provisioning_disabled
{
"error": "provisioning_failed (retry), no_capacity, or managed_provisioning_disabled"
}Return the workspace's entity-resolution configuration, falling back to system defaults when unset.
curl
curl 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 'https://nams.development.neo4jsandbox.com/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 https://nams.development.neo4jsandbox.com/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",
"https://nams.development.neo4jsandbox.com/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 \ https://nams.development.neo4jsandbox.com/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 = "https://nams.development.neo4jsandbox.com/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": "https://nams.development.neo4jsandbox.com/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": "https://nams.development.neo4jsandbox.com/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": "https://nams.development.neo4jsandbox.com/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": "https://nams.development.neo4jsandbox.com/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": "https://nams.development.neo4jsandbox.com/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_record_step | Record a reasoning step taken by an agent during a conversation | conversation_id, reasoning, action_taken, result (optional) | reasoning:write |
memory_record_tool_call | Record a tool invocation made by an agent | tool_name, input, step_id (optional), output/status/duration_ms (optional) | reasoning:write |
memory_get_trace | Get the full reasoning trace - all steps and tool calls | conversation_id | 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.) |
| AgentStep | A reasoning step recording the agent's thought process |
| ToolCall | A record of a tool invocation made during a reasoning step |
| 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 |
USED_TOOL | AgentStep | ToolCall |
MENTIONS | Message | Entity |
INFLUENCED | 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 |