REST API reference
Token-authenticated endpoints for files, folders, memories, retrieval, ingestion, and structured databases.
Orcha provides a REST API for managing context files, folders, and structured databases within workspaces. All API endpoints require authentication via Bearer token.
Base URL: https://app.tryorcha.com
OpenAPI specification
The complete /api/v1 surface is described by a machine-readable OpenAPI 3.1 specification:
GET /api/docs/openapi.json- the specification as JSONGET /api/docs/openapi.yaml- the specification as YAMLGET /api/docs/swagger- interactive Swagger UI
Both spec downloads work with standard tooling, including client generators such as openapi-generator and openapi-typescript.
Authentication
Include your API token in the Authorization header:
Create tokens on the Tokens page with appropriate permissions (read, write, delete).
The full token value is shown exactly once, when the token is created; store it
securely. Afterwards Orcha keeps only a hashed verifier, so the secret cannot be
viewed again. If it is lost, create a new token.
Rate limits
Every /api/v1 request and every MCP tool call counts against per-token minute, hour, and day windows. The limits are abuse protection rather than a billing lever, and they are sized for multi-agent workloads: 600 requests per minute on Free, 1,200 on Starter, 2,400 on Studio and Team, and 6,000 on Pro and Business. Hourly and daily ceilings apply on the lower tiers and are unlimited on the higher ones.
Every response carries the current state:
Exceeding a window returns 429 Too Many Requests with a Retry-After header in seconds. Over MCP, only real work counts: tools/call, resources/read, and prompts/get. Protocol overhead such as initialize and tools/list is free, and each message in a JSON-RPC batch counts individually. Repeated requests with invalid tokens are limited separately per source address.
Workspaces
All files, folders, and structured databases belong to a workspace. When you create an API token, it is automatically scoped to the workspace you are currently viewing. Resources created via the API are placed in the token's associated workspace.
Your current workspace ID can be found in the workspace switcher in the sidebar.
Token scoping
Tokens can be scoped to restrict access:
| Scope type | Behavior |
|---|---|
all | Token can access all folders and files in the workspace |
folders | Token is restricted to specified folders and their subfolders |
When a token is folder-scoped:
- Only files within the allowed folders are accessible
- Subfolders of allowed folders are automatically included
- Root-level files (no folder) are excluded
- Root-level databases are excluded; a database assigned to an allowed folder remains accessible
- Attempting to access out-of-scope resources returns 403 Forbidden
Files
List files
Returns all files accessible to the token within the associated workspace.
Query parameters:
folderId(optional): Filter files by folder ID
Response:
Permission required: read
Get file
Returns a specific file including its content.
Response:
Permission required: read
Get raw file content
Downloads the raw file content with appropriate Content-Type header.
Content-Type by file type:
markdown:text/markdownjson:application/jsonyaml:text/yamltext:text/plain
Permission required: read
Create file
Creates a new file in the token's associated workspace.
Request body:
Fields:
name(required): File namecontent(required): File contentfileType(required): One ofmarkdown,json,yaml,textfolderId(optional): Parent folder ID, null for root
Response: Returns the created file object with workspaceId.
Permission required: write
Update file
Updates an existing file.
Request body:
All fields are optional. Only provided fields will be updated.
Permission required: write
Delete file
Moves a file to trash (soft delete). Files can be restored from the Trash page.
Permission required: delete
Folders
List folders
Returns all folders accessible to the token within the associated workspace.
Query parameters:
parentId(optional): Filter by parent folder ID
Response:
Permission required: read
Get folder
Returns a specific folder.
Permission required: read
Get files in folder
Returns all files in a folder, including files in subfolders by default.
Query parameters:
recursive(optional): Set tofalseto only return direct files (not from subfolders). Default istrue.
Permission required: read
Get subfolders
Returns direct subfolders of a folder.
Permission required: read
Create folder
Creates a new folder in the token's associated workspace.
Request body:
Fields:
name(required): Folder nameparentId(optional): Parent folder ID, null for root
Permission required: write
Update folder
Updates an existing folder.
Request body:
Permission required: write
Delete folder
Moves a folder to trash (soft delete). The folder and its contents can be restored from the Trash page.
Permission required: delete
Memories
A memory is a curated set of context that agents load whole instead of searching. Each memory has a name, a workspace-unique slug, an optional description, an optional useWhen string that tells an agent when the memory applies, and a version counter that increments on every metadata or membership change.
Members come in four kinds, each referencing a target in the same workspace:
| Kind | Reference field | Resolves to |
|---|---|---|
file | fileId | The file's current content |
folder | folderId | Every live file in the folder's subtree (capped at 50 files per folder member) |
source_document | sourceDocumentId | The synced document's retained body |
database | databaseId (optional databaseQuery) | The database's fields and records; databaseQuery accepts the same search, filter, sortFieldId, sortDirection, and limit shape as query_database |
| Endpoint | Permission | Purpose |
|---|---|---|
GET /api/v1/memories | read | List memories in the token workspace |
POST /api/v1/memories | write | Create a memory, optionally with an 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 name, slug, description, useWhen, or isPublic |
DELETE /api/v1/memories/:id | delete | Delete a memory. Its members' targets are untouched |
POST /api/v1/memories/:id/members | write | Add members (non-empty members array of kind + reference) |
DELETE /api/v1/memories/:id/members/:memberId | delete | Remove one member from the memory |
GET /api/v1/memories/:slug/export | read | Export memory metadata plus resolved member contents |
Resolution is bounded and honest about gaps: soft-deleted targets, catalog-only synced documents, truncated folder expansions, and scope exclusions each produce a coverage note instead of a silent omission. Folder-scoped tokens see only in-scope files, never connected-source members, and only databases whose folder is in scope.
Export is the one endpoint that accepts an unauthenticated request, and only for a memory explicitly marked isPublic. An unauthenticated export serves file and folder members only; connected-source and database members are excluded with a coverage note. Every other memory request needs a token.
Retrieval
Search context
Returns ranked, workspace-scoped chunks with source citations.
strategy may be keyword, semantic, or hybrid. The query supports websearch syntax ("quoted phrases", -excluded terms).
searches (optional, 1 to 8 entries) supplies typed sub-queries fused with the original query by weighted reciprocal-rank fusion; the original query runs at double weight. lex entries route to full-text search, vec and hyde entries to vector search. hyde is a short hypothetical answer passage (Hypothetical Document Embeddings). minScore drops weak results, and explain attaches per-result score traces.
mode (optional: fast, balanced (default), or fresh) controls upstream freshness cost. fast searches retained content only. balanced also searches the connected-source catalog and, on a decisive metadata match, fetches up to a few catalog-only bodies live from the provider, cited with syncMode: "live". fresh additionally consults live-mode providers. Live calls are metered against the connection's daily provider budget. sourceIds (optional) restricts results to specific connected sources.
The response contains results (cited evidence), coverage (routing notes: live fetches, catalog matches not fetched, budget or availability limits; never quote these as content), and mode. Each result includes its chunk/document/file identifiers, score, chunk metadata (including startLine/endLine anchors and Markdown headingPath), document updatedAt, and citation.
Permission required: read
Query a single connected source
Queries exactly one connected source: retained content first, then the provider's live-search path or its catalog with a bounded live fetch of the best-matching bodies, all under the connection's daily provider budget. The body takes query (required) and limit (optional, default 5, max 20). The response contains results with citations, coverage notes, and providerOperations. Folder-scoped tokens cannot use this endpoint.
Permission required: read
Fetch a source document
Returns one connected-source document's full body. Retained documents come from the index (origin: "indexed"); catalog-only documents are fetched live from the provider under the daily budget (origin: "live") and are not persisted. The response contains title, content, citation, origin, and providerOperations. Folder-scoped tokens cannot use this endpoint.
Permission required: read
Filesystem access
Execute a VFS script
Runs a read-only, filesystem-shaped script against a virtual tree of the token's workspace. This is the endpoint behind the orcha CLI and the browse_context MCP tool; use it directly when an agent should explore context with familiar commands instead of paging through list endpoints.
The virtual tree mounts four sections plus a root README.md that orients agents:
| Path | Contents |
|---|---|
/files | Workspace files and folders |
/memories | Curated memories; each directory holds file members and a README with useWhen guidance plus pointers to other member kinds |
/databases | Structured databases; each record renders as a markdown file (fields, then page body) |
/sources | Connected read-only sources; documents carry 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. Pipe with | (grep, rg, head, tail, and wc accept piped input) and chain with ; or &&. The script runs in Orcha's own restricted parser; redirection, substitution, and every write-shaped construct are rejected, so the surface is read-only by construction.
grep/rg patterns use RE2 syntax, which matches in time linear to the input so no pattern can stall a request. Constructs that require backtracking, notably lookahead, lookbehind, and backreferences, are not supported and return an error naming the unsupported construct. Pass -F to match the pattern literally. find -name takes a glob (*, ?), not a regular expression.
The response returns the combined output plus citations for every file whose content was returned:
Every execution is bounded by a scan budget (files opened, bytes read, nodes visited, wall clock) and an output cap (maxOutputBytes, 1 KB to 200 KB, default 60 KB). When a limit trips, the output says so explicitly; narrow the path or switch to search_context for ranked retrieval. failed reports the script's bash-style status: true when the last executed command errored or the script aborted on a parse error or budget stop (the orcha CLI exits non-zero on it). stat <path> prints any node's entity ID, deep link, citation label, freshness, and useWhen guidance.
Folder-scoped tokens see a pruned /files tree only (out-of-scope paths simply do not exist), and soft-deleted content is never mounted. Executions and returned content are recorded in usage analytics like any other retrieval.
Permission required: read
Ingestion
Ingest a document
Validates and queues non-Orcha source content for indexing. Replaying the same idempotency key with identical content is recognized and deduplicated within the token's workspace.
New work returns 202 Accepted; an identical replay returns 200 OK with deduplicated: true. Reusing the key with different content returns 409 Conflict. Content is limited to 5 MB and metadata to 16 KB.
Permission required: write
Get ingestion status
Returns pending, indexing, indexed, or failed, plus content hash, indexing time, citation, and any available error. Status is visible only to tokens scoped to the document's workspace.
Permission required: read
Directory sync
The write path behind the CLI's orcha sync, available to any client. A sync posts a manifest of relative paths and text content; the server derives the folder tree, hashes every document, and reconciles against what earlier syncs with the same name created: unchanged files are skipped, changed files are updated, and files absent from the manifest can be pruned to trash. Requires a workspace-wide token; folder-scoped tokens are rejected.
Preview a sync
Creates a run in ready state without writing any content and returns it with a wouldPrune list: previously synced files and folders absent from this manifest that a prune pass would move to trash. Limits: 5,000 documents, 5 MB per document, 24 MB of content per run. Paths must be relative; absolute paths, .. segments, and control characters are rejected. conflictPolicy is update (default), skip, or duplicate; update applies local changes but never overwrites a file edited in Orcha since the last sync, flagging it as a conflict instead.
Permission required: write
Start a sync run
Re-checks plan limits, then queues the run for execution. Returns 202 Accepted, 403 with error: "LIMIT_EXCEEDED" when the run exceeds plan limits, or 409 when the run is not in a startable state.
Permission required: write
Get sync run status
Returns the run status (ready, queued, running, completed, completed_with_warnings, failed, cancelled, rolled_back), progress counters (created, updated, skipped, conflicts, pruned), warnings, and execution results.
Permission required: read
Delete a sync run
Removes the run and its stored manifest snapshot; dry-run previews use this to clean up after themselves. Synced content is untouched, but deleting a completed run forfeits its rollback. Busy runs return 409.
Permission required: write
Sync runs also appear in the web app's import history, where completed runs can be rolled back within 7 days; rollback restores pruned files from trash and reverts updates, always leaving files edited in Orcha alone.
Retrieval analytics
Workspace administrators can request the session-authenticated endpoint:
The response includes query volume, top documents, no-result rate, p50/p95 latency, cache rate, first successful retrieval and MCP activation, daily UTC series, and separate billing-dimension totals. days accepts 1 to 90.
Structured databases
Structured databases contain typed properties and records. Record values are keyed by stable property UUID rather than property name, so renaming a property does not break API consumers.
Supported 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 or, when config.multiple is true, an array of UUIDs. Referenced resources must be active and in the same workspace. A record can also set contentFileId to use a normal Orcha file as its editable page body.
| Endpoint | Permission | Purpose |
|---|---|---|
GET /api/v1/databases | read | List accessible databases |
POST /api/v1/databases | write | Create a database with a primary Name property and default table view |
GET /api/v1/databases/:databaseId | read | Get schema, properties, views, and record count |
PATCH /api/v1/databases/:databaseId | write | Update name, description, icon, or folder |
DELETE /api/v1/databases/:databaseId | delete | Move a database to trash |
GET /api/v1/databases/:databaseId/records | read | Search, sort, filter, target 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 |
GET /api/v1/files/:fileId/database-backlinks | read | List database records that reference 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 non-primary property |
POST /api/v1/databases/:databaseId/views | write | Create a saved table view |
PATCH /api/v1/databases/:databaseId/views/:viewId | write | Update view filters and sorting |
Record query parameters include recordId, search, sortFieldId, sortDirection, filterFieldId, filterOperator, filterValue, limit (maximum 200), and offset. Filter operators are contains, equals, not_equals, is_empty, and is_not_empty.
Example record creation:
Records are indexed automatically. File references and record bodies use stable file IDs and /file/:fileId deep links, while search_context results include native record citations linking to /databases/:databaseId?record=:recordId. Folder-scoped tokens cannot write out-of-scope file references or bodies; inaccessible references are redacted from record responses and excluded from scoped retrieval results.
Imports
Import endpoints are session-authenticated web-app endpoints and enforce the selected workspace's read/write/delete RBAC. Uploads use multipart form data with the ZIP in the archive field. The import guide covers the workflow. These endpoints answered on /api/migrations/* before August 2026; that path still works as a deprecated alias.
| Endpoint | Purpose |
|---|---|
POST /api/import/preview | Validate an obsidian_zip or notion_zip, check quota, and create a dry-run report |
GET /api/import?workspaceId=:id | List import runs and 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 | Request cooperative cancellation |
POST /api/import/:runId/rollback | Roll back untouched imported objects within seven days |
GET /api/import/:runId/report | Download the dry-run/fidelity/execution report |
GET /api/assets/:assetId/content | Read an authorized imported attachment |
Preview fields are workspaceId, provider, and conflictPolicy (update, skip, or duplicate).
Feedback
Submit agent feedback
Sends feedback about the workspace's context to its maintainers: missing or stale content, wrong retrieval results, tool problems, or anything else worth fixing. Delivery reuses the product feedback pipeline (an email to the feedback inbox plus an internal notification); nothing is stored in the workspace. This endpoint backs the orcha feedback CLI command; MCP agents use the submit_feedback tool instead.
| Field | Type | Required | Description |
|---|---|---|---|
| message | string | Yes | The feedback itself, up to 5000 characters |
| category | string | No | One of missing_context, stale_content, wrong_result, tool_problem, other (default other) |
| context | object | No | Structured details, e.g. the query used or the document path; must serialize to 10 KB or less |
| channel | string | No | rest or cli (default rest); the CLI sets this so triage can tell the surfaces apart |
The response is { "message": "Feedback sent" }. A 502 Bad Gateway means an email provider is configured but delivery failed. Permission required: read
Error responses
| Status | Meaning |
|---|---|
400 Bad Request | Invalid request body or parameters |
401 Unauthorized | Missing or invalid authentication token |
403 Forbidden | Token lacks required permission or resource is out of scope |
404 Not Found | Requested resource does not exist |
413 Payload Too Large | An asset or migration upload exceeds the plan's per-object limit |
429 Too Many Requests | A rate-limit window is exhausted; see Retry-After |
Error bodies have the shape:
Validation failures add an errors array with the individual issues.