REST API

The Server AI Toolkit provides REST API endpoints for both tools and workflows.

Postman collection

Browse the

Postman collection

for the Server AI Toolkit REST API.

Authentication

All requests must include:

  • Authorization: Bearer <JWT>
  • X-App-Id: <APP_ID>

Generate the JWT server-side with your AI secret. Get your App ID and secret key on the Server AI Toolkit settings page.

import jwt from 'jsonwebtoken'

const JWT_TOKEN = jwt.sign(
  {
    experimental_document_server_id: 'your-document-server-id',
    experimental_document_server_management_api_secret:
      'your-document-server-management-api-secret',
  },
  'your-ai-secret-key',
  { expiresIn: '1h' },
)

See the authorization guide for more information.

Document Server credentials

Include these JWT claims when you want the Server AI Toolkit to fetch and save Tiptap Cloud documents automatically:

  • experimental_document_server_id
  • experimental_document_server_management_api_secret

Base URL

The hosted base URL is:

https://api.tiptap.dev

In the examples below, requests are written as BASE_URL/v3/ai/....

How to provide the document

Most tool and workflow endpoints accept exactly one document source:

  • document: Inline Tiptap JSON
  • experimental_documentOptions: A Tiptap Cloud document reference

experimental_documentOptions has the following shape:

  • documentId (string, required): The Tiptap Cloud document identifier.
  • userId? (string | null, optional): Identifier attributed to edits the AI performs.
  • field? (string | null, optional, default: "default"): Targets a specific collaborative field (Y.js XML fragment) inside the document when omitted or null. Use this when your document stores multiple editable fields — for example a separate title and body — under the same documentId.

Example with a Tiptap Cloud document:

{
  "experimental_documentOptions": {
    "documentId": "your-document-id",
    "userId": "ai-assistant"
  }
}

Example targeting a non-default collaborative field:

{
  "experimental_documentOptions": {
    "documentId": "your-document-id",
    "userId": "ai-assistant",
    "field": "title"
  }
}

Example with an inline document:

{
  "document": {
    "type": "doc",
    "content": []
  }
}

Threads require a cloud document

Thread and comment endpoints always require experimental_documentOptions.documentId.

Session mechanism

Read endpoints return a sessionId that records the node hashes and content hashes the AI saw. Reuse that same sessionId on follow-up edit requests so the server can reject stale edits instead of overwriting newer user changes.

Formats

Most endpoints accept a format field:

  • "json": Standard JSON representation
  • "shorthand": Tiptap Shorthand, a token-efficient format for prompts and model output

proofreader currently supports shorthand only.

Tool endpoints

Get tool definitions

POST /v3/ai/toolkit/tools

Returns the available tool definitions for AI agents.

Request body:

  • schemaAwarenessData (SchemaAwarenessData, required)
  • tools? (object, optional): Enable or disable individual tools
  • operationMeta? (string | null, optional, default: "")
  • format? ('json' | 'shorthand', optional, default: 'json')

Response:

  • tools (array)
    • name (string)
    • description (string)
    • inputSchema (object)

Execute a tool

POST /v3/ai/toolkit/execute-tool

Executes one Server AI Toolkit tool such as tiptapRead, tiptapEdit, getThreads, or editThreads.

Request body:

  • toolName (string, required)
  • input (unknown, required)
  • schemaAwarenessData (SchemaAwarenessData, required)
  • sessionId? (string | null, optional): Reuse the session from a previous read or tool execution to enable stale-read protection.
  • format? ('json' | 'shorthand', optional, default: 'json')
  • chunkSize? (number, optional, default: 32000)
  • reviewOptions? (ReviewOptions, optional, default: { mode: 'disabled' })
  • experimental_commentsOptions? ({ threadData?: Record<string, unknown>, commentData?: Record<string, unknown> }, optional): Metadata attached to new threads and comments created during thread-related tool execution.
  • exactly one of:
    • document
    • experimental_documentOptions

Response:

  • sessionId (string)
  • output (unknown)
  • docChanged (boolean)
  • document (object | null)

Workflow endpoints

Get a workflow definition

Use one of these endpoints:

  • POST /v3/ai/toolkit/workflows/edit
  • POST /v3/ai/toolkit/workflows/insert-content
  • POST /v3/ai/toolkit/workflows/proofreader
  • POST /v3/ai/toolkit/workflows/threads

