Docs
Files and memory
Search your documents and keep what matters between conversations.
File searchPOST/v1/vector_stores
OpenAI's vector stores and the file_search tool, on your key's account. Upload a document to /v1/files with purpose assistants (PDF, Word, HTML, Markdown, text, CSV, JSON and source code; at most 4 MB a file), make a store with POST /v1/vector_stores, and attach the file. Each file is read, cut into chunks of 800 tokens overlapping by 400 (or a static chunking_strategy of your own), and embedded with openai/text-embedding-3-large at 256 dimensions, or the embedding_model and embedding_dimensions you give the store. Every embedding is an embeddings request on the key's account, held, metered and billed like /v1/embeddings, as the key that attached the file, which needs the embeddings scope. A file is in_progress until it is completed or failed, and the store counts them in file_counts and its usage_bytes.
curl https://useantimatter.com/v1/vector_stores/vs_.../search \
-H "Authorization: Bearer $ANTIMATTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "refund policy", "max_num_results": 5,
"filters": {"type": "eq", "key": "team", "value": "support"}}'A search embeds the query with the store's model (billed) and ranks chunks by cosine similarity, a score from 0 to 1, held to filters on the files' attributes (eq, ne, gt, gte, lt, lte, in, nin, and, or) and to ranking_options.score_threshold. Up to 100,000 chunks a search scans exactly. Past that, libsql's vector index answers, which is approximate. x-antimatter-vector-search says which. There is no reranker and no query rewriting.
On /v1/responses, a tool {"type": "file_search", "vector_store_ids": [...]} is run by the gateway. The model asks for searches, the gateway runs them on your account and returns the passages, for at most 3 rounds. The answer carries file_search_call items (with their results when include names file_search_call.results) and file_citation annotations. Every model call and every query embedding is billed as its own request, and x-antimatter-cost-micros is their sum. With stream: true the answer is written as the event stream once it is ready.
Storage is free here. A store with expires_after expires that many days after it was last searched or given a file, and its files go with it. Deleting a store deletes its chunks. The uploaded files stay in /v1/files until you delete them.
MemoryPOST/v1/memories
Long term memory for your agents and apps. Facts are kept across sessions in a memory space on your key's account and searched by meaning. POST /v1/memories takes memories (texts) or messages (a conversation). From messages, a model reads the facts worth keeping, at most 20, each with a confidence. Then every fact that resembles an existing memory (cosine 0.6 or more) goes to a second step that decides, as mem0 does, whether it is new (ADD), changes a memory (UPDATE), says one is no longer true (DELETE) or is already kept (NONE). A fact nothing resembles is added without asking, and words already kept are NONE without any call. Both steps are chat requests on the cheapest priced text model from a well known lab that writes JSON, under strict JSON, billed as your key, which needs the chat scope. With infer: false nothing is extracted or decided and the key needs only the embeddings scope. Every embedding is an embeddings request on your account. The answer lists each change and x-antimatter-cost-micros is the sum of every call. async: true queues the conversation and returns 202 with a /v1/memory_extractions/{id} to follow.
curl https://useantimatter.com/v1/memories \
-H "Authorization: Bearer $ANTIMATTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user": "ada", "messages": [
{"role": "user", "content": "I moved to Lyon last spring and I am vegetarian."}]}'
curl https://useantimatter.com/v1/memories/search \
-H "Authorization: Bearer $ANTIMATTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"user": "ada", "query": "where does she live", "top_k": 5}'A space (POST /v1/memory_spaces) holds up to 5,000 memories and embeds with one model. A request that names none uses your key's default space, made on first use. An agent's key reaches only its agent's spaces. user is your own end user's id. One user's memories are never used in another user's decision or search. Every change is in GET /v1/memories/{id}/history, kept 365 days, after the memory itself is deleted too.
On a chat completion, x-antimatter-memory: default (or a space id) recalls the 5 memories nearest the last user turn, scored 0.3 or more, into one system message after yours, for the request's user. x-antimatter-memory-write: 1 queues the conversation and the answer for extraction after the answer. Both are billed as their own requests and named in the answer's x-antimatter-memory. The same two headers work on /v1/messages, where the recall ends system and the end user is metadata.user_id, and on /v1/responses, where it ends instructions and the end user is user (else safety_identifier). A stream is read as it passes. In a hosted agent run a tool {"type": "memory"} gives the model remember and recall on the agent's own space, billed to its wallet.