SPB Git forge

spb/doc-api

Public
2commits 1branches 0releases
15.7 MBsize
maindefault branch
13 days agolast push
Python 88.3% TypeScript 7.6% Shell 4.1%
8.1 KB · 91 lines markdown
Rendered Raw Blame History
1# OpenAI Vector Stores (Retrieval API)23**Status:** `DOCUMENTED` · `LIVE_VERIFIED` (all 15 endpoints called 2026-09-18; `file_batches/{id}/cancel` on a completed batch → HTTP 500 = `FAILED_VERIFICATION` for that call only).4**Sources:** [Retrieval guide](https://developers.openai.com/api/docs/guides/retrieval) · [Vector stores reference](https://developers.openai.com/api/reference/resources/vector_stores) · [vector store files](https://developers.openai.com/api/reference/resources/vector_stores/subresources/files) · [file batches](https://developers.openai.com/api/reference/resources/vector_stores/subresources/file_batches) · [File search tool guide](https://developers.openai.com/api/docs/guides/tools-file-search) · [Pricing](https://developers.openai.com/api/docs/pricing).5**Last verified:** 2026-09-18. Twins: endpoints fragment `openai-files-vectorstores-batch-finetuning-evals.json`, parameters `openai-vector-stores.json`, objects `openai-platform-objects.json`, lifecycles `openai-lifecycles.json`.67A vector store chunks, embeds and indexes Files. It backs (a) the standalone **search endpoint** documented here and (b) the hosted **`file_search` tool** of the Responses API (`tools: [{type: "file_search", vector_store_ids: [...], max_num_results, filters, ranking_options}]`) — the tool itself is owned by `docs/tools/` (tools agent); this page covers the stores it consumes.89## 1. Endpoints1011| Method / path | SDK (python) | Key params | 2026-09-18 |12|---|---|---|---|13| `POST /v1/vector_stores` | `vector_stores.create` | `name`, `description`, `file_ids[]`, `chunking_strategy` (only with file_ids), `expires_after {anchor:"last_active_at", days 1–365}`, `metadata` | 200, `status: completed`, `usage_bytes 0` |14| `GET /v1/vector_stores` | `.list` | `limit` 1–100, `order`, `after`, `before` | 200 |15| `GET /v1/vector_stores/{id}` | `.retrieve` | | 200; 404 bogus id |16| `POST /v1/vector_stores/{id}` | `.update` | `name`, `expires_after` (nullable), `metadata` | 200 |17| `DELETE /v1/vector_stores/{id}` | `.delete` | → `{object:"vector_store.deleted", deleted:true}` | 200 |18| `POST /v1/vector_stores/{id}/search` | `.search` | `query` (string **or array**), `rewrite_query`, `max_num_results` 1–50 (default 10), `filters`, `ranking_options {ranker, score_threshold}` | 200 |19| `POST /v1/vector_stores/{id}/files` | `.files.create` | `file_id`, `attributes`, `chunking_strategy` | 200 → `in_progress` |20| `GET /v1/vector_stores/{id}/files` | `.files.list` | `filter` in_progress/completed/failed/cancelled + cursors | 200 |21| `GET /v1/vector_stores/{id}/files/{file_id}` | `.files.retrieve` | | 200 |22| `POST /v1/vector_stores/{id}/files/{file_id}` | `.files.update` | `attributes` (required; **replaces** the map) | 200 |23| `DELETE /v1/vector_stores/{id}/files/{file_id}` | `.files.delete` | detaches (File itself remains) → `vector_store.file.deleted` | 200 |24| `GET /v1/vector_stores/{id}/files/{file_id}/content` | `.files.content` | parsed chunks page | 200 |25| `POST /v1/vector_stores/{id}/file_batches` | `.file_batches.create` | `file_ids[]` + global `attributes`/`chunking_strategy` **or** `files[] {file_id, attributes?, chunking_strategy?}` (mutually exclusive); ≤ 500 files | 200 → `in_progress` |26| `GET /v1/vector_stores/{id}/file_batches/{batch_id}` | `.file_batches.retrieve` | | 200 |27| `POST /v1/vector_stores/{id}/file_batches/{batch_id}/cancel` | `.file_batches.cancel` | | **500** when already completed |28| `GET /v1/vector_stores/{id}/file_batches/{batch_id}/files` | `.file_batches.list_files` | `filter` + cursors | 200 |2930Rate limits (documented): `files` + `file_batches` creation share **300 req/min per vector store**; 2 000 attached files/min/org.3132## 2. Chunking3334| Strategy | Params | Constraints |35|---|---|---|36| `{"type":"auto"}` (default) | — | resolves to static 800 / 400 (observed: a file added with `auto` is returned with `chunking_strategy.type = "static"`) |37| `{"type":"static","static":{"max_chunk_size_tokens","chunk_overlap_tokens"}}` | both required | `max_chunk_size_tokens` 100–4096 (default 800); `chunk_overlap_tokens` ≥ 0 and ≤ max/2 (default 400) |38| response-only `{"type":"other"}` | — | files indexed before chunking strategies existed |3940Verified: `static 100/20` accepted; a 200-byte file produced 1 chunk and `usage_bytes 1203` (index overhead ≫ raw size — billing is on indexed bytes).4142## 3. Attributes and filters4344`attributes` = map of ≤ 16 keys, values `string | number | boolean`, key/string ≤ 256 chars. Update **replaces** the whole map (observed: `{atlas, n, draft}` → `{atlas, n, lang}`). Numbers come back as floats (`1` → `1.0`).4546Comparison filter `{"type": eq|ne|gt|gte|lt|lte|in|nin, "key": "<attr>", "value": string|number|boolean|array}`; compound `{"type": and|or, "filters": [...]}` (nestable). The guide also shows `"property": "filename"` with `in`/`nin` (filter on filename) — `UNVERIFIED`. Live: `and[eq atlas=platform, gte n=1]` matched; `eq atlas=nomatch` → empty `data`.4748## 4. Search response4950```json51{"object":"vector_store.search_results.page","search_query":["Woodchucks per passenger ratio"],52 "data":[{"file_id":"file-…","filename":"….txt","score":0.977,"attributes":{"n":1.0,"atlas":"platform","draft":false},53          "content":[{"type":"text","text":"…chunk…"}]}],"has_more":false,"next_page":null}54```55`search_query` is always an array; with `rewrite_query: true` it holds the rewritten query (observed: question → keyword phrase). Array `query` (multi-query) is accepted and echoed. `ranking_options.ranker` ∈ `none | auto | default-2024-11-15` (guide also mentions `default-2024-08-21`); `score_threshold` 0–1. The guide documents `ranking_options.hybrid_search {embedding_weight, text_weight}` (RRF weights) — not in the OpenAPI spec, `UNVERIFIED`.5657## 5. Objects5859- **VectorStore** `object:"vector_store"`: `id` (`vs_…`), `name`, `description?`, `usage_bytes`, `file_counts {in_progress, completed, failed, cancelled, total}`, `status` (`in_progress | completed | expired`), `expires_after`, `expires_at`, `last_active_at`, `metadata`, `created_at`.60- **VectorStoreFile** `object:"vector_store.file"`: `id` (= the File id), `vector_store_id`, `usage_bytes`, `status` (`in_progress | completed | cancelled | failed`), `last_error {code: server_error|unsupported_file|invalid_file, message}`, `chunking_strategy`, `attributes`, `created_at`.61- **VectorStoreFileBatch**: spec says `object:"vector_store.files_batch"`, **live returns `"vector_store.file_batch"`** (`id` prefix `vsfb_ibj_…`); `status`, `file_counts`, `vector_store_id`.62- **File content page** `object:"vector_store.file_content.page"`: `data[] {type:"text", text}`, `has_more`, `next_page`.6364Lifecycles with observed timings (file: `in_progress` → `completed` in ~7.6 s; batch ~4 s) are in `openai-lifecycles.json`.6566## 6. Expiration6768`expires_after {anchor: "last_active_at", days}`: after `days` without activity the store becomes `expired`, its files are deleted and billing stops. Observed on create: `expires_at = created_at + days·86400`; `last_active_at` refreshed by search/file operations. Set `expires_after: null` on update to remove (nullable in spec).6970## 7. Limits and pricing7172| Item | Value |73|---|---|74| Max file size / tokens | 512 MB / 5 000 000 tokens per file |75| Files per batch request | 500 |76| Attributes | 16 keys × 256 chars |77| Search results | ≤ 50 per call |78| Storage price | first 1 GB free (across all stores), then **$0.10 / GB / day** (GB = 2^30 bytes) |79| `file_search` tool calls (Responses only) | $2.50 / 1 000 calls; direct `/search` calls are not separately priced on the pricing page (2026-09-18) |8081## 8. Errors observed8283| Call | HTTP | Message |84|---|---|---|85| `GET /vector_stores/vs_bogus` | 404 | `No vector store found with id 'vs_atlasbogus000'.` (`param: vector_store_id`) |86| `POST …/file_batches/{completed}/cancel` | 500 | `The server had an error processing your request…` |8788## 9. Test recipe used (≈ $0, cleaned up)8990create → files.create (static 100/20, attributes) → poll → list(filter) → content → search ×3 → files.update → update → file_batches.create(`files[]`) → poll → list_files → cancel(500) → delete files → delete store → leftover check (0 stores).91