Docs
Errors, limits and quotas
The limits agentics.you enforces today, the monthly quota on each plan, and every error code the memory REST API answers with.
Rate limits
| Surface | Limit | When it is hit |
|---|---|---|
MCP server, /mcp | 120 calls a minute per token or agent key | 429 with Retry-After. Wait that many seconds. |
Memory REST API, /v1/ | 300 requests a minute per client address | 429 rate_limited with Retry-After. |
| Memory REST API, per workspace | 600 writes and 300 searches a minute, across every key and session of the workspace. Reads are not counted. | 429 rate_limited with Retry-After. |
| Search meaning | 5,000 query embeddings a workspace per UTC day | Search still answers, by keyword only, with mode keyword and degraded ["dense_quota"]. |
| Creating API keys | 20 a workspace per hour | 429. |
Back off when you see 429: wait the Retry-After seconds, then retry with some jitter. Do not retry a 4xx other than 429. The request will fail the same way.
Monthly quotas
Plans are priced on actions. An action is a receipt written: a memory write, a decision, an approval, a handoff. Reads, recall and checking receipts are not actions, and agents are never counted.
| Plan | Actions a month | People who sign in |
|---|---|---|
| Free | 10,000 | 2 |
| Pro | 100,000 | 3 |
| Team | 1,000,000 | Unlimited |
| Enterprise | Set by contract | Unlimited |
On Free, once the month's actions are used, new writes are refused until the 1st (UTC): MCP tools that write return a message that says so, and POST /v1/memories answers 402 plan_action_limit. Free also keeps at most 10,000 stored memories; past that, POST /v1/memories answers 402 plan_memory_limit. Pause all, rules, approvals, reads, search, deletes and checking receipts keep working. Paid plans are not stopped at the limit. See Pricing.
Sizes and pages
| Limit | Value |
|---|---|
| Request body | 8 MiB. Larger answers body_too_large. |
| Sensitive content | Emails, phone numbers, card and IBAN numbers, keys and tokens in content and metadata are stored as [redacted], unless the workspace is set to refuse them (content_rejected). |
GET /v1/memories/export | A page stops at about 8 MiB of content and metadata. Follow next_cursor. |
Memory content | 1,048,576 bytes of UTF-8 (1 MiB). Larger answers content_too_large. |
Memory metadata | 65,536 bytes as JSON. Larger answers metadata_too_large. |
GET /v1/memories | limit 1 to 100, default 25. q up to 2,000 characters. Up to 100 namespace_id values. |
POST /v1/memories/search | query up to 2,000 characters. k 1 to 50, default 8. token_budget 200 to 32,000, default 4,000. Up to 100 namespace_ids. |
page paging | Up to offset 10,000. Past that, use cursor (use_cursor_pagination). |
| Bulk delete | 1 to 1,000 ids per call. |
| Namespaces | Name 1 to 64 characters. Up to 1,000 per page. |
| Key bindings | Up to 1,000 namespaces per key. |
MCP get_context | limit 1 to 50. max_tokens 200 to 32,000, default 4,000. |
MCP record_action_batch | 1 to 50 actions. |
MCP subscribe | 50 subscriptions per agent. |
| MCP batch | 20 JSON-RPC messages per request. |
Memory API error codes
Every error has the same shape. Match on code; the message is for people and can change.
{ "error": { "code": "content_too_large", "message": "content is 2000000 bytes; the limit is 1048576 bytes.", "details": { "limit_bytes": 1048576, "size_bytes": 2000000 } } }| Code | Status | Meaning and what to do |
|---|---|---|
invalid_json | 400 | The body is not a JSON object. |
invalid_name | 400 | A namespace name is empty, longer than 64 characters, or has control characters. |
invalid_cursor | 400 | The cursor is not one this list returned. Start again without it. |
invalid_move_to | 400 | move_to names the namespace being deleted. Name another one. |
invalid_kind | 400 | An import's kind must be text, file or url. |
invalid_content | 400 | content is missing or empty, or, on an import of kind text, not a string. |
invalid_metadata | 400 | metadata is not a JSON object. |
invalid_source | 400 | source is not a string. |
invalid_namespace | 400 | namespace is not a string. |
namespace_required | 400 | No namespace was named and the workspace has no default. |
invalid_sort | 400 | sort must be newest. |
invalid_pagination | 400 | cursor and page were both sent. Use one. |
invalid_page | 400 | page must be 1 or more. |
use_cursor_pagination | 400 | page went past offset 10,000. Use cursor. |
invalid_ids | 400 | ids must be a non-empty list of memory ids. |
too_many_ids | 400 | More than 1,000 ids in one bulk delete. |
invalid_namespace_ids | 400 | namespace_ids must be a list of strings. |
too_many_namespaces | 400 | More than 1,000 namespaces for one key. |
invalid_query | 400 | Search query is missing, empty, or longer than 2,000 characters. |
invalid_agent_id | 400 | Search agent_id is not a string. |
invalid_k | 400 | Search k is not a whole number from 1 to 50. |
invalid_token_budget | 400 | Search token_budget is not a whole number from 200 to 32,000. |
invalid_filters | 400 | Search filters has an unknown key or a value of the wrong type. |
unknown_field | 400 | The search body has a field it does not take. |
unauthorized | 401 | No credential, or the key has no workspace. Send Authorization: Bearer ak_…. |
session_expired | 401 | The console session expired. Sign in again. |
credential_not_supported | 403 | A virtual key (vk_) or another credential this API does not take. Use an ak_ key. |
csrf | 403 | A cookie request from another site was refused. Call from the console, or use a key. |
workspace_role_required | 403 | The signed-in person has no role in this workspace. |
read_only | 403 | The signed-in person's role is read-only, so writes are refused. |
user_session_required | 403 | Key bindings are managed by a signed-in person, not a key. |
insufficient_scope | 403 | The key was created with memory.read or memory.write, and this call needs the other. Writes need memory.write. |
key_has_no_namespaces | 403 | The key is bound to no namespace. An admin binds it with PUT /v1/keys/{key_id}/namespaces. |
namespace_out_of_scope | 403 | The key is not bound to that namespace. |
namespace_management_forbidden | 403 | Only a signed-in workspace admin can create, rename or delete a namespace. |
memory_out_of_scope | 403 | The memory is in a namespace the key is not bound to. |
job_out_of_scope | 403 | The job is in a namespace the key is not bound to. |
key_out_of_scope | 403 | That key belongs to another workspace. |
key_binding_forbidden | 403 | Only a workspace admin can set a key's namespaces. |
approval_invalid | 403 | approval_receipt_id is not an approval for exactly these ids. |
not_found | 404 | The memory API is not switched on. |
feature_not_enabled | 404 | The memory API is not on for this workspace. |
route_not_found | 404 | No such route or method. |
namespace_not_found | 404 | No namespace with that id or name. |
namespace_deleted | 404 | The namespace was deleted. |
memory_not_found | 404 | No memory with that id. |
job_not_found | 404 | No job with that id. |
key_not_found | 404 | No live API key with that id in this workspace. |
no_workspace | 409 | The signed-in person has no workspace yet. Create one, then retry. |
namespace_name_conflict | 409 | Another namespace has that name. |
cannot_delete_default_namespace | 409 | The default namespace cannot be deleted. |
namespace_not_empty | 409 | The namespace holds memories. Pass move_to, or delete them first. details.memory_count says how many. |
approval_required | 409 | Bulk delete, or a memory write a workspace rule holds, needs a person's approval. details.approval_id names the request in Needs you. For a write, retry with approval_id once it is approved. |
job_not_retryable | 409 | The job is still running or already done. Retry only a failed or stalled job. |
content_rejected | 400 | The memory contains emails, keys, tokens, card or IBAN numbers, and this workspace is set to refuse them. details.kinds counts what was found. Remove them and retry. |
admin_required | 403 | Exporting every memory needs an owner or admin session, or a key not narrowed to memory.read or memory.write. |
tenant_paused | 423 | The workspace owner paused every agent (Pause all). Nothing was written. Only the owner can resume. |
body_too_large | 413 | The request body is over 8 MiB. |
content_too_large | 413 | content is over 1 MiB. |
metadata_too_large | 413 | metadata is over 64 KiB. |
rate_limited | 429 | Too many requests. Wait Retry-After seconds. |
internal_error | 500 | Something failed on our side. Retry with backoff. |
receipt_unavailable | 503 | The write could not be recorded as a receipt, so nothing was written. Retry. |
approval_unavailable | 503 | A write rule needs the owner's approval, and the request could not be filed. Nothing was written. Retry shortly. |
meter_unavailable | 503 | The plan meter could not be read, so nothing was written. Wait Retry-After seconds and retry. |
agent_required | 400 | A webhook call needs the x-agentics-agent header naming the agent that owns the webhook. |
invalid_request | 400 | The webhook body was not accepted: an unknown field, a pattern with no fields, or a URL that is not public https. error.message says which. |
agent_not_linked | 403 | The agent named in x-agentics-agent is not linked to this workspace. |
webhook_not_found | 404 | No webhook with that id belongs to this agent. |
method_not_allowed | 405 | /v1/webhooks takes GET or POST; /v1/webhooks/{id} takes DELETE. |
subscription_limit | 409 | The agent already has 50 webhooks, or the workspace has 500. Delete one first. |
memory_unavailable | 503 | The webhook store could not be reached, so nothing changed. Retry. |
invalid_stage | 400 | stage on GET /v1/ingest names a stage that does not exist. |
invalid_file | 400 | An import of kind file needs filename and valid base64 in data_base64. |
invalid_url | 400 | An import of kind url needs an absolute http or https address, up to 2,048 characters, with no user name or password. |
url_not_allowed | 400 | The address is private, local or on a non-standard port, so it is not fetched. |
source_too_large | 413 | The file or page is over 5 MB. |
unsupported_file | 415 | Import reads PDF and text files (.txt, .md, .csv, .json, .html and similar). |
unsupported_url | 415 | The page's content type is not one Import can read. |
unreadable_pdf | 422 | The PDF could not be read. |
no_text | 422 | There is no text to remember, such as a scanned PDF with no text layer. Nothing was written. |
fetch_failed | 502 | The address could not be reached, answered an error, or redirected too many times. |
recall_receipt_unavailable | 503 | A search could not be recorded as a receipt, so no results were returned. Wait Retry-After seconds and retry. |
Free's limits answer 402 with their own body, the same one MCP returns: {"error": "plan_action_limit" or "plan_memory_limit", "message", "current_plan", "limit", "used"}.
MCP errors
| Answer | Meaning |
|---|---|
HTTP 401 with WWW-Authenticate | No token, or one /mcp does not take. Sign in, or send an agent key. |
HTTP 403, code -32000 | The token lacks mcp:tools. |
| HTTP 405 | Use POST. |
-32700 | The body is not JSON. |
-32600 | Not a JSON-RPC request, or a batch of more than 20. |
-32601 | No such method. |
-32602 | Bad arguments to a memory tool, or an unknown resource or prompt. |
A result with isError true | The tool refused, with a sentence that says why: an unknown tool, a missing scope, Pause all, or the Free monthly limit. |