For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
DocsAPI ReferenceSDKs
DocsAPI ReferenceSDKs
  • Introduction
    • Product Overview
    • Pricing
    • Model Explanation
    • Available Models
  • Guides
    • Quickstart
    • Authentication
    • BYOK
    • Dashboard Guide
    • Prompt Templates
    • Embeddings
    • RAG (Files & Search)
    • Audio
    • Images & Vision
    • Image Generation
    • Compare
    • Batch API
    • Auto Routing
    • Realtime Audio
  • SDKs
    • Node.js (TypeScript)
    • Python
    • Go
  • Infrastructure
    • Architecture
LogoLogo
On this page
  • Step 1 — Upload a file
  • Init upload fields
  • Init upload response
  • Step 2 — Wait for embeddings
  • Status fields
  • Step 3 — Search your files
  • Search fields
  • Search response
  • End-to-end: RAG chat
  • Filtering by metadata
  • Re-triggering embeddings
  • List your files
  • Common errors
Guides

RAG (Retrieval-Augmented Generation)

||View as Markdown|
Was this page helpful?
Edit this page
Previous

Embeddings

Next

Audio

Built with

RAG lets you upload files, automatically convert them into searchable chunks, and then query them with plain-language questions. The API returns the most relevant passages, which you can feed directly into a chat completion to get answers grounded in your own content.

The full flow is three steps:

  1. Upload a file and get a file_id
  2. Wait for embeddings to finish processing
  3. Search with a natural-language query
1POST https://api.meshapi.ai/v1/files # upload
2POST https://api.meshapi.ai/v1/files/embed # (re-)trigger embeddings
3POST https://api.meshapi.ai/v1/files/search # semantic search

Step 1 — Upload a file

Call POST /v1/files to register the file. You get back a file_id and a short-lived signed_url — use the signed URL to PUT the actual bytes directly to storage.

curl
Python
Node.js
$# 1a. Register the file and get an upload URL
$INIT=$(curl -s https://api.meshapi.ai/v1/files \
> -H "Authorization: Bearer <YOUR_RSK_KEY>" \
> -H "Content-Type: application/json" \
> -d '{
> "file_name": "handbook.pdf",
> "mime_type": "application/pdf",
> "embed": true
> }')
$
$FILE_ID=$(echo $INIT | jq -r '.file_id')
$SIGNED_URL=$(echo $INIT | jq -r '.signed_url')
$
$# 1b. Upload the file bytes to the signed URL
$curl -X PUT "$SIGNED_URL" \
> -H "Content-Type: application/pdf" \
> --data-binary @handbook.pdf
$
$echo "File ID: $FILE_ID"

Init upload fields

FieldTypeNotes
file_namestringName of the file (used for display and file-type detection)
mime_typestringMIME type, e.g. application/pdf, text/plain, text/markdown
embedbooleanDefault true — automatically triggers embedding after upload
metadataobjectOptional key-value pairs attached to every chunk (useful for filtering later)

Init upload response

1{
2 "file_id": "file_abc123",
3 "signed_url": "https://storage.example.com/...",
4 "expires_at": "2026-05-26T12:30:00Z"
5}

The signed_url expires in a few minutes. PUT your file bytes immediately after receiving it.


Step 2 — Wait for embeddings

After the PUT completes, the API automatically chunks and embeds your file (because embed: true). You can poll GET /v1/files/{file_id} to watch progress.

curl
Python
Node.js
$curl https://api.meshapi.ai/v1/files/$FILE_ID \
> -H "Authorization: Bearer <YOUR_RSK_KEY>"

Status fields

FieldValuesMeaning
upload_statuspending → readyFile bytes have been received
embedding_statuspending → queued → processing → completed | failedChunking and embedding progress

Once embedding_status is completed, the file is ready to search.


Step 3 — Search your files

Send a natural-language query to POST /v1/files/search. The API converts your query into a vector, finds the closest chunks, and returns the raw text with relevance scores.

