API Reference
Everything you need to integrate with RagUp
Quick Start
Authenticate, upload documents, and start querying your knowledge base in minutes.
Base URL
Authentication
All API requests require an x-api-key header. Get your key from
API Keys.
Folders
Organize your documents into folders. Each folder scopes the RAG search — queries within a folder only search documents in that folder.
/api/v1/folders
/api/v1/folders
Returns all active folders for the authenticated user.
/api/v1/documents/upload
Upload a document (PDF, TXT, Word .doc/.docx, or CSV). The file is processed asynchronously — text is extracted, chunked, and embedded for RAG queries. Returns 202 Accepted immediately.
Processing Pipeline
Parameters (multipart/form-data)
| Field | Type | Required | Description |
|---|---|---|---|
| file | binary | required | PDF, TXT, Word (.doc, .docx), or CSV. Max size set by server (env MAX_UPLOAD_SIZE, in MB). |
| folderId | UUID | required | Target folder ID |
| metadata | JSON string | optional | Custom key-value metadata for filtering |
Example
curl -X POST ${baseUrl}/documents/upload \ -H "x-api-key: YOUR_API_KEY" \ -F "file=@document.pdf" \ -F "folderId=FOLDER_UUID"
const form = new FormData(); form.append("file", fileInput.files[0]); form.append("folderId", "FOLDER_UUID"); const res = await fetch("${baseUrl}/documents/upload", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY" }, body: form, }); const data = await res.json(); // data.document.id → use to check status // data.document.status → "processing"
import requests res = requests.post( "${baseUrl}/documents/upload", headers={"x-api-key": "YOUR_API_KEY"}, files={"file": open("document.pdf", "rb")}, data={"folderId": "FOLDER_UUID"}, ) data = res.json() # data["document"]["id"] → use to check status
Response 202 Accepted
{
"message": "Document uploaded and queued for processing",
"document": {
"id": "d1e2f3a4-b5c6-...",
"fileName": "document.pdf",
"status": "processing",
"folderId": "f47ac10b-..."
},
"jobId": "job-uuid",
"checkStatusUrl": "/api/v1/queue/jobs/job-uuid"
}
Polling: Check GET /api/v1/documents/:id until status changes to "ready". Only then can you query the document.
MCP Integration
Connect remote LLMs, AI agents, or MCP clients to query your RAG via the Model Context Protocol. Uses the same authentication (API key) and rate limits as the REST API.
Endpoint
Authentication
Use header x-api-key: YOUR_API_KEY (rag-service only). allowedHost is enforced if configured.
Plano
Disponível apenas para planos Pro, Business e Enterprise.
Tool: rag_query
Query the RAG. Parameters: question (required), folderId, filters, topK.
Example
curl -X POST ${baseUrl}/mcp \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "rag_query", "arguments": { "question": "What is the contract duration?" } } }'
Response format
JSON-RPC 2.0. Tool result contains answer, sources, tokens, confidence, conversationId.
Rate limit
Same as REST API (per plan). Headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
Error codes (JSON-RPC)
| Code | Meaning |
|---|---|
| -32001 | Missing or invalid API key |
| -32002 | Forbidden (App ID, host restriction) |
| -32003 | MCP disponível a partir do plano Pro |
| -32005 | Rate limit exceeded |
| -32600 | Request entity too large (max 256KB) |
| -32603 | Internal server error |
/api/v1/rag/ask
Ask a question and get relevant document chunks (retrieve-only, default) or an AI-generated answer (when synthesize: true).
By default the endpoint only runs vector similarity search and returns sources and confidence — no LLM call.
Stateless endpoint: Every call creates a new conversation record for audit trail. For multi-turn chat with conversation history, use Conversations API instead.
Default (retrieve-only)
With synthesize: true
Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
| question | string | required | Your question (1-10,000 chars) |
| folderId | UUID | optional | Restrict search to a specific folder |
| filters | array | optional | Metadata filters (max 10). Each: { field, operator, value } |
| synthesize | boolean | optional | If true, runs the LLM and returns answer, tokens, conversationId. Omitted or false = retrieve-only (sources + confidence). |
Filter Operators
| Operator | Description | Example |
|---|---|---|
| = | Equal | {"field":"status","operator":"=","value":"active"} |
| != | Not equal | {"field":"status","operator":"!=","value":"archived"} |
| > | Greater than | {"field":"amount","operator":">","value":1000} |
| contains | Contains (case-insensitive) | {"field":"client","operator":"contains","value":"abc"} |
| in | In list | {"field":"type","operator":"in","value":["a","b"]} |
| between | Range | {"field":"amount","operator":"between","value":[1000,5000]} |
Example
curl -X POST ${baseUrl}/rag/ask \ -H "x-api-key: YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "question": "What is the contract duration?", "folderId": "FOLDER_UUID" }' # Default: returns sources + confidence. Add "synthesize": true for answer + tokens + conversationId.
const res = await fetch("${baseUrl}/rag/ask", { method: "POST", headers: { "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json", }, body: JSON.stringify({ question: "What is the contract duration?", folderId: "FOLDER_UUID", }), }); const data = await res.json(); // Default: data.sources, data.confidence. With synthesize: true also data.answer, data.tokens, data.conversationId console.log(data.sources, data.confidence);
import requests res = requests.post( "${baseUrl}/rag/ask", headers={ "x-api-key": "YOUR_API_KEY", "Content-Type": "application/json", }, json={ "question": "What is the contract duration?", "folderId": "FOLDER_UUID", }, ) data = res.json() # Default: sources, confidence. Add "synthesize": True for answer, tokens, conversationId print(data["sources"], data["confidence"])
Response 200 OK
Default (retrieve-only):
{
"sources": [
{ "chunkId": "...", "content": "...", "distance": 0.12, "documentId": "..." }
],
"confidence": 0.88
}
With synthesize: true: adds answer, tokens, conversationId. With x-api-key, sources may be omitted in the synthesized response; with JWT (dashboard), sources is included.
Response Fields
sources
Retrieved chunks (chunkId, content, distance, documentId). Always present.
confidence
Heuristic retrieval confidence score (0-1). Higher = better match between question and retrieved chunks. Always present.
answer
The AI-generated answer. Only when synthesize: true.
tokens
Token usage (prompt + completion). Only when synthesize: true.
conversationId
Inbox conversation ID (message history). Only when synthesize: true.
Conversations (Multi-turn)
StatefulFor chat interfaces and widgets that need conversation history. Create a conversation once, then send multiple questions — the LLM receives the full message history for context-aware answers.
Step 1 — Create a conversation
/api/v1/conversations
Returns a conversation object with id. Use this ID for subsequent questions.
Step 2 — Send questions
/api/v1/conversations/:id/ask
The LLM receives the last 10 messages as context. Supports SSE streaming via Accept: text/event-stream header.
Webhooks
Pro+Receive real-time notifications when events happen in your account. Configure endpoints to receive HTTP POST callbacks with event payloads.
/api/v1/webhooks/endpoints
| Event | Description |
|---|---|
document.ready | Document processed and ready for queries |
document.error | Document processing failed |
conversation.created | New conversation created |
conversation.message.created | New message in a conversation |
scraping.completed | Web scraping finished successfully |
scraping.error | Web scraping failed |
Deliveries are retried up to 5 times with exponential backoff. Each delivery includes an HMAC-SHA256 signature for verification.
Code Search via TreeSeek
Pro+Busca semântica de código integrada ao seu editor e agente de IA. Você não chama endpoints diretamente — o treeseek faz tudo via MCP (Model Context Protocol). Configure uma vez e use naturalmente no Claude Code, Cursor, Windsurf ou VS Code.
Como funciona
1. Indexe localmente
O treeseek faz o chunking AST (tree-sitter) do seu código localmente. Nada de código sai bruto — só os chunks processados vão pro RagUp.
2. RagUp gera embeddings
Os chunks são enviados ao RagUp, que gera embeddings via Ollama e armazena em pgvector com busca por similaridade.
3. Busque semânticamente
Seu agente de IA busca código por similaridade semântica via treeseek MCP. Resultados em milissegundos, com contexto completo.
Configuração em 3 passos
Crie uma credential Code Search
No dashboard, vá em API Keys e crie uma credential do tipo Code Search (MCP). Copie a chave gerada.
Configure a variável de ambiente
O treeseek detecta automaticamente o modo remoto quando RAGUP_API_KEY está configurada.
Adicione ao seu client MCP
Configure o treeseek como MCP server no seu editor/agente de IA.
// ~/.claude/settings.json { "mcpServers": { "treeseek": { "command": "npx", "args": ["-y", "treeseek"], "env": { "RAGUP_API_KEY": "sua-code-search-key", "RAGUP_HOST": "https://www.ragup.com.br" } } } }
// ~/.cursor/mcp.json { "mcpServers": { "treeseek": { "command": "npx", "args": ["-y", "treeseek"], "env": { "RAGUP_API_KEY": "sua-code-search-key", "RAGUP_HOST": "https://www.ragup.com.br" } } } }
// VS Code settings.json → mcp.servers { "mcp.servers": { "treeseek": { "command": "npx", "args": ["-y", "treeseek"], "env": { "RAGUP_API_KEY": "sua-code-search-key", "RAGUP_HOST": "https://www.ragup.com.br" } } } }
Ferramentas MCP disponíveis
| Ferramenta | Descrição |
|---|---|
| index_codebase | Indexa um diretório de código (AST chunking + embeddings). Reexecuções são incrementais. |
| search_code | Busca semântica por query em linguagem natural. Retorna os chunks mais relevantes. |
| get_indexing_status | Verifica se um diretório já foi indexado e quantos chunks existem. |
| clear_index | Remove o índice de um diretório (local ou remoto). |
Modos de operação
Local (offline)
Sem RAGUP_API_KEY
- • LanceDB local para armazenamento
- • Ollama local para embeddings
- • 100% offline e gratuito
- • Dados ficam na sua máquina
RagUp Cloud
Pro+Com RAGUP_API_KEY
- • pgvector no RagUp para armazenamento
- • Ollama no server para embeddings
- • Sincronização sob demanda
- • Busca disponível de qualquer lugar
- • Retro-compatível com modo local
Linguagens suportadas
TypeScript, JavaScript, Python, Java, Go, Rust, C, C++, C#, Ruby, PHP, Swift, Kotlin, Scala, e mais. O treeseek usa AST-aware chunking via tree-sitter para preservar funções completas.
Plano Pro: até 3 repositórios, 50.000 chunks, 2.000 buscas/mês
Plano Business: até 10 repositórios, 200.000 chunks, 10.000 buscas/mês
Enterprise: ilimitado
Code Search API
Pro+Index and semantically search your codebase. RagUp generates embeddings server-side — just send raw code chunks and query with natural language. Ideal for AI-powered code search, MCP tools, and IDE integrations.
Authentication
Uses a separate Code Search credential (Bearer token). Create one in the API Keys dashboard by selecting the code-search type.
/api/v1/code-search/collections
Create a new collection to hold code chunks for a project.
Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | required | Collection name (used in URL path) |
| description | string | optional | Human-readable description |
Example
curl -X POST ${baseUrl}/code-search/collections \ -H "Authorization: Bearer sua-code-search-key" \ -H "Content-Type: application/json" \ -d '{"name": "my-project", "description": "My project description"}'
const res = await fetch("${baseUrl}/code-search/collections", { method: "POST", headers: { "Authorization": "Bearer sua-code-search-key", "Content-Type": "application/json", }, body: JSON.stringify({ name: "my-project", description: "My project description", }), }); const data = await res.json(); // data.collection.name → "my-project"
import requests res = requests.post( "${baseUrl}/code-search/collections", headers={ "Authorization": "Bearer sua-code-search-key", "Content-Type": "application/json", }, json={ "name": "my-project", "description": "My project description", }, ) data = res.json() # data["collection"]["name"] → "my-project"
/api/v1/code-search/collections/:name/chunks
Insert code chunks into a collection. RagUp generates embeddings server-side — you only send the raw text.
Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
| documents | array | required | Array of document objects (see below) |
| documents[].id | string | required | Unique chunk identifier (e.g. src/main.ts:1-20) |
| documents[].content | string | required | Raw code content of the chunk |
| documents[].relativePath | string | optional | File path relative to project root |
| documents[].startLine | number | optional | Start line number in the source file |
| documents[].endLine | number | optional | End line number in the source file |
| documents[].fileExtension | string | optional | File extension (e.g. .ts, .py) |
| documents[].metadata | object | optional | Additional key-value metadata |
Example
curl -X POST ${baseUrl}/code-search/collections/my-project/chunks \ -H "Authorization: Bearer sua-code-search-key" \ -H "Content-Type: application/json" \ -d '{ "documents": [{ "id": "src/main.ts:1-20", "content": "export function validateEmail(email) { ... }", "relativePath": "src/main.ts", "startLine": 1, "endLine": 20, "fileExtension": ".ts", "metadata": {} }] }'
const res = await fetch("${baseUrl}/code-search/collections/my-project/chunks", { method: "POST", headers: { "Authorization": "Bearer sua-code-search-key", "Content-Type": "application/json", }, body: JSON.stringify({ documents: [{ id: "src/main.ts:1-20", content: "export function validateEmail(email) { ... }", relativePath: "src/main.ts", startLine: 1, endLine: 20, fileExtension: ".ts", metadata: {}, }], }), }); const data = await res.json(); // data.inserted → number of chunks indexed
import requests res = requests.post( "${baseUrl}/code-search/collections/my-project/chunks", headers={ "Authorization": "Bearer sua-code-search-key", "Content-Type": "application/json", }, json={ "documents": [{ "id": "src/main.ts:1-20", "content": "export function validateEmail(email) { ... }", "relativePath": "src/main.ts", "startLine": 1, "endLine": 20, "fileExtension": ".ts", "metadata": {}, }], }, ) data = res.json() # data["inserted"] → number of chunks indexed
Server-side embeddings: RagUp automatically generates vector embeddings from your content field. No need to compute or send embeddings yourself.
/api/v1/code-search/collections/:name/search
Search a collection with a natural language query. Returns the most semantically similar code chunks.
Body (application/json)
| Field | Type | Required | Description |
|---|---|---|---|
| query | string | required | Natural language search query |
| topK | number | optional | Number of results to return (default: 10) |
Example
curl -X POST ${baseUrl}/code-search/collections/my-project/search \ -H "Authorization: Bearer sua-code-search-key" \ -H "Content-Type: application/json" \ -d '{"query": "function that validates email", "topK": 10}'
const res = await fetch("${baseUrl}/code-search/collections/my-project/search", { method: "POST", headers: { "Authorization": "Bearer sua-code-search-key", "Content-Type": "application/json", }, body: JSON.stringify({ query: "function that validates email", topK: 10, }), }); const data = await res.json(); // data.results → ranked code chunks
import requests res = requests.post( "${baseUrl}/code-search/collections/my-project/search", headers={ "Authorization": "Bearer sua-code-search-key", "Content-Type": "application/json", }, json={ "query": "function that validates email", "topK": 10, }, ) data = res.json() # data["results"] → ranked code chunks
Setup Instructions
Create a Code Search credential
Go to API Keys and create a credential with the code-search type.
Install treeseek
Configure your API key
Add to your MCP client config
Add the treeseek server to your Claude Code, Cursor, or other MCP client configuration.
Error Codes
| Code | Meaning | Fix |
|---|---|---|
| 400 | Invalid request body or params | Check required fields and types |
| 401 | Invalid or missing API key | Verify x-api-key header |
| 403 | Plan quota exceeded | Upgrade plan or wait for monthly reset |
| 404 | Resource not found | Check folderId/documentId |
| 429 | Rate limit exceeded | Wait for Retry-After seconds |
Rate Limits
| Plan | Requests/min | Queries/month | Documents |
|---|---|---|---|
| Free | 20 | 150 | 3 |
| Starter | 60 | 1,500 | 30 |
| Pro | 100 | 4,000 | 150 |
| Business | 300 | 8,000 | 500 |
| Enterprise | 1,000 | Unlimited | Unlimited |
Rate limit headers are included in every response: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset