On 2026-10-24 Vector DB, AI Memory, the AI Gateway and Agents moved to one set of words: userId names your end user everywhere, a text is text, lists page with nextCursor, every refusal carries a code (and param for the field at fault), and any text over 2,000 characters is refused with input_too_long rather than cut. Code written against the old answers may need the changes below.
The old names listed last keep working until 2026-11-23, then they are removed. SDK 0.4.0 and the CLI 0.4.0 already use the new ones.
Vector DB
- A text over 2,000 characters is refused with 400
input_too_long(paramnames it), also when sent withvalues. Metadata keys that start with_hk_are refused, and metadata plus text over 10,240 bytes is 400metadata_too_large. - A namespace written to must be 1–64 letters, digits and . _ - : @ + = (an id or an email fits). Writes into an older namespace with a space or a slash are refused with 400
invalid_request; reading from it still works. - Filters with
$or,$and,$existsor an unknown operator are refused with 400filter_operator_unsupported, and filter errors carrycodeandparam. - Visitor chat searches only collections opened to it (
visitorChat: true). Every existing collection starts closed. A visitor's chat run searches by text across the whole collection, every namespace included, with at most 10 matches: open only a collection whose every vector may be shown to anyone. - A collection's
endpointis its own address (/api/vectors/:id), and it hasvisitor_chat. Deleting vectors by id no longer lowersvector_countat once;GET /api/vectors/:idreads the current count. - The connector's query_vectors no longer takes
returnMetadataand capstopKat 50.
AI Memory
- A store created without
kindis kind "memory" (it used to be "kv"), and every data call on it needsuserId(400user_id_required). Stores created before keep their kind and work as before. - Store answers (
GET/POST /api/projects/:id/memory,GET /api/memory/:id,/api/resources/memory) no longer carryprovider,endpointorseq; they gainsearchable,edge_fallback,user_id_required,created_atandquota. - Changing a memory's text gives it a new id: use the
idin the answer (previous_idis the old one). 409already_existswhen the user already has that text. - Refusals carry
codeandparam: a bad user id is 400invalid_user_id, a call the store's kind does not have is 409wrong_store_kind. HTTP statuses are unchanged. - The connector's search_memory sends
scopeas given; withuserIdtoo and the two different, it is 400conflicting_param.
AI Gateway
- An unknown model is 404
model_not_found(it was 400), on/api/ai/chatand/api/ai/v1. - A model you name that cannot be reached is 503
model_unavailable, with nothing charged, instead of being answered by Llama. Useharakumo-1to fail over. /api/ai/v1/chat/completionsrefuses unknown fields and the parameters it does not honour with 400unsupported_parameter; parameters with no effect are accepted only at their no-effect values. The nativePOST /api/ai/chatrefusestools,tool_choiceandresponse_formatother than text (other unknown fields are still ignored).- Output defaults to each model's own: 4,096 tokens on vendor models, 1,024 on Llama, up to 32,000. A
max_tokensover a model's most is a 400 naming the model. - Tools and JSON output (
json_object,json_schema) work only on the models whosesupported_parameterslist them, once the model has passed a live check through the gateway; elsewhere they are 400unsupported_parameter.json_objectneeds the word JSON in a message, and a conversation with tool calls must sendtools. - Every cheap and mid-price model is on by default for a workspace that never saved its model settings; Claude Opus stays off, and so does Kimi K2.6 until it is confirmed.
- Added, nothing removed: OpenAI error objects carry
paramandmetadata,usagehascost, andharakumohasrequest_id.
Agents
- Agents and runs have one shape:
toolsis a list (it may hold function tools),allow_writesis true or false,triggeris{ kind, label }, a run hascost_usdonly,stop_reasonis null when it completed,started_byisapiwhen someone asked, and a step hastool, parsedargumentsandoktrue or false. GET /api/agents/:idanswersrecent_runs(the 5 newest, without steps) instead ofruns(20 with steps).GET /api/agents/runs/:runIdhas one run with its steps, andGET /api/agents/:id/runspages through them.- A run you ask for starts at once in the background and gets its id at once (
POST /api/agents/:id/runs);wait(0 to 60 seconds) counts from when the request arrives. A run that finished answers 200 (it was 202). Thequeuedanswer is gone. maxStepscounts model calls, each with up to 8 tool calls. A run has 5 minutes (timeLimitSeconds10 to 300), and a cost cap of $0.25 on Hobby and $1 on paid plans unless the agent or the run sets one (stop_reasonbudget).- A run with no sign of life for 5 minutes is marked failed (
stale) and frees its slot. A run that could not start is 503run_not_started, nothing done or charged. - A schedule, app events and visitor chat can be on together: setting one no longer turns the others off, and
trigger.kindis a label only. - An agent whose tools are function tools only is offered only those; list tool names beside them to keep them.
- SDK:
agents.runresolves to the run itself (not{ run }), and waits for it to end.
Old names kept until 2026-11-23
| Old | Use instead |
|---|---|
POST /api/agents/:id to start a run (answers Deprecation and Sunset headers) | POST /api/agents/:id/runs { input, wait? } |
SDK memory.forget(storeId, scope) (one conversation only) | memory.forgetUser(storeId, userId), or DELETE /api/memory/:id/users/:userId: everything kept for the user |
SDK vectors.indexMetadata and POST /api/vectors/:id { action: "index-metadata" } | vectors.update(id, { metadataIndexes }), or PATCH /api/vectors/:id { metadataIndexes } |
userId on vector calls (the same field as namespace), memory for a memory's text, and user_id or scope for userId are accepted names, not old ones: they stay.