Request body:

  • format? ('json' | 'shorthand', optional, default: 'json'). The proofreader workflow only accepts 'shorthand'.

Response:

  • systemPrompt (string)
  • outputSchema (object)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/workflows/edit' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "format": "shorthand"
  }'

Keep the returned sessionId and send it with the matching workflow execute request.

Read document content for a workflow

POST /v3/ai/toolkit/read/read-document

Reads document content and returns workflow-ready content.

Request body:

  • range? ({ from: number, to: number }, optional, default: entire document)
  • schemaAwarenessData (SchemaAwarenessData, required)
  • format? ('json' | 'shorthand', optional, default: 'json')
  • sessionId? (string | null, optional)
  • chunkSize? (number, optional, default: 32000)
  • reviewOptions? (ReviewOptions, optional, default: { mode: 'disabled' })
  • exactly one of:
    • document
    • experimental_documentOptions

Response:

  • sessionId (string)
  • output
    • success (boolean)
    • content? (unknown)
    • error? (string)
  • docChanged (boolean)
  • document (object | null)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/read/read-document' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "schemaAwarenessData": { /* schema awareness data */ },
    "format": "shorthand",
    "reviewOptions": {
      "mode": "disabled"
    },
    "experimental_documentOptions": {
      "documentId": "your-document-id",
      "userId": "ai-assistant"
    }
  }'

Keep the returned sessionId and send it with the matching insert-content execute request.

Read the current selection

POST /v3/ai/toolkit/read/read-selection

Reads the selection and returns either a selection payload or an explicit empty state.

Request body:

  • range ({ from: number, to: number }, required)
  • schemaAwarenessData (SchemaAwarenessData, required)
  • format? ('json' | 'shorthand', optional, default: 'json')
  • sessionId? (string | null, optional)
  • chunkSize? (number, optional, default: 32000)
  • reviewOptions? (ReviewOptions, optional, default: { mode: 'disabled' })
  • exactly one of:
    • document
    • experimental_documentOptions

Response:

  • sessionId (string)
  • output
    • when the selection is empty:
      • isEmpty (true)
    • when the selection contains content:
      • isEmpty (false)
      • content (unknown)
      • nodeHashes (string[])
      • nodeRange ({ from: number, to: number })
      • prompt (string)
  • docChanged (boolean)
  • document (object | null)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/read/read-selection' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "schemaAwarenessData": { /* schema awareness data */ },
    "range": { "from": 10, "to": 42 },
    "format": "shorthand",
    "experimental_documentOptions": {
      "documentId": "your-document-id"
    }
  }'

Read threads

POST /v3/ai/toolkit/read/threads

Reads all threads and comments for a Tiptap Cloud document.

Request body:

  • schemaAwarenessData (SchemaAwarenessData, required)
  • format ('json' | 'shorthand', required)
  • experimental_documentOptions ({ documentId: string, userId?: string, field?: string | null }, required)

Response:

  • output
    • threads? (unknown[])
    • error? (string)
  • docChanged (boolean)
  • document (object | null)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/read/threads' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "schemaAwarenessData": { /* schema awareness data */ },
    "format": "shorthand",
    "experimental_documentOptions": {
      "documentId": "your-document-id",
      "userId": "ai-assistant"
    }
  }'

Execute the insert-content workflow

POST /v3/ai/toolkit/execute-workflow/insert-content

Request body:

  • input (unknown, required): Generated insert-content payload
  • range? ({ from: number, to: number }, optional)
  • schemaAwarenessData (SchemaAwarenessData, required)
  • format? ('json' | 'shorthand', optional, default: 'json')
  • sessionId? (string | null, optional)
  • chunkSize? (number, optional, default: 32000)
  • reviewOptions? (ReviewOptions, optional, default: { mode: 'disabled' })
  • exactly one of:
    • document
    • experimental_documentOptions

Response:

  • sessionId (string)
  • output
    • error? (string)
    • range? ({ from: number, to: number })
  • docChanged (boolean)
  • document (object | null)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/execute-workflow/insert-content' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "schemaAwarenessData": { /* schema awareness data */ },
    "input": "This is the replacement content.",
    "range": { "from": 10, "to": 42 },
    "format": "shorthand",
    "reviewOptions": {
      "mode": "disabled"
    },
    "experimental_documentOptions": {
      "documentId": "your-document-id",
      "userId": "ai-assistant"
    }
  }'

Execute the Tiptap Edit workflow

