Omni Docs
API Reference

API Endpoints

Canonical API contract for the Omni edge proxy and modern PKMS routes.

This page documents the routes exposed by omni-edge-proxy/src/index.ts:33-348 and the modern PKMS routes registered in omni-edge-proxy/src/routes/pkms.ts:1150-1679.

Use Legacy Notes Compatibility for the workspace-scoped compatibility routes that the current desktop client still uses for note CRUD.


Authentication and headers

Most PKMS routes require:

Authorization: Bearer <token>

The proxy accepts several token forms through the shared auth pipeline described in omni-edge-proxy/src/index.ts:75-97 and omni-edge-proxy/src/routes/pkms.ts:319-336.

CORS-allowed headers

The edge proxy explicitly allows these request headers:

Content-Type
Authorization
X-Appwrite-Project
X-Appwrite-Key
X-Proxy-Decrypt
X-Client-Key

See omni-edge-proxy/src/index.ts:35-41.

Response decryption controls

PKMS responses are only transformed when the caller opts in with:

X-Proxy-Decrypt: true

You may also provide a client key directly:

X-Client-Key: <client-key>

Behavior from omni-edge-proxy/src/routes/pkms.ts:122-153 and omni-edge-proxy/src/routes/pkms.ts:222-233:

  1. If X-Proxy-Decrypt is not true, the proxy returns the stored response unchanged.
  2. If X-Proxy-Decrypt: true is present, the proxy resolves a client key.
  3. Client key precedence is:
    1. X-Client-Key
    2. escrowed key resolved through getClientKey in omni-edge-proxy/src/index.ts:75-97
  4. If no client key is available, the response is still returned unchanged.

The response transformer can decrypt:

  • envelope objects with format: "omni.om.encrypted"
  • encrypted blob strings shaped like iv:tag:ciphertext
  • nested arrays and objects containing those values

See omni-edge-proxy/src/routes/pkms.ts:137-220.


Route inventory

MethodPathDescription
GET/healthHealth probe.
GET/v1/meVerify the current token and report whether escrowed client key material exists.
POST/api/v1/webhooks/r1xG2bFatcOoQS0A28AQZ/syncFirebase-backed sync and wrapped-key restoration webhook.
POST/api/v1/webhooks/E6K9u35uZUEIJVnp2NivP/syncFirebase-backed onboarding and client-key escrow webhook.
GET/v1/workspacesList workspaces.
POST/v1/workspacesCreate a workspace.
GET/v1/workspaces/:workspaceIdFetch one workspace.
POST/v1/documentsCreate a unified PKMS document.
PATCH/v1/documents/:idPartially update a unified document.
DELETE/v1/documents/:id?workspace_id=...Delete a unified document.
POST/v1/documents/queryQuery documents with semantic-first orchestration and keyword fallback.
GET/v1/workspaces/:workspaceId/documentsList document summaries for a workspace.
POST/v1/workspaces/:workspaceId/documentsCreate a workspace-scoped unified document.
GET/v1/workspaces/:workspaceId/documents/:documentIdFetch a unified document plus blocks and markdown.
PUT/v1/workspaces/:workspaceId/documents/:documentIdReplace/update a workspace-scoped unified document.
DELETE/v1/workspaces/:workspaceId/documents/:documentIdDelete a workspace-scoped unified document.
POST/v1/workspaces/:workspaceId/chatsCreate a new chat session thread.
PATCH/v1/workspaces/:workspaceId/chats/:threadIdUpdate chat thread title or metadata.
GET/v1/workspaces/:workspaceId/chats/:threadId/messagesFetch messages for a chat session.
POST/v1/workspaces/:workspaceId/chats/:threadId/messagesAppend a message to a chat session thread.
GET/v1/workspaces/:workspaceId/index/statusRead legacy derived-index status.
GET/v1/workspaces/:workspaceId/index/rawRead the raw derived block index.
POST/v1/workspaces/:workspaceId/index/clearClear derived search/index artifacts.
POST/v1/workspaces/:workspaceId/reindexRebuild derived index artifacts from stored documents.
POST/v1/workspaces/:workspaceId/files/upload-urlGenerate a presigned upload or download URL for a workspace file.
GET/v1/workspaces/:workspaceId/vector-manifestRead vector manifest metadata.
PUT/v1/workspaces/:workspaceId/vector-manifestSave vector manifest metadata.
GET/v1/workspaces/:workspaceId/search/block-indexRead the stored block index.
PUT/v1/workspaces/:workspaceId/search/block-indexReplace the stored block index.
GET/v1/workspaces/:workspaceId/graph/block-edgesRead stored block graph edges.
PUT/v1/workspaces/:workspaceId/graph/block-edgesSave stored block graph edges.
POST/v1/uploads/startStart a multipart upload session.
POST/v1/uploads/:uploadId/partUpload a part into an in-memory upload session.
POST/v1/uploads/:uploadId/completeComplete an in-memory upload session and persist the assembled file.

