NAMS limits and behavior

This page describes the service contract used by this checkout. The SDK source alone does not verify a deployed service, dashboard, quota or authentication configuration. Check the authenticated service response and current workspace settings when following operational instructions.

Operational limits, quotas, and runtime behavior for the hosted NAMS backend. These describe what to expect as a client — not internal service metrics. For the wire contract see NAMS REST API; for setup see Use NAMS.

Conformance tiers ≠ access tiers. Bronze / Silver / Gold / Platinum are agent-memory-tck cross-language conformance levels (how complete a client SDK is), not a NAMS pricing or access tier. Every NAMS capability listed in backend capabilities is reachable by any authenticated workspace.

Client defaults (NamsConfig)

These are Python SDK defaults you can override; they are not server limits. The TypeScript client has no retry settings: it makes one attempt per request (see TypeScript errors).

Setting Default Notes

timeout

30s

Per-request HTTP timeout.

max_retries

3

Retries on network errors and on 429, 500, 502, 503 and 504.

retry_backoff_seconds

0.5s

Base for exponential backoff. Retry-After is honored on 429.

validate_on_connect

true

Sends a probe (with X-Workspace-Id when set) so misconfiguration fails fast.

transport_mode

auto

rest for /v{n} endpoints, bridge otherwise.

Rate limits

A handful of endpoints enforce explicit rate limits. When you exceed one the service returns 429 Too Many Requests. The Python SDK honors any Retry-After header while retrying and raises RateLimitError (carrying retry_after) after retries are exhausted. The TypeScript client does not retry; it raises TransportError with statusCode 429.

Operation Limit On exceed

Ontology preview / extraction-backed import (POST /v1/ontologies/preview, RDF /import)

30 requests / hour / workspace

429 {"error":"preview rate limit exceeded (30/hour)"}

Feedback (POST /v1/feedback)

10 / min and 100 / hour per user; 200 / hour per workspace

429

OAuth dynamic client registration (/oauth/register, MCP)

Per-source-IP sliding window

429 with Retry-After: 600

Beyond these guards there is no blanket per-request rate limiter today — but write your client to tolerate 429 regardless.

Treat 429 as normal backpressure. The Python SDK already retries with backoff; with the TypeScript client, retry idempotent calls yourself (see handling errors). For bulk ingestion prefer bulk_add_messages(…​) over many single add_message(…​) calls.

Quotas

Quota Behavior

Managed workspaces per user

Capped (default 10, operator-configured via MAX_MANAGED_WORKSPACES_PER_USER). Creating one past the cap returns a workspace_limit_reached error with the current limit. Workspaces backed by your own database (external / BYOD) are not counted against this cap.

Skill package size

A distilled skill artifact is capped at 1 MiB (SKILL_MAX_ARTIFACT_BYTES).

Feedback payload size

Feedback bodies over 16 KiB are rejected.

Request payload size

Oversized requests return 413 Request Entity Too Large. The exact byte ceiling is service-configured.

Idle managed databases

A managed (NAMS-provisioned) workspace database is reclaimed after 2 days of inactivity (MANAGED_DB_INACTIVITY_DAYS). BYOD databases are never reaped.

NAMS has no paid tiers or plan-based quotas today: every NAMS capability in backend capabilities is available to any authenticated workspace, and the limits above apply uniformly. (A plan field appears on some workspace responses but is currently unused.)

Runtime behavior

Extraction is asynchronous on NAMS

When you add messages, entity/relationship extraction runs server-side. Writes are accepted immediately (202 Accepted); extracted entities become queryable a short time later. Poll GET /v1/conversations/{id}/extraction-status, or call long_term.wait_for_extraction(…​) from the SDK, before asserting on extracted results. (On bolt, extraction is synchronous and wait_for_extraction is a no-op returning True.)

Read-only Cypher

client.query.cypher(…​) runs against the workspace graph in Neo4j READ access mode. Write statements are rejected server-side (400). This is available to any authenticated workspace — it is not gated behind a tier.

Eventual consistency

Because extraction and resolution are asynchronous, a just-written message and its derived entities are not guaranteed to be visible in the same instant. Delete operations likewise propagate asynchronously.

Status codes & errors

The service uses standard HTTP status codes; error bodies are JSON of the shape {"error": "…​"} (some carry additional fields such as message and limit). See REST API → Errors for the full mapping to SDK exceptions.

See also