REST API
The Server AI Toolkit REST API contains endpoints for getting the available tools and executing tool calls
Legacy endpoints
V4 is the current API version of the Server AI Toolkit endpoints. V3 endpoints are deprecated; use
v4 for new work. v4 also renames the tool-definition endpoint to /v4/ai/toolkit/fetch-tools;
older names such as /v3/ai/toolkit/tools belong to the v3 API. See the v3 REST API
reference for the legacy endpoints.
Base URL
The Tiptap Cloud base URL is:
BASE_URL=https://api.tiptap.devIn on-premises deployments, the base URL may differ.
In the examples below, requests are written as BASE_URL/v4/ai/toolkit/....
Authentication
All requests must include this authentication header:
Authorization: Bearer JWT, whereJWTis a Tiptap Access Control JWT.
Sign the token server-side with these settings:
- Audience:
AI - Permissions:
AI:Toolkit
To fetch and save Tiptap Cloud documents automatically, add the Documents audience and the Documents:Write permission. Documents:Write includes read and comment access.
See Authentication for how to create a key pair and sign tokens, and the authorization guide for the full setup.
import { SignJWT, importPKCS8 } from 'jose'
const privateKey = await importPKCS8(process.env.TIPTAP_PRIVATE_KEY, 'ES256')
const JWT_TOKEN = await new SignJWT({
permissions: [
{ action: 'AI:Toolkit', resource: '*' },
{ action: 'Documents:Write', resource: 'your-document-id' },
],
})
.setProtectedHeader({ alg: 'ES256' })
.setIssuer(process.env.TIPTAP_ENVIRONMENT_ID)
.setAudience(['AI', 'Documents'])
.setExpirationTime('30m')
.sign(privateKey)The previous App ID + secret authentication flow is documented under Legacy authentication.
Optional fields
Optional fields can be omitted, null, or undefined.
Endpoints
Fetch tool definitions
POST /v4/ai/toolkit/fetch-toolsReturns the prompt and tool definitions that you pass to your AI provider.
Request body:
editorContext(object, required): The editor context returned bygetEditorContext.tools(Record<string, boolean | ToolConfig>, optional, default:{}): Enables, disables, or configures tools. Tools are disabled by default.format('json' | 'shorthand' | 'shorthandV2', optional, default:'json'): Document format used by tool definitions and model output. See Tiptap Shorthand.
tools can contain these keys:
tiptapRead(boolean, optional)tiptapEdit(boolean | { meta?: string }, optional): Setmetawhen you want the AI to include an extra metadata field on every edit operation, such as a short explanation.tiptapQuery(boolean | { meta?: string }, optional): Setmetawhen you want the AI to include an extra metadata field on every operation that changes the document. SeetiptapQuery.getThreads(boolean, optional)editThreads(boolean, optional)readDocument(boolean, optional)replaceDocument(boolean, optional)createDocument(boolean, optional): Alias forreplaceDocument.readSelection(boolean, optional)proofread(boolean | { meta?: string }, optional): Setmetawhen you want the AI to include an extra metadata field on every proofreading edit, such as a short explanation.readBoard,createShapes,arrangeShapes,distributeShapes,createDiagram,updateShapes,deleteShapes,connectShapesandcreateDocFrame(boolean, optional): The board tools, for a whiteboard.
Response:
systemPrompt(string): Add this to the system prompt for your AI request. It teaches the AI how Tiptap documents work, what elements the editor supports, and which document format to use.tools(array): Tool definitions the AI or developer can call. Each array element contains:name(string): Tool name.description(string): Tool description.inputSchema(object): JSON schema for the AI-generated tool input.
Example:
curl --location 'BASE_URL/v4/ai/toolkit/fetch-tools' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT' \
--data '{
"editorContext": { /* editor context data */ },
"tools": {
"tiptapRead": true,
"tiptapEdit": {
"meta": "Briefly explain the edit."
}
},
"format": "shorthandV2"
}'
Error responses
HTTP errors return:
error(object): An object with these properties:message(string): Human-readable error message.status(number): HTTP status code.code(string): Stable error code.data(object, optional): Sanitized structured context.
This endpoint can return:
401withaccess_control_auth_requiredormissing_token: The request did not include a Tiptap Access Control JWT.401with an access-control code such astoken_expiredorsignature_invalid: The JWT was rejected by Access Control.403withfeature_not_available: Server AI Toolkit is not enabled for the environment.403withinsufficient_permissions: The JWT does not grantAI:Toolkit.403withorigin_not_allowed: The requestOriginis not allowed for the environment.422withvalidation_failed: The request body does not match the endpoint schema. The response includeserror.issues, a list of validation issues.422withtool_config_validation_failed: The tool config provided in the request body is invalid. The response includeserror.data.issues, a list of validation issues.429withrate_limited: Access Control rate-limited authentication.429: The server-side rate limiter blocked the request. This response uses a different top-level shape:error(string): Rate limit error message.retryAfter(number, optional): Seconds to wait before retrying.limit(number, optional): Request limit for the current window.window(number, optional): Rate-limit window in seconds.
500withinternal_server_error: An unexpected server error occurred.500withmissing_cloud_api_token: The cloud service is missing internal authentication configuration.503withservice_unavailable: Access Control was temporarily unavailable.
Execute a tool
POST /v4/ai/toolkit/execute-toolExecutes a tool. Use this endpoint after the AI model has generated the tool call.
Request body:
editorContext(object, required): The editor context returned bygetEditorContext.document(object, required): Document to execute the tool against. Use{ "type": "cloud", "id": "your-document-id" }when the API should read from and write to a Tiptap Cloud document. Use{ "type": "inline", "content": { /* Tiptap JSON document */ } }when you want to provide the Tiptap JSON document in the request body.user(string, optional): Author of the edits in version history. It also sets the user associated with AI-generated comments, threads and Tracked Changes suggestions. usereviewOptions.trackedChangesOptions.userId.field(string, optional, default:"default"): Collaborative field to target inside a cloud document. Use this when a document stores multiple editable fields, such as a title and body.tool(object, required): Tool call to execute.name(string, required): Tool name, for example"tiptapRead".input(object, required): Tool input generated by the AI. This is an object that matches the schema and the tool definition for that tool. The schemas and tool definitions of each tool are obtained from the/v4/ai/toolkit/fetch-toolsendpoint.config(unknown, optional): Tool-specific configuration provided by the developer.
format('json' | 'shorthand' | 'shorthandV2', optional, default:'json'): Document format for tool input and output. See Tiptap Shorthand.reviewOptions(ReviewOptions, optional, default:{ mode: 'disabled' }): Controls whether edits are applied directly or as reviewable changes.hiddenAttributes(string[], optional): Node attributes to hide from the AI in the tools that read or edit document content. See Hidden attributes.
Response:
tool(object): Executed tool and its output.name(string): Tool name.output(object): Tool output for the AI.
docChanged(boolean): Whether the document changed.before(JSONContent): The Tiptap JSON document before the tool was executed.document(JSONContent | null): The Tiptap JSON document after the tool was executed, ornullwhen the document did not change. Changes may involve modifications in document content and also modifications in the_hashattributes of the nodes, which are used as unique identifiers and allow the AI to select the nodes of the document.
Example:
curl --location 'BASE_URL/v4/ai/toolkit/execute-tool' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer YOUR_JWT' \
--data '{
"editorContext": { /* editor context data */ },
"document": {
"type": "cloud",
"id": "your-document-id"
},
"user": "ai-assistant",
"tool": {
"name": "tiptapRead",
"input": {
"from": 0
}
},
"format": "shorthandV2"
}'
Error responses
HTTP errors return:
error(object): An object with these properties:message(string): Human-readable error message.status(number): HTTP status code.code(string): Stable error code.data(object, optional): Sanitized structured context. Document and thread upstream failures include fields such asoperation,upstreamStatus,upstreamUrl, andupstreamMethod.
This endpoint can return:
400withmissing_document_credentials: The request uses a cloud document, but the JWT does not include document server credentials.400withmissing_document_options:getThreadsoreditThreadswas executed against an inline document. These tools require a cloud document.400with a thread-store code such asthread_not_foundorcomment_not_found: A thread or comment operation referenced data that does not exist.401withaccess_control_auth_requiredormissing_token: The request did not include a Tiptap Access Control JWT.401with an access-control code such astoken_expiredorsignature_invalid: The JWT was rejected by Access Control.403withfeature_not_available: Server AI Toolkit is not enabled for the environment.403withinsufficient_permissions: The JWT does not grantAI:Toolkit, or it does not grant access to the requested cloud document.403withorigin_not_allowed: The requestOriginis not allowed for the environment.403withunsupported_tool_format: The selected tool does not support the requestedformat.403withtracked_changes_unsupported_schema:reviewOptions.modeistrackedChanges, but the editor schema does not support tracked changes.403withthread_schema_not_supported: The editor schema does not support comments or threads.403withboard_schema_not_supported: A board tool got a document or an editor schema that isn't a whiteboard it can work on.409withconcurrent_edit_conflict: The cloud document changed while the tool was executing. Retry the request with the latest document state.422withvalidation_failed: The request body does not match the endpoint schema. The response includeserror.issues, a list of validation issues.422withtool_config_validation_failed:tool.configisn't valid, like areadSelectioncall withoutuser. The response includeserror.data.issues.429withrate_limited: Access Control rate-limited authentication.429: The server-side rate limiter blocked the request. This response uses a different top-level shape:error(string): Rate limit error message.retryAfter(number, optional): Seconds to wait before retrying.limit(number, optional): Request limit for the current window.window(number, optional): Rate-limit window in seconds.
500withdocument_save_failed: The server could not save the cloud document after loading it, or the save flow was called before a document was loaded.500withdiff_worker_failedordiff_worker_invalid_result: The internal diff worker failed while preparing reviewable changes.500withinternal_server_errororunknown_error: An unexpected server error occurred.500withmissing_cloud_api_token: The cloud service is missing internal authentication configuration.502withdocument_load_failedordocument_save_failed: Loading or saving the cloud document failed upstream. Checkerror.data.upstreamStatusfor the upstream HTTP status.502with a thread or comment code such asthread_list_failed,thread_create_failed,thread_update_failed,thread_delete_failed,thread_resolve_failed,thread_unresolve_failed,comment_create_failed,comment_update_failed, orcomment_delete_failed: A comments API operation failed upstream.503withdiff_worker_queue_timeout: The diff worker queue was saturated or timed out.503withservice_unavailable: Access Control was temporarily unavailable.
Stream a tool
POST /v4/ai/toolkit/stream-toolStreams tool execution. tiptapEdit can apply edits incrementally for a typing effect. Other tools
run after the full input is received and return one final event, like execute-tool.
The request is sent in parts. The first part contains:
editorContext(object, required): The editor context returned bygetEditorContext.document(object, required): Cloud document to stream the edit into:{ "type": "cloud", "id": "your-document-id" }. Inline documents are not supported for streaming.user(string, optional): Author of the edits in version history, comments and threads (for example witheditThreads). It does not set the author of Tracked Changes suggestions, for Tracked Changes authorship usereviewOptions.trackedChangesOptions.userId.field(string, optional, default:"default"): Collaborative field to target inside a cloud document. Streaming supports only thedefaultfield; any other value is rejected.tool(object, required): Tool call to execute, withouttool.input.name(string, required): Tool name, for example"tiptapEdit".config(unknown, optional): Tool-specific configuration provided by the developer.
format('json' | 'shorthand' | 'shorthandV2', optional, default:'json'): Document format for tool input and output. See Tiptap Shorthand.reviewOptions(ReviewOptions, optional, default:{ mode: 'disabled' }): Controls whether edits are applied directly or as reviewable changes.hiddenAttributes(string[], optional): Node attributes to hide from the AI in the tools that read or edit document content. See Hidden attributes.delayMs(number, optional, default:5): Per-character delay in milliseconds for incrementaltiptapEditoutput. Must be between0and1000. Use0to apply edits as fast as possible.
Then send:
- Following parts: The value of
tool.input, streamed as the AI generates it.
Response:
tiptapEdit: Incremental events while edits are applied, followed by a final event with the updateddocument.- Other tools: One final event with the same result shape as
execute-tool.
Error responses
Before streaming starts, HTTP errors use the same JSON shape as execute-tool:
error(object): An object with these properties:message(string): Human-readable error message.status(number): HTTP status code.code(string): Stable error code.data(object, optional): Sanitized structured context.
After streaming starts, errors are sent as NDJSON events:
version(number): Stream protocol version.type('error'): Event type.code(string): Stable error code.status(number): HTTP-style status code.message(string): Human-readable error message.
This endpoint can return or emit:
400withinvalid_request: The request has no body.400withmissing_document_credentials: The JWT does not include document server credentials.400withinvalid_stream_message: A stream message is not valid JSON, fails schema validation, uses an unsupported protocol version, or the stream ends with an unterminated NDJSON line.400withduplicate_start: More than onestartmessage was sent.400withdelta_before_start: Adeltamessage arrived beforestart.400withend_before_start: Anendmessage arrived beforestart.400withincomplete_stream: The request ended before anendmessage arrived.400with a thread-store code such asthread_not_foundorcomment_not_found: A buffered thread or comment operation referenced data that does not exist.401withaccess_control_auth_requiredormissing_token: The request did not include a Tiptap Access Control JWT.401with an access-control code such astoken_expiredorsignature_invalid: The JWT was rejected by Access Control.403withfeature_not_available: Server AI Toolkit is not enabled for the environment.403withinsufficient_permissions: The JWT does not grantAI:Toolkit.403withorigin_not_allowed: The requestOriginis not allowed for the environment.403withtracked_changes_unsupported_schema:reviewOptions.modeistrackedChanges, but the editor schema does not support tracked changes.403withthread_schema_not_supported: The editor schema does not support comments or threads.413withndjson_line_too_long: A single NDJSON line exceeded the maximum size.429withstream_rate_limit_exceeded: Too many concurrent streams are open for the same client.429withrate_limited: Access Control rate-limited authentication.429: The server-side rate limiter blocked the request before streaming started. This response uses a different top-level shape:error(string): Rate limit error message.retryAfter(number, optional): Seconds to wait before retrying.limit(number, optional): Request limit for the current window.window(number, optional): Rate-limit window in seconds.
500withdiff_worker_failed,diff_worker_invalid_result,stream_internal_error, orunknown_error: An unexpected server error occurred during stream processing.500withmissing_cloud_api_token: The cloud service is missing internal authentication configuration.502with document, thread, or comment upstream failure codes such asdocument_load_failed,document_save_failed,thread_list_failed, orcomment_create_failed: A cloud document or comments API operation failed upstream.503withdiff_worker_queue_timeout: The diff worker queue was saturated or timed out.503withservice_unavailable: Access Control was temporarily unavailable.504withstream_request_timeout: The stream exceeded the server request timeout.
Available tools
These tools can be provided to an AI agent. The agent decides which tool to call.
All tools are disabled by default. We recommend starting with tiptapRead and tiptapEdit, then
enabling additional tools as needed.
You can also call these tools directly from your application code to build custom workflows.
Hidden attributes
Use the hiddenAttributes field (string[]) of execute-tool and stream-tool requests to keep node attributes away from the AI, like layout settings that only an export uses. tiptapRead, tiptapEdit, tiptapQuery, replaceDocument, createDocument, readSelection, getThreads and readDocument use it: through these tools, the AI can't read or change these attributes, and the document keeps their values. The other tools ignore it, so the board tools still read and write shapes with all their attributes, like the docId of a doc frame. Pass the same list in every request that reads or edits the document.
- Reads leave the attributes out of the returned content.
- Edits ignore the values that the AI writes for them. A node whose text doesn't change keeps its values, also when it moves. A changed node keeps the values of the node of the same type that it replaces, also when the AI rewrites a whole table or list and adds or removes rows. A paragraph that the AI splits into several paragraphs passes its values to each of them.
- New content, like an added table row, and a node that changes its type, like a paragraph that becomes a heading, get the default values of the schema. A node that the AI moves with a separate insert and delete is new content too.
- When one edit adds a node and completely rewrites the text of a node next to it, the values can go to the added node instead.
- The AI can't carry out requests that need these attributes, like a smaller line height.
- Only node attributes are hidden.
_hashand the tracked-changes attributes can't be hidden. An invalid list fails with422andvalidation_failedinexecute-tool, and with400andinvalid_stream_messageinstream-tool. stream-toolrejects the option fortiptapEditwithinvalid_stream_message, because streamed edits can't keep the values.
tiptapRead
Reads the document in chunks to avoid overflowing the context window.
Tool input (tool.input):
from(number, required): Zero-based index of the first top-level node to read. Must be a non-negative integer.
Tool config (tool.config):
chunkSize(number, optional): Maximum number of characters to read in each tool call. Default:32000omitNullAttributes(boolean, optional): Leaves out node and mark attributes whose value and default are bothnullfrom the returned content. Use it when the schema has many attributes that are usually unset. A node written back without these attributes keeps the same values. Default:false
Tool output (tool.output):
Success response:
success(true): Indicates that the read request was successful.totalNodeCount(number): Total number of top-level nodes in the document.nodeRange([number, number]): Top-level node range that was read.content(JSONContent[] | string): Document content for the returned range. Whenformatisjson, this is a Tiptap JSON fragment. WhenformatisshorthandorshorthandV2, this is a Tiptap Shorthand string.
Error response:
success(false): Indicates that the read request failed.error(string): Error message.totalNodeCount?(number): Total number of top-level nodes.
tiptapEdit
Edits document content.
Tool input (tool.input):
operations(array, required): One or more edit operations, applied sequentially.type('replace' | 'insertBefore' | 'insertAfter', required): Edit to perform.target(string, required): Selects a node of the document where the operation will be applied, or the entire document. It is the value of the_hashattribute of the selected node, or"doc"to target the entire document.content(JSONContent[] | string, required): Replacement or inserted content. Use a Tiptap JSON fragment whenformatisjson, or a Tiptap Shorthand string whenformatisshorthandorshorthandV2. To delete a node, use an empty fragment.meta(string, optional): Metadata for the operation. This field is required when thetiptapEdit.metaoption passed tofetch-toolsis set.
Tool config (tool.config):
threadData(object, optional): Metadata added to created threads.commentData(object, optional): Metadata added to created comments.
Tool output (tool.output):
Success or partial-success response:
success(boolean): Whether all operations completed successfully.operationResults(array): Result for each operation.success(boolean): Whether the operation completed successfully.target(string): String identifier of the element targeted by the operation.error(string | null): Failure reason, ornullif the operation succeeded.
Error response:
success(false): Indicates that the edit request failed.reason('validationError' | 'unexpectedError'): Error category.error(string): Error message.
tiptapQuery
Reads, searches and edits the document with JSON operations. It works on its own, without
tiptapRead or tiptapEdit. It is not available through stream-tool.
Tool input (tool.input):
operations(array, required): 1 to 50 operations, run in order. Each operation selects content and reads or edits it. See thetiptapQueryreference for the operation format.
Tool config (tool.config):
chunkSize(number, optional): Maximum number of characters that all reads of one tool call return together. Default:32000omitNullAttributes(boolean, optional): Leaves out node and mark attributes whose value and default are bothnullfromcontentandsummaryreads. Use it when the schema has many attributes that are usually unset. A node written back without these attributes keeps the same values. Default:falsethreadData(object, optional): Metadata added to created threads.commentData(object, optional): Metadata added to created comments.
Tool output (tool.output):
success(boolean): Whether all operations completed successfully.operationResults(array): Result for each operation that ran. See thetiptapQueryreference.skipped(number): Number of operations that didn't run because an earlier operation failed.
replaceDocument
Replaces the entire document with new content.
Tool input (tool.input):
content(JSONContent | string, required): The replacement document content. Use a Tiptap JSON document whenformatisjson, or a Tiptap Shorthand string whenformatisshorthandorshorthandV2.
Tool config (tool.config):
null
Tool output (tool.output):
Success response:
success(true): Indicates that the document was replaced successfully.
Error response:
success(false): Indicates that the document could not be replaced.error(string): Error message.
createDocument
Alias for replaceDocument. It accepts the same input and returns the same output.
readSelection
Reads the user's current editor selection.
This tool is only compatible with Tiptap Cloud collaborative documents. In multi-field documents, it reads the selection in the requested field.
Tool input (tool.input):
This tool does not take any input. Pass an empty object ({}).
Tool config (tool.config):
user(string, required): The ID of the user whose selection to read. Must matchuser.idconfigured in Collaboration Caret.omitNullAttributes(boolean, optional): Leaves out node and mark attributes whose value and default are bothnullfrom the returned content. Use it when the schema has many attributes that are usually unset. A node written back without these attributes keeps the same values. Default:false
Tool output (tool.output):
Success response:
success(true): Indicates that the request succeeded.isEmpty(false): A non-empty selection was resolved.content(JSONContent[] | string): The nodes of the document that contain the selection, with special markers delimiting the selection.nodeRange([number, number]): The node range where the selection is located.
Success response (empty selection):
success(true): Indicates that the request succeeded.isEmpty(true): The selection is empty
getThreads
Reads comment threads from a cloud document.
Tool input (tool.input):
from(number, required): Zero-based index of the first thread to read. Must be a non-negative integer.
Tool config (tool.config):
chunkSize(number, optional): Maximum number of characters to read in each tool call. Default:32000omitNullAttributes(boolean, optional): Leaves out node and mark attributes whose value and default are bothnullfrom the returned content. Use it when the schema has many attributes that are usually unset. A node written back without these attributes keeps the same values. Default:false
Tool output (tool.output):
Success response:
success(true): Indicates that the read request was successful.totalThreadCount(number): Total number of threads in the document.threadRange([number, number]): Thread range that was read, as[from, to).threads(array): Returned thread objects.id(string): Unique thread identifier.nodeRange([number, number] | null): Node range where the thread is located, ornullif the thread is not annotated in the document.content(JSONContent[] | string | null): Content marked by the thread. Whenformatisjson, this is a Tiptap JSON fragment. WhenformatisshorthandorshorthandV2, this is a Tiptap Shorthand string.nullmeans the thread is not annotated in the document.comments(array): Comments in the thread.id(string): Unique comment identifier.content(string): Comment text.userId(string): ID of the user who created the comment.createdAt(string): ISO timestamp when the comment was created.updatedAt(string): ISO timestamp when the comment was last updated.
resolvedAt?(string | null): ISO timestamp when the thread was resolved, ornullif unresolved.createdAt(string): ISO timestamp when the thread was created.updatedAt(string): ISO timestamp when the thread was last updated.data?(Record<string, unknown>): Public thread metadata.
Error response:
success(false): Indicates that the read request failed.error(string): Error message.totalThreadCount?(number): Total number of persisted threads, when known.
editThreads
Creates and updates comment threads.
Tool input (tool.input):
operations(array, required): One or more thread operations, applied sequentially. Each operation has one of these shapes:createThread:type('createThread', required),nodeHash(string, required), andcontent(JSONContent[] | string, required).contentis the node content withinlineThreadmarks added, as a Tiptap JSON fragment whenformatisjsonor a Tiptap Shorthand string whenformatisshorthandorshorthandV2.createComment:type('createComment', required),threadId(string, required), andcontent(string, required).updateComment:type('updateComment', required),threadId(string, required),commentId(string, required), andcontent(string, required).removeComment:type('removeComment', required),threadId(string, required), andcommentId(string, required).removeThread:type('removeThread', required) andthreadId(string, required).resolveThread:type('resolveThread', required) andthreadId(string, required).unresolveThread:type('unresolveThread', required) andthreadId(string, required).
Tool config (tool.config):
threadData(object, optional): Metadata added to created threads.commentData(object, optional): Metadata added to created comments.
Tool output (tool.output):
Success or partial-success response:
success(boolean): Indicates whether all operations completed successfully.operations(array): Result for each operation.type(string): Operation type that was executed.success(boolean): Whether the operation completed successfully.message(string): Human-readable operation result.threadId?(string): Thread ID for operations that create or reference a thread.
Error response:
success(false): Indicates that the request failed before operations were processed.error(string): Error message.
readDocument
Reads the entire document.
May overflow the context window
readDocument returns the full document. For large documents, use tiptapRead instead.
Tool input (tool.input):
This tool does not take any input. Pass an empty object ({}).
Tool config (tool.config):
omitNullAttributes(boolean, optional): Leaves out node and mark attributes whose value and default are bothnullfrom the returned content. Use it when the schema has many attributes that are usually unset. A node written back without these attributes keeps the same values. Default:false
Tool output (tool.output):
Success response:
success(true): Indicates that the document was read successfully.content(JSONContent[] | string): Whole effective document content. Whenformatisjson, this is a Tiptap JSON fragment. WhenformatisshorthandorshorthandV2, this is a Tiptap Shorthand string.
proofread
Applies proofreading edits.
This tool supports format: "shorthand" and format: "shorthandV2".
Tool input (tool.input):
operations(array, required): One or more proofreading operations, applied sequentially.target(string, required): Selects a node of the document where the operation will be applied, or the entire document. It is the value of the_hashattribute of the selected node, or"doc"to target the entire document.delete(string, required): Exact text to remove. Only its first occurrence in the target node is replaced.insert(string, required): Corrected text to insert in place ofdelete.meta(string, optional): Metadata for the operation. This field is required when theproofread.metaoption passed tofetch-toolsis set.
Tool config (tool.config):
threadData(object, optional): Metadata added to created threads.commentData(object, optional): Metadata added to created comments.
Tool output (tool.output):
Success or partial-success response:
success(boolean): Indicates whether all operations completed successfully.operationResults(array): Result for each operation.target(string): String identifier of the element targeted by the operation.success(boolean): Whether the operation completed successfully.error(string | null): Failure reason, ornullwhen the operation succeeded.
Board tools
Alpha feature
The board tools are currently in alpha
These tools read and change a whiteboard. Execute them with the editor context of the board's editor, on the board's document. See Use with Whiteboard for the setup.
The board tools take plain text, not document content, so they work the same in every format. They aren't available through stream-tool.
A board tool that can't run changes nothing. When the model can fix the call, like an input that doesn't match the schema or ids that aren't on the board, the tool answers with HTTP status 200, and with success: false and an error in its tool output.
When the request itself can't work, execute-tool fails like it does for the other tools:
403withboard_schema_not_supported: The document or the editor context isn't a whiteboard that the tool can work on, like a board without doc frames forcreateDocFrame.403withtracked_changes_unsupported_schema:reviewOptions.modeis'trackedChanges'for a tool that changes the board, but the editor context has no Tracked Changes.readBoarddoesn't check this.
Board tool config
readBoard, createShapes, createDiagram and createDocFrame take this tool config (tool.config):
selectedIds(string[], optional): Ids of the shapes that the user selects, in the order of the selection.viewport({ x: number, y: number, width: number, height: number }, optional): The part of the board that the user sees, in board units.widthandheightmust be above0.
Each field that is missing, null or invalid falls back on its own: to no selection, or to no viewport.
Board placement
createShapes, createDiagram and createDocFrame take these fields in their input (tool.input), so the AI can name the place for new content:
near(string[], optional): Up to 100 ids of the shapes that the new content belongs next to, like the diagram that a summary is about. Defaults to the selected shapes.side('right' | 'below' | 'left' | 'above' | 'between', optional): The side of those shapes for the new content. Defaults to'right', or'below'when the free spot there is closer.'between'puts the new content in the middle between exactly two shapes, and places it like withoutsidefor any other number of shapes.
New shapes go beside the shapes in near that are on the board, or else beside the selected shapes. Without such shapes, they go in the middle of the viewport, or else right of all shapes on the board, or at the origin of an empty board. When other shapes are in the way, they move to the closest free spot.
Board suggestions
With reviewOptions.mode: 'trackedChanges', the board tools write their changes as suggestions of Tracked Changes:
- The shapes that one call adds or deletes share one suggestion, so one
acceptSuggestionorrejectSuggestionreviews them all. - Each changed shape and each new text get a suggestion of their own. A later change of a shape that waits for a review of the same user goes into that suggestion.
- The tools leave a shape alone that waits for another user's review, or for a review that deletes it, and don't delete a shape that waits for a review of a change. They say why in
skippedorskippedArrows.
suggestionIds (string[]) lists the suggestions that the call made or went on with. A suggestion that the call went on with also holds the earlier change, and a change to a shape that an earlier suggestion adds is part of that add, so it isn't listed. Other suggestions stay as they are when you review these ids. Without review, suggestionIds is empty, and the tools leave every shape alone that waits for a review.
readBoard
Reads the shapes of the board, the arrows between them and the selection. It doesn't change the document.
Tool input (tool.input):
This tool does not take any input. Pass an empty object ({}).
Tool config (tool.config):
The board tool config.
Tool output (tool.output):
Success response:
success(true): Indicates that the board was read.shapeCount(number): Number of shapes on the board, arrows included.selectedIds(string[]): Ids of the selected shapes that are on the board.shapes(array): The shapes, selected ones first.id(string): Unique shape identifier.type(string): Node type, likestickyNote,geo,freeText,freehandordocFrame.kind?(string): Kind of a geometric shape, likerectangleordiamond.x,y,width,height(number): Box of the shape, in whole board units.ygrows downwards.color?(string): Color name, likeyellow.text?(string): Text of the shape, one line per paragraph or list item. List items start with-,1.,[ ]or[x]. The text of shapes that aren't selected is cut after 280 characters.docId?(string): Id of the document that a doc frame shows. Every doc frame has it. For a frame without adocIdattribute, it is the shape id, whose document the frame shows.selected?(true): The user selects the shape.suggestion?('add' | 'delete' | 'change'): A suggestion that waits for a review, and adds or deletes the shape, or changes its attributes or its text.
arrows(array): The arrows on the board.id(string): Unique arrow identifier.fromId(string | null): Id of the shape where the arrow starts, ornullfor a free end.toId(string | null): Id of the shape that the arrow points to, ornullfor a free end.label?(string): Label on the arrow, one line per paragraph. The label of arrows that aren't selected is cut after 280 characters.suggestion?('add' | 'delete' | 'change'): A suggestion that waits for a review, and adds or deletes the arrow, or changes its attributes or its label.
omittedShapeCount(number): Number of shapes and arrows that the output leaves out. It lists at most 300.viewport(object | null): Theviewportof the tool config.
createShapes
Adds sticky notes as one grid, or plain text as one column, in front of all shapes.
Tool input (tool.input):
notes(array, required): 1 to 24 notes or texts, in reading order.text(string, required): Text of the note, up to 500 characters. A line break starts a new paragraph. Lines that start with-,1.,[ ]or[x]make a bulleted list, a numbered list or a task list.color('black' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'blue' | 'violet', optional): Color of the note or text. Default:'yellow'for notes,'black'for text
type('note' | 'text', optional):'text'adds free text without a note around it, like a heading or a caption, up to 400 wide, one text below the other. Default:'note'nearandside(optional): Where the notes go. See board placement.
Tool config (tool.config):
The board tool config.
Tool output (tool.output):
Success response:
success(true): Indicates that the notes or texts were added.createdIds(string[]): Ids of the new notes or texts, in the order of the input.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that no notes were added.error(string): Error message.
arrangeShapes
Groups shapes into columns from left to right, each with a free text title on top. The columns start where the shapes are, or at the closest free spot when they would cover other shapes. Shapes only move, so the arrows that connect them follow.
Tool input (tool.input):
groups(array, required): 1 to 12 groups, from left to right, with at most 300 ids in all.title(string, required): Title of the group, up to 60 characters.ids(string[], required): Ids of the shapes in the group, in reading order. A shape joins the first group that names it.
Tool config (tool.config):
null
Tool output (tool.output):
Success response:
success(true): Indicates that the shapes were arranged.movedIds(string[]): Ids of the shapes that moved.titleIds(string[]): Ids of the new titles.skipped(array): Shapes that stayed where they were, each withidandreason, like an id that isn't a shape on the board, an arrow, an id that an earlier group names, or a shape that waits for another user's review.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that no shapes were arranged. The error lists the reasons.error(string): Error message.
distributeShapes
Lines shapes up in one row or column, with equal room between them, in their order along it. They line up on the middle of all of them. The row keeps the outer edges of the shapes, unless the room between them would be under 48, and then the shapes go 48 apart. When the row would cover other shapes, it moves as a whole to the closest free spot, but frames of its shapes don't count. Shapes only move, so the arrows that connect them follow, and the shapes in a moved frame move with it.
Tool input (tool.input):
ids(string[], required): 2 to 300 ids of the shapes to line up.direction('horizontal' | 'vertical', optional): A row from left to right, or a column from top to bottom. Default:'horizontal'
Tool config (tool.config):
null
Tool output (tool.output):
Success response:
success(true): Indicates that the shapes were lined up.movedIds(string[]): Ids of the shapes that moved, with the shapes in moved frames. Shapes that were in place already are left out.skipped(array): Shapes that stayed where they were, each withidandreason, like an id that isn't a shape on the board, an arrow, an id that came earlier, or a shape that waits for another user's review.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that fewer than two shapes could be lined up. The error lists the reasons.error(string): Error message.
createDiagram
Draws shapes with text, connected by arrows, and lays them out as a diagram. The arrows connect the shapes and hold their labels, so both follow when a user moves a shape.
Tool input (tool.input):
title(string, optional): Title above the diagram, up to 80 characters.direction('down' | 'right', optional): Where the arrows mostly point. Default:'down'nodes(array, required): 1 to 40 shapes.key(string, required): The AI's own name for the shape, up to 40 characters and unique in the diagram. Arrows refer to it.text(string, optional): Text in the shape, up to 60 characters. A shape without text is 120 wide and 120 tall.shape('rectangle' | 'ellipse' | 'diamond', optional): Kind of the shape. Another kind becomes a rectangle. Default:'rectangle'color(string, optional): One of the colors ofcreateShapes. Default:'black'
arrows(array, optional): Up to 60 arrows.from(string, required): Key of the shape where the arrow starts.to(string, required): Key of the shape that the arrow points to.label(string, optional): Label on the arrow, up to 24 characters.
nearandside(optional): Where the diagram goes. See board placement.
Tool config (tool.config):
The board tool config.
Tool output (tool.output):
Success response:
success(true): Indicates that the diagram was drawn.createdIds(string[]): Ids of all new shapes: the title, the shapes and the arrows.nodeIds(Record<string, string>): Id of each new shape, by its key.skippedArrows(array): Arrows that were left out, each withfrom,toandreason. An arrow with an unknown key, from a shape to itself, or that came earlier is left out.skippedLabels(array): Arrows that were drawn without their label, each withfrom,toandreason. Arrows of Whiteboard 0.1.0 hold no label.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that the diagram was not drawn.error(string): Error message.
updateShapes
Changes the text, color or kind of shapes, and the labels of arrows. Shapes keep their place and size.
Tool input (tool.input):
shapes(array, required): 1 to 40 shapes, each shape once, with only what changes.id(string, required): Id of the shape.text(string, optional): New text, up to 500 characters, with the same lines as forcreateShapes. It replaces the text of the shape, without its formatting. The text thatreadBoardgives for the shape is no change. An empty text takes the text away. Free text without text stays on the board, so delete it instead. Sticky notes, geometric shapes and free text have text. The text of an arrow is its label, without lists, from Whiteboard 0.2.0 on.color(string, optional): New color, one of the colors ofcreateShapes.kind('rectangle' | 'ellipse' | 'diamond' | 'triangle', optional): New kind of a geometric shape.
Tool config (tool.config):
null
Tool output (tool.output):
Success response:
success(true): Indicates that at least one shape changed.updatedIds(string[]): Ids of the changed shapes.skipped(array): Shapes that stayed as they were, each withidandreason, like a shape that waits for another user's review, or a shape without text that gets atext.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that no shape changed. The error lists the reasons.error(string): Error message.
deleteShapes
Deletes shapes, arrows included. Arrows that connected a deleted shape keep a free end.
Tool input (tool.input):
ids(string[], required): 1 to 100 ids of shapes.
Tool config (tool.config):
null
Tool output (tool.output):
Success response:
success(true): Indicates that the shapes were deleted. With review, they stay with adeletesuggestion until a user accepts it.deletedIds(string[]): Ids of the deleted shapes.skipped(array): Shapes that stayed on the board, each withidandreason, like an id that isn't a shape on the board, or a shape that waits for a review.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that no shapes were deleted. The error lists the reasons.error(string): Error message.
connectShapes
Draws arrows between shapes that are on the board, each with an optional label on it. An arrow runs between the middles of its shapes, or between the middles of their sides when it and its label cover other shapes and labels less there. An arrow back between two shapes takes another line than the arrow there.
Tool input (tool.input):
arrows(array, required): 1 to 40 arrows.from(string, required): Id of the shape where the arrow starts.to(string, required): Id of the shape that the arrow points to.label(string, optional): Label on the arrow, up to 24 characters.
Tool config (tool.config):
null
Tool output (tool.output):
Success response:
success(true): Indicates that at least one arrow was drawn.createdIds(string[]): Ids of the new arrows.skippedArrows(array): Arrows that were left out, each withfrom,toandreason: an unknown shape, an arrow from a shape to itself, a shape that waits to be deleted, or an arrow that the board has already.skippedLabels(array): Arrows that were drawn without their label, each withfrom,toandreason. Arrows of Whiteboard 0.1.0 hold no label.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that no arrow was drawn. The error lists the reasons.error(string): Error message.
createDocFrame
Adds a doc frame with a new, empty document, in front of all shapes. Write the document with tiptapEdit, on the Tiptap Cloud document of its docId. See Write the documents of doc frames.
Tool input (tool.input):
lines(number, optional): About how many lines the document will have, as a whole number from 1 to 400. The frame keeps room for them. Default:12nearandside(optional): Where the frame goes. See board placement.
Tool config (tool.config):
The board tool config.
Tool output (tool.output):
Success response:
success(true): Indicates that the frame was added.frameId(string): Id of the new frame.docId(string): Id of the frame's document.suggestionIds(string[]): See board suggestions.
Error response:
success(false): Indicates that no frame was added.error(string): Error message.