Inventory grounded to omni-edge-proxy/src/index.ts:43-348 and omni-edge-proxy/src/routes/pkms.ts:1150-1679.


Shared schemas

Error response

Most PKMS route failures use:

{
  "error": {
    "code": "error | unauthorized | not_found",
    "message": "string"
  }
}

See omni-edge-proxy/src/routes/pkms.ts:236-238.

Encrypted envelope

{
  "format": "omni.om.encrypted",
  "ciphertext": "iv_hex:auth_tag_hex:ciphertext_hex"
}

See omni-edge-proxy/src/routes/pkms.ts:137-139.

Unified document record

{
  "id": "doc_123",
  "project_id": "project_123",
  "workspace_id": "ws_123",
  "document_type": "note",
  "title": "My document",
  "slug": "my-document",
  "root_block_id": "root_123",
  "document_payload": {},
  "blocks_payload": [],
  "markdown": "# My document",
  "metadata": {},
  "created_at": "2026-06-18T00:00:00.000Z",
  "updated_at": "2026-06-18T00:00:00.000Z"
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:90-104 and omni-edge-proxy/src/routes/pkms.ts:500-529.

Document summary

Workspace-scoped list routes return summaries shaped like:

{
  "id": "doc_123",
  "workspaceId": "ws_123",
  "notebookId": "nb_123",
  "title": "My document",
  "slug": "my-document",
  "rootBlockId": "root_123",
  "createdAt": "2026-06-18T00:00:00.000Z",
  "updatedAt": "2026-06-18T00:00:00.000Z",
  "_meta": {}
}

See omni-edge-proxy/src/routes/pkms.ts:439-451.


Core proxy routes

GET /health

Returns:

{ "status": "ok" }

Grounded to omni-edge-proxy/src/index.ts:43.

GET /v1/me

Verifies the caller token, resolves the user identity, and reports stored profile plus whether escrowed client key material exists.

Required headers:

  • Authorization

Success response:

{
  "ok": true,
  "userId": "string",
  "profile": {
    "userName": "string | null",
    "display_name": "string | null",
    "age": 0
  },
  "clientKeyEscrow": {
    "present": true
  },
  "verifiedAt": "ISO8601 timestamp"
}

Failure response:

{
  "ok": false,
  "error": "Missing Token | Invalid token",
  "details": "string"
}

Grounded to omni-edge-proxy/src/index.ts:325-347.

POST /api/v1/webhooks/r1xG2bFatcOoQS0A28AQZ/sync

Firebase-backed compatibility webhook for session sync and wrapped-key restoration.

Required headers:

  • Authorization

Request body:

{
  "client_temp_public_key": "string"
}

Response:

{
  "secret": "string",
  "userId": "string",
  "status": "new_user | missing_key | incomplete_profile | complete",
  "profile": {
    "userName": "string | null",
    "display_name": "string | null",
    "age": 0
  },
  "wrapped_key": "string | null",
  "debug_log": "Sync complete."
}

Grounded to omni-edge-proxy/src/index.ts:99-225.

POST /api/v1/webhooks/E6K9u35uZUEIJVnp2NivP/sync

Firebase-backed onboarding route for username registration and optional first-time client-key escrow.

Required headers:

  • Authorization

Request body:

{
  "userName": "string",
  "display_name": "string",
  "age": 0,
  "clientKey": "string"
}

Response:

{
  "ok": true,
  "userId": "string",
  "profile": {
    "userName": "string",
    "display_name": "string | null",
    "age": 0
  },
  "clientKeyEscrowed": true,
  "encryptedBlobSaved": true
}

Grounded to omni-edge-proxy/src/index.ts:227-323.


Modern PKMS routes

GET /v1/workspaces

Lists workspaces visible to the authenticated identity.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Success response:

[
  {
    "id": "ws_123",
    "name": "Workspace name",
    "createdAt": "ISO8601 timestamp",
    "updatedAt": "ISO8601 timestamp"
  }
]

Grounded to omni-edge-proxy/src/routes/pkms.ts:339-349 and omni-edge-proxy/src/routes/pkms.ts:1151-1158.

POST /v1/workspaces

Creates a workspace.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Request body:

{
  "name": "Untitled Workspace"
}

Success response:

{
  "id": "ws_123",
  "name": "Untitled Workspace",
  "createdAt": "ISO8601 timestamp",
  "updatedAt": "ISO8601 timestamp"
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:1161-1178.

GET /v1/workspaces/:workspaceId

Fetches one workspace.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Success response:

{
  "workspace": {
    "id": "ws_123",
    "name": "Workspace name",
    "createdAt": "ISO8601 timestamp",
    "updatedAt": "ISO8601 timestamp"
  }
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:1180-1188.

POST /v1/documents

Creates a unified document record.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Request body fields accepted by the implementation include:

  • workspace_id or workspaceId
  • title
  • id optional
  • root_block_id or rootBlockId optional
  • document_payload or documentPayload optional
  • blocks_payload or blocksPayload optional
  • markdown optional
  • metadata or _meta optional
  • indexable_blocks or indexableBlocks optional
  • notebook_id or notebookId optional
  • client_key or clientKey optional

If client_key or clientKey is present, the proxy encrypts documentPayload, blocksPayload, and markdown before storage. See omni-edge-proxy/src/routes/pkms.ts:408-437 and omni-edge-proxy/src/routes/pkms.ts:926-983.

Example request:

{
  "workspace_id": "ws_123",
  "title": "My note",
  "document_payload": {
    "format": "omni.om",
    "title": "My note",
    "type": "document"
  },
  "blocks_payload": [
    {
      "id": "root",
      "type": "page",
      "content": "Hello world"
    }
  ],
  "markdown": "# My note\n\nHello world",
  "metadata": {
    "source": "editor"
  },
  "indexable_blocks": [
    {
      "id": "root",
      "type": "page",
      "content": "Hello world"
    }
  ],
  "client_key": "optional-client-key"
}

Success response:

{
  "document": {
    "id": "doc_123",
    "project_id": "project_123",
    "workspace_id": "ws_123",
    "document_type": "note",
    "title": "My note",
    "slug": "my-note",
    "root_block_id": "root_123",
    "document_payload": {},
    "blocks_payload": [],
    "markdown": "# My note",
    "metadata": {},
    "created_at": "ISO8601 timestamp",
    "updated_at": "ISO8601 timestamp"
  }
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:1227-1235 and omni-edge-proxy/src/routes/pkms.ts:500-529.

PATCH /v1/documents/:id

Partially updates a unified document.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Request body requirements:

  • workspace_id or workspaceId is required

Supported update fields include:

  • title
  • root_block_id or rootBlockId
  • document_payload or documentPayload
  • blocks_payload or blocksPayload
  • markdown
  • metadata_patch
  • indexable_blocks or indexableBlocks
  • notebook_id or notebookId
  • client_key or clientKey

metadata_patch merges keys and removes keys whose value is null. Grounded to omni-edge-proxy/src/routes/pkms.ts:986-1066.

DELETE /v1/documents/:id

Deletes the document and derived artifacts.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Required query parameter:

  • workspace_id or workspaceId

Success response:

{
  "id": "doc_123",
  "deleted": true
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:1250-1262.

POST /v1/documents/query

Queries documents using buildContext, which returns semantic results when available and keyword fallback otherwise.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Request body:

{
  "workspace_id": "ws_123",
  "query": "billing rollout",
  "top_k": 5,
  "include": {
    "notes": true,
    "memories": true,
    "files": false
  },
  "filter": {
    "eq": {
      "document_type": "note"
    }
  },
  "metadata": {
    "filters": {
      "workspaceId": "ws_123",
      "session_id": "ws_123"
    }
  }
}

Success response shape:

{
  "query": "billing rollout",
  "mode": "semantic",
  "items": [],
  "results": [],
  "contextText": "Relevant context:",
  "query_strategy": "semantic"
}

The implementation returns both items and results. See omni-edge-proxy/src/routes/pkms.ts:1068-1148 and omni-edge-proxy/src/routes/pkms.ts:1265-1273.

GET /v1/workspaces/:workspaceId/documents

Lists workspace document summaries.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Optional query parameter:

  • notebookId

Success response:

{
  "documents": [
    {
      "id": "doc_123",
      "workspaceId": "ws_123",
      "notebookId": "nb_123",
      "title": "My note",
      "slug": "my-note",
      "rootBlockId": "root_123",
      "createdAt": "ISO8601 timestamp",
      "updatedAt": "ISO8601 timestamp",
      "_meta": {}
    }
  ]
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:1275-1284.

POST /v1/workspaces/:workspaceId/documents

Creates a workspace-scoped unified document.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Behavior matches POST /v1/documents, except workspace_id is injected from the path. Response contains a summary document instead of the full unified record. Grounded to omni-edge-proxy/src/routes/pkms.ts:1286-1298.

GET /v1/workspaces/:workspaceId/documents/:documentId

Fetches a unified document plus blocks and markdown.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Optional query parameter:

  • clientKey

Behavior:

  • If clientKey query param is present, the route decrypts document.documentPayload, document.blocksPayload, document.markdown, blocks, and markdown before building the response.
  • After that, the shared response transformer may still run if X-Proxy-Decrypt: true is set.

See omni-edge-proxy/src/routes/pkms.ts:1300-1335.

Response shape:

{
  "document": {},
  "blocks": [],
  "markdown": "# My note"
}

PUT /v1/workspaces/:workspaceId/documents/:documentId

Updates a workspace-scoped unified document using the same patch logic as PATCH /v1/documents/:id.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Response shape:

{
  "document": {
    "id": "doc_123",
    "workspaceId": "ws_123"
  }
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:1337-1350.

DELETE /v1/workspaces/:workspaceId/documents/:documentId

Deletes a workspace-scoped unified document.

Required headers:

  • Authorization
  • optional X-Proxy-Decrypt
  • optional X-Client-Key

Success response:

{
  "deleted": true
}

Grounded to omni-edge-proxy/src/routes/pkms.ts:1352-1365.


Supporting PKMS routes

These routes are still implemented and should be documented because they are part of the current proxy surface.

Derived index routes

All require Authorization and optionally accept X-Proxy-Decrypt and X-Client-Key.

MethodPathResponse shape
GET/v1/workspaces/:workspaceId/index/statusLegacyIndexStatus
GET/v1/workspaces/:workspaceId/index/rawraw index object
POST/v1/workspaces/:workspaceId/index/clear{ success: true, message: string }
POST/v1/workspaces/:workspaceId/reindex{ message, status, indexStatus }

Grounded to omni-edge-proxy/src/routes/pkms.ts:1514-1553.

File and manifest routes

MethodPathNotes
POST/v1/workspaces/:workspaceId/files/upload-urlRequires files:write; returns { url, key, method, omniUri }.
GET/v1/workspaces/:workspaceId/vector-manifestReturns { manifest }.
PUT/v1/workspaces/:workspaceId/vector-manifestSaves and returns { manifest }.
GET/v1/workspaces/:workspaceId/search/block-indexReturns { index }.
PUT/v1/workspaces/:workspaceId/search/block-indexSaves and returns { index }.
GET/v1/workspaces/:workspaceId/graph/block-edgesReturns { edges }.
PUT/v1/workspaces/:workspaceId/graph/block-edgesSaves and returns { edges }.

Grounded to omni-edge-proxy/src/routes/pkms.ts:1555-1642.

Upload session routes

These routes do not require the PKMS auth helper in the current implementation.

MethodPathRequest bodyResponse
POST/v1/uploads/start{ workspaceId, filename, contentType }{ uploadId }
POST/v1/uploads/:uploadId/part{ partNumber, data }{ uploaded: true }
POST/v1/uploads/:uploadId/completenone{ key, completed: true }

Grounded to omni-edge-proxy/src/routes/pkms.ts:1644-1678.


Native Chat API (Phase 1)

The Native Chat API provides dedicated endpoints for managing chat threads and message streams, keeping chat interaction decoupled from standard note documents.

[!IMPORTANT] Chats bypass the createUnifiedDocument and patchUnifiedDocument helpers to prevent vector/file bloat. While standard documents generate block bundles and full markdown sidecars, chat sessions store message DAG streams directly in dedicated storage objects.

POST /v1/workspaces/:workspaceId/chats

Creates a new chat session thread. Initializes the underlying storage files (meta.om, document.om.enc, history.om.enc, and vector_state.om).

Request body:

{
  "title": "New Chat"
}

Response:

{
  "id": "chat_session_id",
  "title": "New Chat",
  "createdAt": "ISO8601 timestamp"
}

PATCH /v1/workspaces/:workspaceId/chats/:threadId

Updates the chat thread title or metadata.

Request body:

{
  "title": "Updated Chat Title"
}

Response:

{
  "success": true
}

GET /v1/workspaces/:workspaceId/chats/:threadId/messages

Fetches the complete array of messages in the chat's DAG array.

Response:

[
  {
    "id": "msg_123",
    "role": "user",
    "encryptedContent": "string",
    "createdAt": "ISO8601 timestamp"
  }
]

POST /v1/workspaces/:workspaceId/chats/:threadId/messages

Appends a new message to the message DAG array and increments the messageCount in the meta.om sidecar.

Request body:

{
  "role": "user | assistant",
  "content": "Message content"
}

Response:

{
  "id": "msg_124",
  "role": "user",
  "createdAt": "ISO8601 timestamp"
}

Spotlight Search Integration

[!NOTE] While Chats use a bespoke, lightweight write-path to optimize database and storage operations, they still write a meta.om sidecar file directly under the documents/ prefix. This ensures they are indexed correctly and can be seamlessly queried using the unified search endpoint (POST /v1/documents/query) via Spotlight Search.


Notes for frontend implementers

  • The current desktop client loads workspaces from /v1/workspaces but still performs note CRUD through legacy note routes, not the modern /v1/workspaces/:workspaceId/documents routes. See web-omni/src/features/desktop-client/DesktopClientApp.tsx:23-57 and web-omni/src/features/desktop-client/lib/documentRepository.ts:311-420.
  • Search already uses the modern route /v1/documents/query. See web-omni/src/features/desktop-client/lib/documentRepository.ts:389-420.
  • If you are building a new client, prefer the unified /v1/documents and /v1/workspaces/:workspaceId/documents routes for new work.

On this page