REST API reference
Token-authenticated endpoints for files, folders, memories, retrieval, ingestion, and structured databases.
Orcha has a REST API for the context files, folders, and structured databases in a workspace. All API endpoints need a Bearer token.
Base URL: https://app.tryorcha.com
OpenAPI specification
An OpenAPI 3.1 specification describes the full /api/v1 surface:
GET /api/docs/openapi.json: the specification as JSONGET /api/docs/openapi.yaml: the specification as YAMLGET /api/docs/swagger: the interactive Swagger UI
Standard tools, such as openapi-generator and openapi-typescript, accept both formats.
Authentication
Put your API token in the Authorization header:
Create tokens on the API Tokens page with the permissions that you need (read, write, delete). Orcha shows the full token value one time, when it creates the token. Store the value in a safe place. After that, Orcha keeps only a hash of the token. You cannot see the secret again. If you lose the secret, create a new token.
Rate limits
Each /api/v1 request and each MCP tool call counts against the minute, hour, and day windows of the token. The limits protect the service against abuse. Orcha does not use them for billing. They are large enough for multi-agent workloads.
The per-minute limit is 600 requests on Free, 1,200 on Starter, 2,400 on Studio and Team, and 6,000 on Pro and Business. The lower tiers also have hourly and daily limits. The higher tiers have no hourly or daily limit.
Each response has headers that show the current state:
If you exceed a window, the server returns 429 Too Many Requests with a Retry-After header in seconds. Over MCP, only tools/call, resources/read, and prompts/get count. Protocol messages such as initialize and tools/list are free. Each message in a JSON-RPC batch counts as one request. Repeated requests with invalid tokens have a separate limit for each source address.
Workspaces
All files, folders, and structured databases belong to a workspace. When you create an API token, Orcha binds it to the workspace that is open at that time. Orcha puts the resources that you create through the API in the workspace of the token.
The workspace switcher in the sidebar shows your current workspace ID.
Token scoping
A token can have a scope that limits access:
| Scope type | Behavior |
|---|---|
all | The token can access all folders and files in the workspace |
folders | The token can access only the specified folders and their subfolders |
For a folder-scoped token:
- Only files in the permitted folders are available
- Subfolders of the permitted folders are included
- Root-level files (files with no folder) are excluded
- Root-level databases are excluded. A database in a permitted folder is available
- A request for a resource that is out of scope returns 403 Forbidden
Files
List files
Returns all files in the workspace that the token can access.
Query parameters:
folderId(optional): Return only the files in this folder
Response:
Permission required: read
Get file
Returns one file with its content.
Response:
Permission required: read
Get raw file content
Returns the raw file content with the applicable Content-Type header.
Content-Type for each file type:
markdown:text/markdownjson:application/jsonyaml:text/yamltext:text/plain
Permission required: read
Create file
Creates a new file in the workspace of the token.
Request body:
Fields:
name(required): The file namecontent(required): The file contentfileType(required): One ofmarkdown,json,yaml,textfolderId(optional): The parent folder ID. Use null for the root
Response: The created file object with workspaceId.
Permission required: write
Update file
Updates a file.
Request body:
All fields are optional. The server updates only the fields that you send.
Permission required: write
Delete file
Moves a file to trash (soft delete). You can restore the file from the Trash page.
Permission required: delete
Folders
List folders
Returns all folders in the workspace that the token can access.
Query parameters:
parentId(optional): Return only the folders in this parent folder
Response:
Permission required: read
Get folder
Returns one folder.
Permission required: read
Get files in folder
Returns all files in a folder. By default, the response includes the files in subfolders.
Query parameters:
recursive(optional): Set tofalseto return only the direct files. The default istrue.
Permission required: read
Get subfolders
Returns the direct subfolders of a folder.
Permission required: read
Create folder
Creates a new folder in the workspace of the token.
Request body:
Fields:
name(required): The folder nameparentId(optional): The parent folder ID. Use null for the root
Permission required: write
Update folder
Updates a folder.
Request body:
Permission required: write
Delete folder
Moves a folder to trash (soft delete). You can restore the folder and its contents from the Trash page.
Permission required: delete
Memories
A memory is a curated set of context. An agent loads the full set instead of a search. Each memory has a name, a slug that is unique in the workspace, an optional description, and an optional useWhen string. The useWhen string tells an agent when the memory applies. A version counter increases on each change to the metadata or the members.
There are four member kinds. Each member refers to a target in the same workspace:
| Kind | Reference field | Resolves to |
|---|---|---|
file | fileId | The current content of the file |
folder | folderId | Each live file in the folder tree, to a maximum of 50 files for each folder member |
source_document | sourceDocumentId | The retained body of the synced document |
database | databaseId (optional databaseQuery) | The fields and records of the database. databaseQuery accepts the same search, filter, sortFieldId, sortDirection, and limit values as query_database |
| Endpoint | Permission | Purpose |
|---|---|---|
GET /api/v1/memories | read | List the memories in the workspace of the token |
POST /api/v1/memories | write | Create a memory, with an optional initial members array |
GET /api/v1/memories/:idOrSlug | read | Get a memory with its members resolved to contents |
PATCH /api/v1/memories/:id | write | Update the name, slug, description, useWhen, or isPublic |
DELETE /api/v1/memories/:id | delete | Delete a memory. The targets of its members do not change |
POST /api/v1/memories/:id/members | write | Add members (a non-empty members array of kind and reference) |
DELETE /api/v1/memories/:id/members/:memberId | delete | Remove one member from the memory |
GET /api/v1/memories/:slug/export | read | Export the memory metadata and the resolved member contents |
Resolution has limits, and the response reports each gap. A soft-deleted target, a catalog-only synced document, a truncated folder, or a member out of scope each produce a coverage note. The response never omits a member silently. A folder-scoped token sees only the files in scope and the databases in a folder in scope. It never sees connected-source members.
The export endpoint is the only endpoint that accepts a request without a token. This works only for a memory with isPublic set to true. An export without a token returns file and folder members only. It excludes connected-source and database members with a coverage note. All other memory requests need a token.
Retrieval
Search context
Returns chunks in rank order, limited to the workspace, with source citations.
strategy is keyword, semantic, or hybrid. The query supports the websearch syntax ("quoted phrases" and -excluded terms).
searches (optional, 1 to 8 entries) adds typed sub-queries. The server fuses them with the original query by weighted reciprocal-rank fusion. The original query has double weight. lex entries go to full-text search. vec and hyde entries go to vector search. A hyde entry is a short hypothetical answer (Hypothetical Document Embeddings). minScore removes weak results. explain adds a score trace to each result.
mode (optional: fast, balanced (default), or fresh) controls the freshness cost. fast searches retained content only. balanced also searches the catalog of connected sources. If the metadata of a catalog entry is a clear match, balanced fetches a small number of catalog-only bodies live from the provider. These results have syncMode: "live". fresh also queries live-mode providers. Each live call counts against the daily provider budget of the connection. sourceIds (optional) limits the results to the specified connected sources.
The response contains results, coverage, and mode. results is the cited evidence. coverage has notes about the route: live fetches, catalog matches that were not fetched, and budget or availability limits. Do not quote coverage notes as content. Each result includes the chunk, document, and file identifiers, the score, and the citation. It also includes the chunk metadata (with startLine and endLine anchors and the Markdown headingPath) and the document updatedAt.
Permission required: read
Query a single connected source
Queries one connected source only. The server searches the retained content first. Then it uses the live-search path of the provider, or its catalog with a limited live fetch of the best bodies. All live calls count against the daily provider budget of the connection. The body accepts query (required) and limit (optional, default 5, maximum 20). The response contains results with citations, coverage notes, and providerOperations. A folder-scoped token cannot use this endpoint.
Permission required: read
Fetch a source document
Returns the full body of one connected-source document. A retained document comes from the index (origin: "indexed"). A catalog-only document comes live from the provider, under the daily budget (origin: "live"). The server does not store a live document. The response contains title, content, citation, origin, and providerOperations. A folder-scoped token cannot use this endpoint.
Permission required: read
Filesystem access
Execute a VFS script
Runs a read-only script with filesystem commands against a virtual tree of the workspace of the token. The orcha CLI and the browse_context MCP tool use this endpoint. Use it directly when an agent must explore the context with familiar commands instead of the list endpoints.
The virtual tree has four directories and a root README.md that describes them:
| Path | Contents |
|---|---|
/files | Workspace files and folders |
/memories | Curated memories. Each directory holds the file members and a README with the useWhen guidance and pointers to the other member kinds |
/databases | Structured databases. Each record is a markdown file (the fields, then the page body) |
/sources | Connected read-only sources. The documents have provider citations |
Supported commands: pwd, cd, ls [-l], tree [-L n], find [-name glob] [-type f|d] [-maxdepth n], cat [-n], grep/rg (-i, -n, -l, -r, -F), head/tail [-n N], wc [-l|-w|-c], stat, and help. Use | to pipe output (grep, rg, head, tail, and wc accept piped input). Use ; or && to chain commands. The script runs in the restricted parser of Orcha. The parser rejects redirection, substitution, and each construct that writes. Thus the surface is read-only by design.
grep and rg patterns use the RE2 syntax. RE2 matches in linear time, so no pattern can stall a request. RE2 does not support constructs that need backtracking: lookahead, lookbehind, and backreferences. If a pattern uses one of these, the server returns an error that names the construct. Use -F to match the pattern as literal text. find -name accepts a glob (*, ?). It does not accept a regular expression.
The response contains the combined output and a citation for each file that the output includes:
A scan budget and an output cap limit each execution. The scan budget counts files opened, bytes read, nodes visited, and wall-clock time. The output cap is maxOutputBytes (1 KB to 200 KB, default 60 KB). If a limit stops the script, the output says so. Then narrow the path, or use search_context for ranked retrieval. failed reports the bash-style status of the script. It is true when the last command failed, or when a parse error or a budget stop ended the script. The orcha CLI exits with a non-zero code in that case. stat <path> prints the entity ID, the deep link, the citation label, the freshness, and the useWhen guidance of a node.
A folder-scoped token sees a pruned /files tree only. Paths that are out of scope do not exist in the tree. Soft-deleted content is never mounted. Usage analytics record each execution and the returned content, the same as other retrieval.
Permission required: read
Ingestion
Ingest a document
Validates content from a source outside Orcha and queues it for the index. If you send the same idempotency key with identical content again, the server detects the repeat and does not index it twice. The check applies in the workspace of the token.
New work returns 202 Accepted. An identical repeat returns 200 OK with deduplicated: true. The same key with different content returns 409 Conflict. The maximum content size is 5 MB. The maximum metadata size is 16 KB.
Permission required: write
Get ingestion status
Returns pending, indexing, indexed, or failed, with the content hash, the index time, the citation, and the error if there is one. Only a token for the workspace of the document can see the status.
Permission required: read
Directory sync
The orcha sync CLI command uses these endpoints. Other clients can use them too. A sync sends a manifest of relative paths and text content. The server derives the folder tree, hashes each document, and compares the manifest with the files that earlier syncs with the same name created. The server skips unchanged files and updates changed files. Files that are not in the manifest can move to trash (prune). A sync needs a workspace-wide token. The server rejects a folder-scoped token.
Preview a sync
Creates a run in the ready state and writes no content. The response includes a wouldPrune list: the files and folders from earlier syncs that are not in this manifest. A prune pass moves them to trash. Limits: 5,000 documents, 5 MB for each document, and 24 MB of content for each run. Paths must be relative. The server rejects absolute paths, .. segments, and control characters. conflictPolicy is update (default), skip, or duplicate. update applies local changes. If a file was edited in Orcha after the last sync, update does not overwrite it and reports a conflict.
Permission required: write
Start a sync run
Checks the plan limits again, then queues the run. Returns 202 Accepted. If the run exceeds the plan limits, returns 403 with error: "LIMIT_EXCEEDED". If the run is not in a state that permits a start, returns 409.
Permission required: write
Get sync run status
Returns the run status, the progress counters, the warnings, and the execution results. The status is one of ready, queued, running, completed, completed_with_warnings, failed, cancelled, or rolled_back. The counters are created, updated, skipped, conflicts, and pruned.
Permission required: read
Delete a sync run
Removes the run and its stored manifest snapshot. Dry-run previews use this endpoint to remove themselves. The synced content does not change. If you delete a completed run, you cannot roll it back later. A busy run returns 409.
Permission required: write
Sync runs also appear in the import history in the web app. You can roll back a completed run for 7 days. A rollback restores pruned files from trash and reverts updates. It never changes a file that was edited in Orcha.
Retrieval analytics
Workspace administrators can send a request to this session-authenticated endpoint:
The response includes the query volume, the top documents, the no-result rate, the p50 and p95 latency, and the cache rate. It also includes the first successful retrieval, the MCP activation, daily UTC series, and separate billing-dimension totals. days accepts 1 to 90.
Structured databases
A structured database has typed properties and records. Record values use the stable property UUID as the key. They do not use the property name. Thus a property rename does not break API clients.
The property types are text, number, boolean, date, select, multi_select, url, relation, file_reference, and asset_reference. A file or asset reference is one UUID. If config.multiple is true, it is an array of UUIDs. The referenced resource must be active and in the same workspace. A record can also set contentFileId. Then a normal Orcha file is the editable page body of the record.
| Endpoint | Permission | Purpose |
|---|---|---|
GET /api/v1/databases | read | List the databases that the token can access |
POST /api/v1/databases | write | Create a database with a primary Name property and a default table view |
GET /api/v1/databases/trash | read | List the databases in trash |
GET /api/v1/databases/:databaseId | read | Get the schema, properties, views, and record count |
PATCH /api/v1/databases/:databaseId | write | Update the name, description, icon, or folder |
DELETE /api/v1/databases/:databaseId | delete | Move a database to trash |
POST /api/v1/databases/:databaseId/restore | delete | Restore a database from trash |
DELETE /api/v1/databases/:databaseId/permanent | delete | Delete a database in trash permanently |
GET /api/v1/databases/:databaseId/records | read | Search, sort, filter, select a citation recordId, and paginate records |
POST /api/v1/databases/:databaseId/records | write | Create a typed record |
PATCH /api/v1/databases/:databaseId/records/:recordId | write | Merge values and save a record version |
DELETE /api/v1/databases/:databaseId/records/:recordId | delete | Move a record to trash |
POST /api/v1/databases/:databaseId/records/:recordId/restore | write | Restore a record from trash |
DELETE /api/v1/databases/:databaseId/records/:recordId/permanent | delete | Delete a record in trash permanently |
GET /api/v1/databases/:databaseId/records/:recordId/versions | read | List the saved versions of a record |
GET /api/v1/files/:fileId/database-backlinks | read | List the database records that refer to a file |
POST /api/v1/databases/:databaseId/fields | write | Add a typed property |
PATCH /api/v1/databases/:databaseId/fields/:fieldId | write | Update a property |
DELETE /api/v1/databases/:databaseId/fields/:fieldId | write | Delete a property that is not the primary property |
POST /api/v1/databases/:databaseId/views | write | Create a saved table view |
PATCH /api/v1/databases/:databaseId/views/:viewId | write | Update the filters and the sort order of a view |
The record query parameters are recordId, search, sortFieldId, sortDirection, filterFieldId, filterOperator, filterValue, limit (maximum 200), and offset. The filter operators are contains, equals, not_equals, is_empty, and is_not_empty.
Example record creation:
The server indexes records automatically. File references and record bodies use stable file IDs and /file/:fileId deep links. search_context results include native record citations with links to /databases/:databaseId?record=:recordId. A folder-scoped token cannot write a file reference or a body that is out of scope. The server redacts references that the token cannot access from record responses and excludes them from scoped retrieval results.
Imports
The import endpoints are session-authenticated web-app endpoints. They apply the read, write, and delete RBAC of the selected workspace. Uploads use multipart form data with the ZIP in the archive field. The import guide describes the procedure. Before August 2026, these endpoints were at /api/migrations/*. That path still works as a deprecated alias.
| Endpoint | Purpose |
|---|---|
POST /api/import/preview | Validate an obsidian_zip or notion_zip, check the quota, and create a dry-run report |
GET /api/import?workspaceId=:id | List the import runs and their progress |
GET /api/import/:runId | Get one run |
POST /api/import/:runId/start | Queue or resume a ready, failed, or cancelled run |
POST /api/import/:runId/cancel | Send a cooperative cancel request |
POST /api/import/:runId/rollback | Roll back imported objects that did not change, for seven days |
GET /api/import/:runId/report | Download the dry-run, fidelity, and execution report |
GET /api/assets/:assetId/content | Read an authorized imported attachment |
The preview fields are workspaceId, provider, and conflictPolicy (update, skip, or duplicate).
Feedback
Submit agent feedback
Sends feedback about the context of the workspace to its maintainers: absent or stale content, wrong retrieval results, tool problems, or other problems. The server sends the feedback through the product feedback pipeline (an email to the feedback inbox and an internal notification). Orcha does not store the feedback in the workspace. The orcha feedback CLI command uses this endpoint. MCP agents use the submit_feedback tool.
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Yes | The feedback text, to a maximum of 5000 characters |
| category | string | No | One of missing_context, stale_content, wrong_result, tool_problem, other (default other) |
| context | object | No | Structured details, for example the query or the document path. The serialized size must be 10 KB or less |
| channel | string | No | rest or cli (default rest). The CLI sets this value so that triage can identify the source |
The response is { "message": "Feedback sent" }. A 502 Bad Gateway response means that an email provider is configured but the delivery failed.
Permission required: read
Error responses
| Status | Meaning |
|---|---|
400 Bad Request | The request body or the parameters are invalid |
401 Unauthorized | The authentication token is absent or invalid |
403 Forbidden | The token does not have the required permission, or the resource is out of scope |
404 Not Found | The resource does not exist |
413 Payload Too Large | An asset or migration upload exceeds the per-object limit of the plan |
429 Too Many Requests | A rate-limit window is exhausted. See Retry-After |
Error bodies have this shape:
A validation failure adds an errors array with each problem.