Docs

Guide

Documents and search

Chat with your documents without running a database: upload files, put them in a hosted vector store, and search it, or let the model search it for you.

Vector stores are available where they are switched on for the deployment. Where they are off, every /v1/vector_stores route answers 404, uploads take purpose=batch only, and the file_search tool is refused with 400.

How it works

The API is OpenAI's Vector Stores API, so the official openai clients work unchanged with the base URL pointed at Silicon Network. Four steps:

  1. Upload each document with POST /v1/files and purpose=assistants (or user_data).
  2. Create a vector store and attach the files. Each file is read, cut into overlapping chunks and embedded in the background.
  3. Poll the file (or the store's file_counts) until it is completed.
  4. Search the store with POST /v1/vector_stores/{id}/search, or pass it to the Responses API as a file_search tool and let the model answer from it.

Every chunk and every query is embedded with the platform's embedding model (bge-m3, multilingual) through the same serving path as /v1/embeddings, as your key. A store keeps the model it was created with, so its queries always match its chunks.

Quickstart

documents.py
import time
from openai import OpenAI

client = OpenAI(base_url="https://api.siliconnetwork.io/v1", api_key="sn_live_...")

f = client.files.create(file=open("handbook.pdf", "rb"), purpose="assistants")
store = client.vector_stores.create(name="Handbook", file_ids=[f.id])

# Ingestion runs in the background.
while client.vector_stores.files.retrieve(f.id, vector_store_id=store.id).status == "in_progress":
    time.sleep(2)

results = client.vector_stores.search(store.id, query="How many vacation days do I get?")
for r in results.data:
    print(round(r.score, 3), r.filename, r.content[0].text[:80])

answer = client.responses.create(
    model="llama-3.1-8b",
    input="How many vacation days do I get?",
    tools=[{"type": "file_search", "vector_store_ids": [store.id]}],
)
print(answer.output_text)
silicon - zsh
curl https://api.siliconnetwork.io/v1/files -H "Authorization: Bearer $SILICON_API_KEY" \
  -F purpose=assistants -F file=@handbook.md

curl https://api.siliconnetwork.io/v1/vector_stores -H "Authorization: Bearer $SILICON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name": "Handbook", "file_ids": ["file-..."]}'

curl https://api.siliconnetwork.io/v1/vector_stores/vs_.../search -H "Authorization: Bearer $SILICON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"query": "vacation days", "max_num_results": 5}'

Files it can read

Supported documents
ExtensionHow the text is read
.txt, .text, .md, .markdownAs is. UTF-8, or UTF-16 with a byte order mark.
.csv, .tsvAs is, one row per line.
.json, .jsonlParsed and printed compactly, one value after another. At most 64 levels of nesting.
.html, .htmThe visible text only: no scripts, styles or templates.
.pdfThe text layer, page by page, of the first 2,000 pages. A scanned PDF without one has no text to index: there is no OCR.

The type is decided by the extension, and the upload is checked before it is stored: text that is not UTF-8, JSON that does not parse or nests deeper than 64 levels, or a PDF that is not one is refused with 400. Documents are read in a separate process with CPU, memory and time limits, and one that needs more fails with invalid_file. A large JSON upload is checked the same way; when the gateway is busy reading other documents it answers 503 with Retry-After, so retry. A file is at most 32 MB and the organization's uploads share the Files API quota (see Files and batches). Uploaded files keep their own expiry, by default 30 days; a store keeps its own copy of the text, so search keeps working after the upload expires.

Stores and files

A store is {id, object: "vector_store", name, status, usage_bytes, file_counts, expires_after, expires_at, last_active_at, metadata}. Create it with POST /v1/vector_stores (name, file_ids, metadata, expires_after, chunking_strategy), list, read, modify and delete it as at OpenAI. Attach more files with POST /v1/vector_stores/{id}/files {file_id, attributes?, chunking_strategy?}.

File status

A file is in_progress until it settles as completed or failed; a failed file carries last_error with OpenAI's codes: unsupported_file, invalid_file (also when the organization's vector storage is full) or server_error. A temporary failure, such as no engine available for a moment or the attaching key at its rate limit, is retried automatically with a backoff, up to three attempts, before the file fails; a retry keeps the chunks already stored. Ingestion uses the attaching key's rate limit at batch priority, so it waits behind your interactive requests. A file that would not fit the organization's vector storage fails with invalid_file before any of it is embedded, and revoking the attaching key fails its files that are still in progress. The data residency of the attaching request (see Data residency) is kept with the file, so its chunks are embedded inside it.

Chunking

The default, or {"type": "auto"}, is chunks of 800 tokens that repeat the last 400 of the chunk before. Choose your own with {"type": "static", "static": {"max_chunk_size_tokens": 400, "chunk_overlap_tokens": 100}}: 100 to 4096 tokens, overlap at most half. Tokens are estimated (about four characters of English text a token, one per character for scripts such as Chinese or Japanese), so a chunk can be somewhat smaller than the model would count, never far larger.

Attributes

Attributes are up to 16 key and value pairs per file (strings up to 512 characters, numbers or booleans), set when you attach the file or later with POST /v1/vector_stores/{id}/files/{file_id}. Search filters read them.

Billing and limits

What it costs
ItemPrice
Embedding a file's chunksThe embedding model's per-token price, once per ingestion
Embedding a search queryThe embedding model's per-token price
Reranking, where configuredThe rerank model's per-token price
file_search excerptsInput tokens of the Responses request, like any prompt
StorageFree for now, and metered as usage_bytes

The embedding calls appear in your usage like any /v1/embeddings request, under the key that attached the file or made the search (a search carries your project tag). See Pricing for the rates. A key whose scope leaves out the embedding model is refused with 403, and one without credit with 402, before anything is stored.

Limits
LimitValue
Vector storage per organization1 GB of usage_bytes (chunk text plus 4 bytes per vector dimension)
Stores per organization1,000
Files per store10,000
Chunks per file20,000
File size32 MB, within the Files API quota
Chunks one search can scan, on a deployment without pgvector100,000 comparisons, counted once per query (a larger search answers 503: send fewer queries)

Privacy and retention

A store keeps its chunks until you remove the file from it, delete the store, or the store expires. With "expires_after": {"anchor": "last_active_at", "days": 7} it expires seven days after it was last used (a search, an attached file or a change counts); an expired store answers with status expired and its chunks are deleted. Removing a file from a store leaves the upload in the Files API, as at OpenAI; delete it there too. A file uploaded with X-Silicon-No-Retention cannot be added to a store, because the store keeps its text. The attaching key is kept, encrypted, only while a file is being ingested, and deleting your account deletes all of your stores.

Not built yet: file batches (/file_batches), reading a store file's parsed content, query rewriting and OCR for scanned PDFs.

Silicon Network›Docs›Guides›Documents and search46 items