curl
Python
Node.js
$curl https://api.meshapi.ai/v1/files/search \
> -H "Authorization: Bearer <YOUR_RSK_KEY>" \
> -H "Content-Type: application/json" \
> -d '{
> "query": "What is the refund policy?",
> "top_k": 5
> }'

Search fields

FieldTypeNotes
querystringPlain-language question or phrase
top_kintegerNumber of chunks to return (1–50, default 5)
file_idsstring[]Restrict search to specific files; omit to search all your files
filterobjectMatch chunks by metadata key-value pairs (exact match)
date_fromintegerUnix timestamp — only return chunks created after this time
date_tointegerUnix timestamp — only return chunks created before this time

Search response

1{
2 "results": [
3 {
4 "score": 0.912,
5 "text": "Refunds are processed within 5–7 business days...",
6 "parent_text": "Section 4: Returns and Refunds\n\nRefunds are processed...",
7 "file_id": "file_abc123",
8 "file_name": "handbook.pdf",
9 "chunk_index": 14,
10 "metadata": {}
11 }
12 ]
13}

End-to-end: RAG chat

Combine search results with a chat completion to answer questions from your documents.

Python
Node.js
1import httpx, json
2
3API = "https://api.meshapi.ai"
4HEADERS = {"Authorization": "Bearer rsk_...", "Content-Type": "application/json"}
5client = httpx.Client(headers=HEADERS)
6
7question = "What is the refund policy?"
8
9# 1. Retrieve relevant chunks
10search = client.post(f"{API}/v1/files/search", json={
11 "query": question,
12 "top_k": 3,
13}).json()
14
15context = "\n\n".join(r["text"] for r in search["results"])
16
17# 2. Ask the model
18chat = client.post(f"{API}/v1/chat/completions", json={
19 "model": "openai/gpt-4o-mini",
20 "messages": [
21 {
22 "role": "system",
23 "content": f"Answer using only the context below.\n\n{context}",
24 },
25 {"role": "user", "content": question},
26 ],
27}).json()
28
29print(chat["choices"][0]["message"]["content"])

Filtering by metadata

Tag files at upload time and filter at search time — useful when you have documents from different departments, clients, or time periods.

$# Upload with metadata
$curl https://api.meshapi.ai/v1/files \
> -H "Authorization: Bearer <YOUR_RSK_KEY>" \
> -H "Content-Type: application/json" \
> -d '{
> "file_name": "q4-report.pdf",
> "mime_type": "application/pdf",
> "metadata": { "department": "finance", "quarter": "Q4-2025" }
> }'
$
$# Search only finance docs
$curl https://api.meshapi.ai/v1/files/search \
> -H "Authorization: Bearer <YOUR_RSK_KEY>" \
> -H "Content-Type: application/json" \
> -d '{
> "query": "What were the operating expenses?",
> "filter": { "department": "finance" }
> }'

Re-triggering embeddings

If embed was set to false at upload time, or if embedding failed, you can kick it off manually:

$curl https://api.meshapi.ai/v1/files/embed \
> -H "Authorization: Bearer <YOUR_RSK_KEY>" \
> -H "Content-Type: application/json" \
> -d '{
> "file_ids": ["file_abc123", "file_def456"]
> }'

The response returns per-file status:

1{
2 "results": [
3 { "file_id": "file_abc123", "embedding_status": "queued", "chunk_count": null },
4 { "file_id": "file_def456", "embedding_status": "queued", "chunk_count": null }
5 ]
6}

You can pass "wait": true to block until all embeddings finish (useful for small files in scripts).


List your files

$curl "https://api.meshapi.ai/v1/files?limit=20&offset=0" \
> -H "Authorization: Bearer <YOUR_RSK_KEY>"

Response includes files (array of file status objects), total, limit, and offset.


Common errors

HTTPMeaning
401Missing or invalid API key
402Balance or spend limit exceeded
422Invalid request body (check required fields)
429Rate limit exceeded — back off and retry