POST /v3/ai/toolkit/execute-workflow/tiptap-edit

Request body:

  • input (object, required): Edit workflow operations
  • schemaAwarenessData (SchemaAwarenessData, required)
  • format? ('json' | 'shorthand', optional, default: 'json')
  • sessionId? (string | null, optional)
  • chunkSize? (number, optional, default: 32000)
  • reviewOptions? (ReviewOptions, optional, default: { mode: 'disabled' })
  • exactly one of:
    • document
    • experimental_documentOptions

Response:

  • sessionId (string)
  • output
    • operationResults? (array)
    • reason? ('validationError' | 'unexpectedError')
    • error? (string)
  • docChanged (boolean)
  • document (object | null)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/execute-workflow/tiptap-edit' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "schemaAwarenessData": { /* schema awareness data */ },
    "input": {
      "operations": [
        {
          "type": "replace",
          "target": "abc123",
          "content": "# Updated heading\n\nUpdated paragraph content."
        }
      ]
    },
    "format": "shorthand",
    "reviewOptions": {
      "mode": "disabled"
    },
    "experimental_documentOptions": {
      "documentId": "your-document-id",
      "userId": "ai-assistant"
    }
  }'

Execute the proofreader workflow

POST /v3/ai/toolkit/execute-workflow/proofreader

Request body:

  • input (object, required): Proofreader operations
  • schemaAwarenessData (SchemaAwarenessData, required)
  • format ('shorthand', required)
  • sessionId? (string | null, optional)
  • chunkSize? (number, optional, default: 32000)
  • reviewOptions? (ReviewOptions, optional, default: { mode: 'disabled' })
  • exactly one of:
    • document
    • experimental_documentOptions

Response:

  • sessionId (string)
  • output
    • operationResults (array)
  • docChanged (boolean)
  • document (object | null)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/execute-workflow/proofreader' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "schemaAwarenessData": { /* schema awareness data */ },
    "input": {
      "operations": []
    },
    "format": "shorthand",
    "reviewOptions": {
      "mode": "trackedChanges",
      "trackedChangesOptions": {
        "userId": "ai-assistant"
      }
    },
    "experimental_documentOptions": {
      "documentId": "your-document-id"
    }
  }'

Execute the comments workflow

POST /v3/ai/toolkit/execute-workflow/threads

Request body:

  • input (object, required): Thread operations
  • schemaAwarenessData (SchemaAwarenessData, required)
  • format? ('json' | 'shorthand', optional, default: 'json')
  • experimental_documentOptions ({ documentId: string, userId?: string, field?: string | null }, required)
  • experimental_commentsOptions? ({ threadData?: Record<string, unknown>, commentData?: Record<string, unknown> }, optional): Metadata attached to new threads and comments created by the workflow.

Response:

  • output
    • operations? (array)
    • error? (string)
  • docChanged (boolean)
  • document (object | null)

Example:

curl --location 'BASE_URL/v3/ai/toolkit/execute-workflow/threads' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer YOUR_JWT_TOKEN' \
  --header 'X-App-Id: YOUR_APP_ID' \
  --data '{
    "schemaAwarenessData": { /* schema awareness data */ },
    "input": {
      "operations": [
        {
          "type": "createComment",
          "threadId": "thread-123",
          "content": "Please clarify this point."
        }
      ]
    },
    "format": "shorthand",
    "experimental_documentOptions": {
      "documentId": "your-document-id",
      "userId": "ai-assistant"
    },
    "experimental_commentsOptions": {
      "threadData": {
        "source": "ai"
      },
      "commentData": {
        "source": "ai"
      }
    }
  }'

Schema awareness prompt

POST /v3/ai/toolkit/schema-awareness-prompt

Returns a prompt that describes the editor schema for the requested format.

Request body:

  • schemaAwarenessData (SchemaAwarenessData, required)
  • format? ('json' | 'shorthand', optional)

Response:

  • prompt (string)

Error handling

The API uses standard HTTP error codes:

  • 400 Bad Request: Invalid body, invalid format, missing document source, or missing Document Server credentials
  • 401 Unauthorized: Missing or invalid JWT or App ID
  • 404 Not Found: Unknown endpoint or tool
  • 422 Unprocessable Entity: Validation failed
  • 429 Too Many Requests: Duplicate request or rate-limit protection
  • 500 Internal Server Error: Unexpected server error
  • 502 Bad Gateway: Failed to load or save the Tiptap Cloud document