Inject content REST API
To inject content into documents server-side, use the PATCH endpoint described in this document. This feature supports version history, tracking changes as well as content added through this endpoint.
The update document endpoint also allows JSON updates to modify documents on your Collaboration server, both On-Premises and Cloud:
- Add
json
,binary
, orbase64
content to any document server-side. - Inject content into specific nodes using the UniqueID extension.
- Users can still collaborate in real-time as content is injected.
- Track user and injected content changes, fully compatible with document history.
Use cases
The content injection REST API enables a couple of handy but sophisticated use cases:
- Live translation of document content.
- Programmatically tagging or manipulating document content server-side.
- Integrating server-side components, like executing SQL queries and displaying results.
- Version history integration and conflict-free merging of concurrent edits.
Subscription required
This feature requires a valid Business or Enterprise subscription and a running Tiptap Cloud instance.
Update a document
To update an existing document on the Collaboration server, you can use the PATCH
method with the following API endpoint:
PATCH /api/documents/:identifier?format=:format
This endpoint accepts a Yjs update message and applies it to the specified document. The format
query parameter specifies the format of the update and can be one of the following:
json
: Updates the document using JSON format (with some caveats, see below).binary
: Directly using Yjs'sY.encodeStateAsUpdate
method.base64
: The binary state encoded as a Base64 string.
Upon successful update, the server will return HTTP status 204
. If the document does not exist, it will return 404
, and if the payload is invalid or the update cannot be applied, it will return 422
.
Example: curl
command to update a document
curl --location --request PATCH 'https://YOUR_APP_ID.collab.tiptap.cloud/api/documents/DOCUMENT_NAME' \\
--header 'Authorization: YOUR_SECRET_FROM_SETTINGS_AREA' \\
--data '@yjsUpdate.binary.txt'
Update via JSON
When updating via JSON, the server computes the difference between the current document state and the provided JSON, then internally calculates the required Yjs update to reach the target state.
To ensure precise updates, especially for node-specific changes, it is recommended to use the nodeAttributeName
and nodeAttributeValue
parameters. These can be generated by Tiptap's UniqueID Extension or a custom implementation.
Note that this only works for top level nodes.
nodeAttributeName
: Configured asattributeName
in the UniqueID extension.nodeAttributeValue
: The unique value generated for the node being updated. You can pass multiple values with?nodeAttributeValue=a&=nodeAttributeValue=b
.
You can use ?mode=append
to append nodes to the document's JSON representation without altering existing nodes.
Omitting these parameters may result in overwriting any updates made between fetching the document and issuing the update call. The get document
call returns a header x-${fragmentName}-checksum
which can be used to detect conflicts by passing
it to the update call as ?checksum=${checksum}
. If the document has been updated since the last fetch, the update will fail with a 409 Checksum mismatch.
status.
Example: Updating a document using JSON
// Define the document name, secret, and application ID
const docName = '' // URI-encoded if necessary
const secret = ''
const appId = '';
// Construct the base URL
const url = `https://${appId}.collab.tiptap.cloud`
// Fetch the current document's JSON representation
const docJson = await axios.get(`${url}/api/documents/${docName}?format=json`, {
headers: {
Authorization: secret
},
})
// Extract the document's JSON content
const tiptapJson = docJson.data
const nodes = tiptapJson.content
// Find and log specific nodes using their unique identifiers
const query = nodes.find(n => n.attrs?.identifier === 'fe5c0789-85d9-4877-a2c3-bccf5d874866').content[0].text
const resultTable = nodes.find(n => n.attrs?.identifier === '246368b6-0746-4ca1-a16f-8d964aff4041')
console.log(`Query: ${query}`)
console.log(JSON.stringify(resultTable.content))
// Append new content to the result table node
resultTable.content.push({
// New table row content here
{
"type": "tableRow",
"content": [
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "Jan"
}
]
}
]
},
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "Thurau"
}
]
}
]
},
{
"type": "tableCell",
"attrs": {
"colspan": 1,
"rowspan": 1
},
"content": [
{
"type": "paragraph",
"attrs": {
"textAlign": "left"
},
"content": [
{
"type": "text",
"text": "jan@janthurau.de"
}
]
}
]
}
]
}
})
// Send the updated JSON back to the server to apply the changes
await axios.patch(`${url}/api/documents/${docName}?format=json`, tiptapJson, {
headers: {
Authorization: secret
}
})
Update only node attrs
If you want to only update attributes of a node, you can use the ?mode=attrs
query parameter. This will only update the attributes of the node and not its content.
In this mode, the nodeAttributeName
and nodeAttributeValue
parameters work for any (not just top level) nodes.
Note that we're deleting all attrs on that node and then setting only the ones specified in the payload of the request. Not specifying a node filter (nodeAttributeName, nodeAttributeValue) will result in all nodes being updated.
curl --location --request PATCH '/api/documents/:identifier?format=json&nodeAttributeName=id&nodeAttributeValue=12&mode=attrs' \
--data '{
"indent": 12,
"textAlign": "right"
}'
Create a document
To seed a new document on the Tiptap Collab server, use the POST
method with the following endpoint:
POST /api/documents/:identifier?format=:format
The server will return HTTP status 204
for successful creation, 409
if the document already exists (you must delete it first to overwrite), and 422
if the action failed.
The format
parameter accepts the same values as the update endpoint (binary
, base64
, or json
).