API Reference
Access your MarkNest documents, folders, tags, and files programmatically. Integrate your content into any workflow with our REST API.
Authentication
All API requests require a management API key (prefix
mk_) passed via the
Authorization: Bearer header.
You can create and manage API keys from your dashboard.
curl -H "Authorization: Bearer mk_your-api-key-here" \
https://your-domain.com/api/v1/documents Available Abilities
Endpoints
View full reference →Documents
| Method | Path | Description | Ability |
|---|---|---|---|
| GET | /documents | List all documents | documents:read |
| POST | /documents | Create a document | documents:write |
| GET | /documents/{id} | Get a single document | documents:read |
| PUT | /documents/{id} | Update a document | documents:write |
| DELETE | /documents/{id} | Delete a document | documents:write |
| GET | /documents/{id}/versions | List version history | documents:read |
| GET | /documents/{id}/versions/{versionId} | Get a specific version | documents:read |
Folders
| Method | Path | Description | Ability |
|---|---|---|---|
| GET | /folders | List all folders | folders:read |
| POST | /folders | Create a folder | folders:write |
| GET | /folders/{id} | Get a single folder | folders:read |
| PUT | /folders/{id} | Update a folder | folders:write |
| DELETE | /folders/{id} | Delete a folder | folders:write |
| GET | /folders/{id}/documents | List documents directly in a folder | documents:read |
Tags
| Method | Path | Description | Ability |
|---|---|---|---|
| GET | /tags | List all tags | tags:read |
| POST | /tags | Create a tag | tags:write |
| PUT | /tags/{id} | Update a tag | tags:write |
| DELETE | /tags/{id} | Delete a tag | tags:write |
| GET | /tags/{id}/documents | List documents with a tag | tags:read |
Files
| Method | Path | Description | Ability |
|---|---|---|---|
| GET | /files | List all uploaded files | files:read |
| POST | /files | Upload files | files:write |
| GET | /files/{id} | Get file metadata | files:read |
| PUT | /files/{id} | Update file metadata | files:write |
| DELETE | /files/{id} | Delete a file | files:write |
| GET | /files/{id}/download | Download a file | files:read |
| GET | /files/{id}/serve | Serve a file inline | files:read |
Search & RAG
| Method | Path | Description | Ability |
|---|---|---|---|
| POST | /search/semantic | Hybrid semantic search; returns chunk-level hits | rag:read |
| GET | /documents/{id}/chunks/{chunkId} | Fetch a single chunk by id | rag:read |
Browse the full API reference
Every endpoint, parameter, request body, and response schema — generated directly from the backend OpenAPI specification.
Fixed-folder RAG for AI agents
One account can serve multiple trusted agents. Configure one folder ID in each agent's backend,
then inject that ID and status=published into every semantic search request.
The key needs rag:read; model-generated arguments and user input must not override the scope.
curl -X POST https://api.marknest.net/api/v1/search/semantic \
-H "Authorization: Bearer <management-api-key>" \
-H "Content-Type: application/json" \
-d '{"query":"How do I configure webhooks?","folder_id":"<agent-folder-id>","status":"published","limit":10}' - Folder and status filters apply together to vector and keyword retrieval. A folder includes only its direct documents, not child folders. Multiple folder IDs are not supported.
- Folder is optional in the general API. Omitted, null, or blank values remove the folder filter. A fixed-folder integration must stop retrieval when its configured ID is missing or blank.
- A nonempty nonexistent folder ID returns no hits. Never retry an empty result or a failed request without the configured folder and published filters.
- Folder filters route retrieval; they do not restrict the API key's permissions. The key can still search other folders in the same account. Use separate accounts for private customer data requiring server-enforced separation.
- Chunk reads do not inherit search filters. If fetching a chunk, accept only document/chunk ID pairs from the current search result. Prefer the returned text when it is sufficient.
- Keep agent histories and caches separate. MarkNest does not store search conversation history or cache retrieval results; rate limits and RAG quotas are shared by account.
Conditional writes and compatibility
When strict revisions are enabled by the server, protected writes to existing documents,
folders, and files require If-Match. This also applies to protected action routes.
Read the resource's current ETag before writing; folder writes use the current folder write-state revision.
Do not reuse a document ETag for a folder or file.
# Read the current resource and retain its ETag response header.
curl -i https://api.marknest.net/api/v1/documents/<document-id> \
-H "Authorization: Bearer <management-api-key>"
# Send that exact ETag, including quotes, with the update.
curl -X PUT https://api.marknest.net/api/v1/documents/<document-id> \
-H "Authorization: Bearer <management-api-key>" \
-H 'If-Match: "doc-<document-id>-<revision>"' \
-H "Content-Type: application/json" \
-d '{"content":"# Reviewed update"}' 428 means the precondition is missing; 412 means the revision is stale.
Preserve the pending content, reload the current resource, and review the conflict before retrying.
Do not use wildcard revisions or silently discard local edits. New resource creation, GET requests,
and POST /api/v1/search/semantic do not require a document ETag.
Keep API keys on the backend. Stop retrying invalid credentials (401), distinguish
permission/quota/account-state failures (403), and respect Retry-After
with bounded retries for 429. Account deletion revokes its keys and tokens.
Code Examples
curl -H "Authorization: Bearer mk_your-api-key" \
https://your-domain.com/api/v1/documents curl -H "Authorization: Bearer mk_your-api-key" \
https://your-domain.com/api/v1/documents/42 curl -X POST https://your-domain.com/api/v1/documents \
-H "Authorization: Bearer mk_your-api-key" \
-H "Content-Type: application/json" \
-d '{"title":"Meeting notes","content":"# Summary","status":"draft"}' const res = await fetch("https://your-domain.com/api/v1/documents", {
headers: { "Authorization": "Bearer mk_your-api-key" },
});
const data = await res.json();
console.log(data); Response Format
{
"data": {
"id": 42,
"title": "My Document",
"content": "# Hello World",
"created_at": "2026-01-15T10:30:00Z",
"updated_at": "2026-02-20T14:00:00Z"
}
} {
"data": [
{ "id": 1, "title": "First Document" },
{ "id": 2, "title": "Second Document" }
],
"meta": { "current_page": 1, "last_page": 3, "per_page": 15, "total": 42 }
} {
"message": "Unauthenticated."
} Status Codes
| Code | Meaning |
|---|---|
| 200 | Success |
| 401 | Missing or invalid API key |
| 403 | Missing ability, exhausted RAG quota, or account deletion in progress |
| 404 | Resource not found |
| 412 | Write revision is stale; refresh and review the conflict |
| 422 | Request validation failed |
| 428 | Write precondition required; obtain an ETag and send If-Match |
| 429 | Rate limit exceeded |