Guides
File inputs & retrieval
Mahvash offers several ways to bring files to a model. Learn what each file interface is for, how indexing and retrieval work, and how to choose the right path for direct inputs, reusable assets and searchable document collections.
Choose a file path
Mahvash has several file interfaces because they serve different integration jobs, not because every upload creates a separate kind of storage. Pick the first row that matches your goal:
| Need | Use | Why |
|---|---|---|
| Give the model a file with one question or across a chat | Mahvash asset + asset_ids | One project-scoped UUID can be passed to any supported request. |
| Use an OpenAI-compatible SDK or a batch | /v1/files | file-... IDs and the direct wire format fit supported SDK methods. |
| Transfer a large file reliably | Resumable upload session | Send numbered, checksummed parts, then complete the upload. |
| Search a collection of documents | Vector store + files | Files are indexed before file_search can retrieve them. |
| Make retrieval available to a whole project | Project data source | Attaches an indexed store to the project; it does not upload or index files. |
- Assets (
/api/v1/chat/assets) are reusable project files identified by a UUID. Pass them to a request withasset_ids. - Files (
/v1/files) are OpenAI-style file objects (file-...) for SDK compatibility, batches and vector stores./api/v1/chat/filesoffers the same objects inside the product envelope. - Uploads (
/api/v1/chat/uploads) split one large file into numbered, retryable parts. - Vector stores (
/v1/vector_stores) index files sofile_searchcan find relevant passages. - Project data sources make an indexed store part of a project's retrieval.
Give a model a file directly
When a user attaches a document or image to one question, the model should read it — not search it. Upload it as an asset once and reference it by UUID:
# Upload once. Keep the returned asset UUID in your own records.
curl https://api.mahvashai.ir/api/v1/chat/assets/upload \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-F "file=@./contract.pdf"
# Reuse it in any supported request of the same project
curl https://api.mahvashai.ir/v1/responses \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "auto", "input": "List the termination clauses.", "asset_ids": ["<asset-uuid>"]}'- Assets must be ready and belong to the same project as the request.
- A request may reference a limited number of assets (by default at most 10, with a combined size limit of 50 MiB). Duplicates are removed while keeping order.
- If the selected model cannot read a file type, a project with managed tools enabled can have Mahvash extract the text or describe the image first. Scanned documents without a text layer are refused.
Note:Never send binary files as base64 inside JSON. Upload them with multipart/form-data and pass the resulting ID.
OpenAI-compatible files
/v1/files follows the OpenAI Files API, so SDK methods like files.create work unchanged. Each file has a purpose: user_data (the default) for general inputs, batch for batch input files, and other OpenAI values such as assistants or vision.
with open("handbook.pdf", "rb") as handle:
uploaded = mahvash.files.create(file=handle, purpose="user_data")
print(uploaded.id) # file-<uuid>
store = mahvash.vector_stores.create(name="Employee handbook")
mahvash.vector_stores.files.create(vector_store_id=store.id, file_id=uploaded.id)Metadata (GET /v1/files/{id}) and content (GET /v1/files/{id}/content) are separate: the content endpoint returns the raw bytes with the stored MIME type, not JSON.
Large and unreliable uploads
For large files or unreliable networks, use a resumable upload session. You declare the file first, send it in numbered parts, then complete it:
# 1. Open a session for the whole file
curl https://api.mahvashai.ir/api/v1/chat/uploads \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"filename": "archive.pdf", "bytes": 10485760, "mime_type": "application/pdf", "purpose": "user_data"}'
# 2. Send numbered parts; each may be retried independently
curl -X PUT https://api.mahvashai.ir/api/v1/chat/uploads/upload-<uuid>/parts/1 \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-H "X-Part-SHA256: <lowercase-sha256-of-part-1>" \
-F "data=@./archive.part1"
curl -X PUT https://api.mahvashai.ir/api/v1/chat/uploads/upload-<uuid>/parts/2 \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-H "X-Part-SHA256: <lowercase-sha256-of-part-2>" \
-F "data=@./archive.part2"
# 3. Complete: parts 1..part_count must add up to the declared bytes
curl https://api.mahvashai.ir/api/v1/chat/uploads/upload-<uuid>/complete \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"part_count": 2}'- Parts are numbered from
1, may be uploaded in any order, and can be retried or replaced until completion. Send each part's SHA-256 inX-Part-SHA256so corruption is detected. - On completion, parts
1..part_countmust be contiguous and add up exactly to the declaredbytes. The result is a normal file object. - A session expires after about an hour by default. Cancel sessions you abandon.
How retrieval works
Retrieval answers questions over collections that are too large to send with every request. It has three separate steps, and it helps to keep them apart:
- 1Upload a file — it is now stored, but not searchable.
- 2Index it by attaching it to a vector store. Mahvash extracts the text, splits it into chunks, and builds a searchable index. The vector store file moves from
in_progresstocompleted(orfailed). - 3Search it: a
file_searchtool in a Responses request retrieves the most relevant chunks and gives them to the model, which answers with citations.
# Create a store in the project that will query it
curl https://api.mahvashai.ir/v1/vector_stores \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Support policies"}'
# Attach an uploaded file; indexing starts now
curl https://api.mahvashai.ir/v1/vector_stores/vs_<uuid>/files \
-H "Authorization: Bearer $MAHVASH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"file_id": "file-<uuid>"}'
# Poll until "status" is "completed" (or handle "failed")
curl https://api.mahvashai.ir/v1/vector_stores/vs_<uuid>/files/file-<uuid> \
-H "Authorization: Bearer $MAHVASH_API_KEY"A store only answers from files whose indexing has completed. Querying a store whose files are not ready fails clearly instead of answering from partial data.
Searching in a request
There are two ways to make a request search your documents.
Explicit `file_search`
Name the stores in the request. This gives you precise control — for example, choosing a store based on your own user's permissions:
{
"model": "auto",
"input": "How many vacation days do new employees get?",
"tools": [
{ "type": "file_search", "vector_store_ids": ["vs_<uuid>"], "max_num_results": 8 }
],
"include": ["file_search_call.results"]
}include: ["file_search_call.results"] returns the retrieved passages in the response, which is useful for showing sources or debugging relevance.
Project data sources
Attach a ready store to the project as a data source. When the project has auto-search enabled, requests that do not specify their own tools search the project's data sources automatically. Attaching a data source does not upload or index anything; it only makes an existing store part of the project's retrieval.
Answers cite sources with file_citation annotations that point to Mahvash file-... IDs. Map those IDs to your own document records to render links.
The Build document Q&A walkthrough connects all of these steps in order.
Scope, placement and lifecycle
- Project scope. Every file, asset and store belongs to one project. A foreign or inaccessible ID answers
404. Afile_searchcan only name stores your organization owns. - Placement. A vector store's
retrieval_placementdecides where its index lives:localkeeps documents in Mahvash's own index,hostedindexes them through a provider account. The default resolves tolocal, and a project can set a different default for new stores. - Deletion is explicit. Detaching a data source stops project retrieval; removing a file from a store deletes its index entries but not the file; deleting the file is a separate call. Plan cleanup according to your retention policy.
- Downloads are yours to protect. Content you download from Mahvash should be served to your users only through your own access checks.