API Documentation
Document Format ¶
The Productive JSON Document Format represents rich text stored in Productive objects. It’s very similar to Atlassian Document Fromat (ADF).
It’s currently being used in the following resources:
Resource | Property | Description |
---|---|---|
pages |
body |
Productive Docs are represented by pages resource and it’s body property is stored as Productive Document Format |
JSON structure
A document in Productive is a JSON object, composed of a hierarchy of nodes. There are two categories of nodes: block and inline. Block nodes define the structural elements of the document such as headings, paragraphs, lists, and alike. Inline nodes contain the document content such as text and images. Some of these nodes can take marks that define text formatting or embellishment such as centered, bold, italics, and alike.
A document is ordered, that is, there’s a single sequential path through it: traversing a document in sequence and concatenating the nodes yields content in the correct order.
For example:
{
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello "
},
{
"type": "text",
"text": "world",
"marks": [
{
"type": "strong"
}
]
}
]
}
]
}
Result in the text "Hello world".
Nodes
Nodes have the following common properties:
Property | Required | Description |
---|---|---|
type | ✔ | Defines the type of block node such as paragraph , table , and alike. |
content | in block nodes, not applicable in inline nodes An array contaning inline and block nodes that define the content of a section of the document. |
Block nodes
Block nodes can be subdivided into:
-
the root
doc
node -
top level nodes, nodes that can be placed directly below the root node
-
child nodes, nodes that have to be the child of a higher-level mode
Some top-level nodes can be used as child nodes. For example, the paragraph
node can be used at the top level or embedded within a list
or table
.
Root block node:
{
"type": "doc",
"content": []
}
Top-level block nodes:
-
paragraph
-
blockquote
-
heading
-
ol
-
ul
-
checklist
-
table
-
divider
-
banner
Child block nodes:
-
checklist_item
-
table_row
-
table_cell
-
table_header
-
li
Inline nodes:
-
text
-
image
-
file
-
mention
-
br
Marks
Mark have the following properties:
Property | Required | Description |
---|---|---|
type | ✔ | Defines the type of mark such as code, link, and alike. |
attrs | Further information defining attributes of the mask such as the URL in a link. |
The marks types are:
-
link
-
em
-
strike
-
underline
-
strong
-
code
-
discussion
Node types
Doc
The doc
node is the root container node representing a document.
{
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello world"
}
]
}
]
}
Paragraph
The paragraph
node is a container for a block of formatted text delineated by a carriage return.
It’s the equivalent of the HTML <p>
tag. Paragraph is a top-level block node that can take any inline node as content
.
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello world"
}
]
}
Quote
The blockquote
node is a container for quotes.
{
"type": "blockquote",
"content": [
{
"type": "text",
"text": "Hello world"
}
]
}
Heading
The heading
represents a heading. Heading can have 3 levels.
{
"type": "heading",
"attrs": {
"level": 1
},
"content": [
{
"type": "text",
"text": "Hello world"
}
]
}
Ordered list
The ol
node is a container for ordered list. List node can only contain li
(list item) child block nodes.
{
"type": "ol",
"content": [
{
"type": "li",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello world"
}
]
}
]
}
]
}
Unordered list
The ul
node is a container for unordered list. List node can only contain li
(list item) child block nodes.
{
"type": "ul",
"content": [
{
"type": "li",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello world"
}
]
}
]
}
]
}
Checklist
The checklist
node is a container for list of checkbox items. checklist
can only contain checklist_item
child block nodes.
{
"type": "checklist",
"content": [
{
"type": "cheklist_item",
"attrs": {
"checked": true
},
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello world"
}
]
}
]
}
]
}
Table
The table
node is a container for a table. Table node can only contain table_row
nodes, which can contain table_cell
or table_header
child block nodes.
{
"type": "table",
"content": [
{
"type": "table_row",
"content": [
{
"type": "table_cell",
"attrs": {
"colspan": 1,
"rowspan": 1,
"colwidth": null
},
"content": [
{
"type": "paragraph"
}
]
},
{
"type": "table_cell",
"attrs": {
"colspan": 1,
"rowspan": 1,
"colwidth": null
},
"content": [
{
"type": "paragraph"
}
]
},
{
"type": "table_cell",
"attrs": {
"colspan": 1,
"rowspan": 1,
"colwidth": null
},
"content": [
{
"type": "paragraph"
}
]
}
]
},
{
"type": "table_row",
"content": [
{
"type": "table_cell",
"attrs": {
"colspan": 1,
"rowspan": 1,
"colwidth": null
},
"content": [
{
"type": "paragraph"
}
]
},
{
"type": "table_cell",
"attrs": {
"colspan": 1,
"rowspan": 1,
"colwidth": null
},
"content": [
{
"type": "paragraph"
}
]
},
{
"type": "table_cell",
"attrs": {
"colspan": 1,
"rowspan": 1,
"colwidth": null
},
"content": [
{
"type": "paragraph"
}
]
}
]
}
]
}
Divider
The divider
node is a divider between different blocks.
{
"type": "divider"
}
Banner
The banner
node is a banner-like block element with 4 different types. Supported types are - “warning”, “success”, “critical”, “info”.
{
"type": "banner",
"attrs": {
"type": "warning"
},
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "This is a banner"
}
]
}
]
}
Text
The text
node is inline element that contains text and can have “marks” applied to it.
{
"type": "text",
"text": "hello",
"marks": [
{
"type": "strong"
}
]
}
Image
The image
node represents an inline image and supports src
, alt
, title
and width
attrs.
{
"type": "image",
"attrs": {
"src": "<url>",
"alt": "some text",
"title": "title.jpeg",
"width": 100
}
}
File
The file
node is an inline node that represents a link to an uploaded file.
{
"type": "file",
"attrs": {
"url": "<url>",
"name": "file.html",
"type": "xml"
}
}
Mention
The mention
node is an inline node that represents a reference to an object - person, task or a page. It behaves like a link and visually renders as a mention tag. Mention node supports these attrs:
-
id
-> the ID of the referencing object -
type
-> type of the referencing object -
label
-> the text inside of an mention tag -
avatarUrl
-> URL of an avatar if the mention is person object
{
"type": "mention",
"attrs": {
"id": "1",
"type": "person",
"label": "John Doe",
"avatarUrl": "<url>"
}
}
Break
The br
node inserts a new line in a text string. It’s the equivalent to a <br/>
in HTML.
{
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello"
},
{
"type": "br"
},
{
"type": "text",
"text": "world"
}
]
}
]
}
Mark types
Link
The link
mark sets a hyperlink. This mark applies to text nodes
{
"type": "text",
"text": "Productive",
"marks": [
{
"type": "link",
"attrs": {
"href": "https://productive.io",
"title": "Productive"
}
}
]
}
Em
The em
mark sets italic styling. This mark applies to text
nodes.
{
"type": "text",
"text": "Hello world",
"marks": [
{
"type": "em"
}
]
}
Strike
The strike
mark sets strike-through styling. This mark applies to text
nodes.
{
"type": "text",
"text": "Hello world",
"marks": [
{
"type": "strike"
}
]
}
Underline
The underline
mark sets underline styling. This mark applies to text nodes.
{
"type": "text",
"text": "Hello world",
"marks": [
{
"type": "underline"
}
]
}
Strong
The strong
mark sets strong styling. This mark applies to text nodes.
{
"type": "text",
"text": "Hello world",
"marks": [
{
"type": "strong"
}
]
}
Code
The code
mark sets code styling. This mark applies to text nodes.
{
"type": "text",
"text": "Hello world",
"marks": [
{
"type": "code"
}
]
}
Discussion
The discussion
mark highlights the text and links to a discussion feed. This mark applies to text nodes.
{
"type": "text",
"text": "world",
"marks": [
{
"type": "discussion",
"attrs": {
"discussionId": "1",
"resolvedId": ""
}
}
]
}
Generated by aglio on 02 Aug 2025