Overview
The Context Engine is hosted by promptev. The base URL is https://api.promptev.ai. The Python and TypeScript SDKs call these same routes, so use them when you can: they check limits before sending, retry passing errors and raise one error class per status.
| Route | Body | What it does |
|---|
| POST /api/v1/documents | multipart/form-data | Put up to 20 files into the key’s project knowledge base (ingestion). |
| POST /api/v1/knowledge | application/json | Read the key’s project knowledge base with one action (retrieval). |
Authentication
Create a project API key under the project’s API keys in the promptev console. Send it on every request:
Authorization: Bearer fk_...
A key belongs to one project. It reads and writes that project’s knowledge base and nothing outside it, so no request names a project. Keep the key on your server.
POST /api/v1/documents
Put documents into the project, in the same Uploads source the console writes to. The project’s agents can use them on their next turn. The request returns when every file is ready, so allow a long timeout for large files.
| Form field | Type | Meaning |
|---|
| files | file, repeated | Required. One part per file, up to 20, 25 MB each. The filename’s extension decides how the file is read. |
| mode | "hybrid" | "graph" | Optional. "graph" also extracts entities and relationships into the Context Graph. Leave it out for the workspace’s default. |
| update | string, repeated | Optional. The name of a file in this request that should update the uploaded document of the same name in place, as the console offers. A file not named here is a new document. |
curl https://api.promptev.ai/api/v1/documents \
-H "Authorization: Bearer $PROMPTEV_API_KEY" \
-F "files=@handbook.pdf" \
-F "files=@pricing.xlsx" \
-F "mode=graph"
# Replace the uploaded handbook.pdf in place instead of adding a second one
curl https://api.promptev.ai/api/v1/documents \
-H "Authorization: Bearer $PROMPTEV_API_KEY" \
-F "files=@handbook.pdf" \
-F "update=handbook.pdf"
The answer has one row per file, in order. A file that fails is reported in its own row (status "failed" and an error) and never fails the others:
{
"results": [
{
"filename": "handbook.pdf",
"status": "…",
"document_id": "…",
"chunks": 42,
"units": 12,
"error": null
},
{
"filename": "pricing.xlsx",
"status": "failed",
"document_id": null,
"chunks": 0,
"units": 0,
"error": "…"
}
]
}An upload costs 1 credit per page, slide or MB, at least 1 per file.
POST /api/v1/knowledge
Read the project’s knowledge base. It is the same tool, with the same actions and fields, as search_knowledge_base on the project’s MCP server. The body is a JSON object: action plus that action’s fields. Start with discover.
curl https://api.promptev.ai/api/v1/knowledge \
-H "Authorization: Bearer $PROMPTEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "discover"}'curl https://api.promptev.ai/api/v1/knowledge \
-H "Authorization: Bearer $PROMPTEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "search", "query": "how many days do customers have to ask for a refund", "top_k": 5}'curl https://api.promptev.ai/api/v1/knowledge \
-H "Authorization: Bearer $PROMPTEV_API_KEY" \
-H "Content-Type: application/json" \
-d '{"action": "get_doc", "document_id": "…"}'Each call costs 1 credit, plus 1 for a search (5 when the graph is searched). There is no extra API-call charge.
Actions and fields
The graph actions (get_neighbors, traverse, find_related, community_summary) need documents uploaded in graph mode. discover says which actions the project can run.
| Action | What you get | Fields |
|---|
| discover | Each document and what is inside it (a sheet’s columns, a document’s sections), the extracted fields, and which actions the project can run. Call it first. | source_ids, document_ids, limit, cursor |
| search | Passages by meaning or keywords, as hits. For an ID, code or invoice number, search the bare identifier. | query, top_k, mode, source_ids, document_ids |
| get_doc | One whole document by id. | document_id |
| get_docs | Several whole documents at once. | document_ids, max_chars |
| get_chunks | One long document in order, up to 25 passages at a time. | document_id, start, end |
| list | Browse the documents without searching. | source_ids, document_ids, limit, cursor |
| query_meta | The structured fields a question names (dates, amounts, parties) and each document’s value. | query, source_ids, limit |
| compute | A figure from the spreadsheets (total, average, count, ranking) or the exact row for one value, over every row. | query, source_ids, document_ids |
| map_reduce | The same question asked of every document in scope, one answer per document. | query, source_ids, document_ids |
| get_neighbors | What is one step from a named thing in the Context Graph. | entity, limit |
| traverse | Everything within a few steps of a named thing, or how two things connect. | entity, depth, category, limit |
| find_related | Connections of one kind across the knowledge base. | category, label, entity_type, limit |
| community_summary | The main themes and groups the knowledge base falls into. | query, limit |
| Field | Type | Meaning |
|---|
| action | string | Required. One of the actions above. |
| query | string | What you are looking for, in words, or a bare identifier you are looking up. |
| top_k | integer | How many passages a search returns. Default 10. |
| mode | "hybrid" | "graph" | How a search ranks. Leave it out and the right one is chosen. |
| document_id | string | One document’s id, from discover, list or a search hit. |
| document_ids | string[] | Narrow to these documents. |
| source_ids | string[] | Narrow to these sources. |
| limit | integer | How many rows: documents for discover and list (default 50), candidates for query_meta (20), links for the graph actions (50), groups for community_summary (3). |
| cursor | string | The next_cursor a previous page returned. |
| entity | string | Where a graph action starts: an entity id from an earlier graph answer (best), or a name as written in the documents. |
| depth | integer | How many steps traverse walks, 1 to 5. Default 2. |
| category | string | The kind of connection to follow or find. |
| label | string | The exact relationship wording, for example reports_to. |
| entity_type | string | Keep only connections with this type of entity on one end. |
| start | integer | First passage to read, from 0. |
| end | integer | Last passage to read, inclusive. |
| max_chars | integer | How much text get_docs returns before it stops. |
Responses
A search answers with hits, best first:
{
"hits": [
{
"document_id": "…",
"document_name": "refund-policy.pdf",
"chunk_text": "Refunds are accepted within 30 days …",
"score": 0.82,
"source_id": "…",
"chunk_idx": 4
}
]
}discover and list page through documents. When has_more is true, send next_cursor back as cursor, or simply send next_page as the next body:
{
"documents": [
{ "id": "…", "name": "handbook.pdf", "source_id": "…", "kind": "text" }
],
"count": 50,
"has_more": true,
"next_cursor": "…",
"next_page": { "action": "list", "cursor": "…" }
}An answer may carry a next_action: the next call, already filled in. Errors carry a message that says what to fix. field is there when the server knows which field is at fault:
{
"error": {
"message": "…",
"field": "files"
}
}Status codes
| Status | Meaning |
|---|
| 200 | Done. The body is the answer. An upload reports each file in results, failures included. |
| 401 | The key is missing, malformed, revoked or expired. |
| 402 | The workspace has no credits left. Top up; a retry does not help. |
| 404 | The key reaches no project. |
| 422 | The request is wrong: no files, too many, too large, a type that is not accepted, a mode that cannot be served, an unknown action, a field the action does not take, or an action that could not answer. The message says why. |
| 429 | Too many requests. Wait for the seconds in the Retry-After header. |
| 502, 503, 504 | A passing server error. Retry after a short wait. Uploading the same bytes again never adds a copy. |