A comment may seem like one of the simplest pieces of data to synchronize between two applications. Retrieve the text, send it through an API, and display it on the other side. In practice, however, preserving the original formatting can be more complicated than it appears.
For developers building integrations with Jira Cloud, this becomes particularly relevant when working with comments through REST API v3. A comment that looks perfectly formatted in its source application may lose its structure, display unexpected formatting syntax, or fail validation when sent to Jira.
One reason is Atlassian Document Format (ADF), the structured JSON format Jira Cloud uses for rich-text content in API contexts such as issue comments.
While working on comment synchronization between Salesforce and Jira for Sinergify, we explored the practical implications of this transition, particularly when translating rich-text content into a format Jira can interpret correctly.
This article covers how ADF structures comment content, common implementation pitfalls, and considerations for developers building reliable cross-platform integrations.
- Understanding ADF: From Text Syntax to Structured Content
Historically, developers working with Jira integrations may have encountered Wiki Markup, where formatting was represented using special characters and conventions embedded in text.
ADF takes a different approach. Instead of interpreting formatting symbols, it represents content as a structured document containing nodes, attributes, and formatting marks.
For example, a simple comment in ADF looks like this:
{
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Your comment goes here."
}
]
}
]
}
Although the comment contains only a single sentence, it still needs to follow the expected document structure.
Three components are worth understanding:
- Document root: The doc node defines the document, with a version and content array.
- Content nodes: Elements such as paragraph, heading, bulletList, and orderedList describe how the content is organized.
- Formatting marks: Elements such as strong, em, underline, and link define formatting applied to text nodes.
The important conceptual shift is that formatting is no longer just a convention embedded in a string. It is represented explicitly in the document structure.
2. Why ADF Matters When Working with Jira Cloud REST API v3
Jira Cloud REST API v3 expects ADF for comment bodies. This means an integration cannot simply pass a plain string or assume that Wiki Markup will be interpreted as formatted content.
The relevant endpoint is:
http
POST /rest/api/3/issue/{issueIdOrKey}/comment
The request's body property must contain a valid ADF document.
For example, this is not the expected v3 comment body structure:
JSON {
"body": "The issue has been reviewed and is ready for testing."
}
Instead, the text needs to be represented within an ADF document:
JSON
{
"body": {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "The issue has been reviewed and is ready for testing."
}
]
}
]
}
}
This distinction is especially important when modernizing integrations originally built around older Jira API conventions.
A practical consideration: API version migration is not merely a matter of changing an endpoint URL. Developers should also review how request bodies are constructed, validated, and interpreted.
3. Representing Common Comment Scenarios in ADF
Understanding the basic document structure makes it easier to handle everyday comment scenarios.
Plain text
Even a comment without formatting requires the appropriate document and paragraph nodes.
JSON
{
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Changes are ready for testing."
}
]
}
]
}
Multiple paragraphs
When a source comment contains multiple paragraphs, represent them as separate paragraph nodes rather than assuming that newline characters will preserve the original layout.
JSON {
"version": 1,
"type": "doc",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Hello Jira team,"
}
]
},
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "The issue has been reviewed. Changes are ready for testing."
}
]
}
]
}
Bold and italic formatting
Formatting is applied through marks on text nodes.
For bold text:
{
"type": "text",
"text": "Critical",
"marks": [
{
"type": "strong"
}
]
}
For italic text:
{
"type": "text",
"text": "Note:",
"marks": [
{
"type": "em"
}
]
}
These text nodes would typically sit inside a paragraph node within the document.
Bullet lists
A bullet list uses a bulletList node containing listItem nodes. Each list item contains block-level content, typically a paragraph.
{
"type": "bulletList",
"content": [
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "First item"
}
]
}
]
},
{
"type": "listItem",
"content": [
{
"type": "paragraph",
"content": [
{
"type": "text",
"text": "Second item"
}
]
}
]
}
]
}
Hyperlinks
Links are represented using the link mark and an href attribute.
{
"type": "text",
"text": "View Salesforce case",
"marks": [
{
"type": "link",
"attrs": {
"href": "https://example.com/case/001"
}
}
]
}
These examples illustrate the basic patterns. In production integrations, developers should validate the complete document against the schema and the requirements of the specific API context.
4. Common ADF Implementation Mistakes
Based on the challenges involved in translating content between systems, several areas deserve particular attention.
- Treating Wiki Markup as ADF
Wiki Markup and ADF represent formatting differently. For example, bold text is a Wiki Markup convention, whereas ADF represents bold text through a strong mark. Sending one format where the other is expected will not automatically preserve formatting. - Using an Incorrect Node Hierarchy
Text nodes should be placed within appropriate parent nodes, such as paragraphs. An invalid hierarchy can result in request validation errors, even when the text itself is correct. - Assuming Plain Text Requires No Transformation
Even unformatted comments need the correct ADF structure when sent through REST API v3. A conversion layer should consistently handle both simple and rich-text content. - Validating Syntax but Not the Rendered Result
A request that passes structural validation is not the end of the process. The resulting comment should also be checked in Jira to confirm that its paragraphs, links, lists, and formatting appear as intended. - Assuming Every ADF Node Works in Every Context
ADF supports a broad range of content structures, but the supported elements depend on the API context. Check the relevant documentation before introducing less common nodes or marks.
For testing and validation, the Atlassian ADF Playground is a useful starting point.
5. The More Complex Challenge: Converting Rich Text Between Salesforce and Jira
The challenge becomes more significant when an integration synchronizes comments that contain more than plain text.
Consider a Salesforce record containing a rich-text comment with headings, hyperlinks, paragraphs, and bullet points. Salesforce may expose that content as HTML, while Jira Cloud expects an ADF document for its comment API.
This introduces a translation problem between two different content representations.
A robust conversion layer needs to account for:
- Paragraphs and line breaks: Preserve the intended reading flow rather than flattening everything into one text block.
- Lists: Convert HTML list structures into the corresponding ADF list and list-item nodes.
- Text formatting: Map supported HTML formatting to ADF marks, such as bold to strong and italic to em.
- Hyperlinks: Preserve valid URLs and their associated link text.
- Unsupported elements: Handle or remove unsupported markup deliberately instead of allowing it to create malformed output.
- Empty and unusual content: Account for blank comments, consecutive line breaks, special characters, and nested formatting.
For example, an HTML element such as <b> may map to an ADF strong mark, while <ul> and <li> need to be translated into the appropriate list structure.
However, this should not be treated as a simple one-to-one tag replacement exercise. HTML and ADF have different content models, and the conversion logic must preserve meaning and hierarchy as well as formatting.
While developing comment synchronization for Sinergify, this was an important consideration in ensuring that content could move between Salesforce and Jira without unnecessarily losing its original structure.
The broader lesson applies to any cross-platform integration: data synchronization is not complete when the payload arrives; it is complete when the receiving system can interpret the data as intended.
6. A Practical Workflow for Reliable Comment Synchronization
A useful way to approach ADF implementation is to treat content conversion as a distinct stage in the integration workflow.
Step 1: Retrieve the source comment
Identify the source field type and determine whether the content is plain text, HTML, or another representation.
Step 2: Normalize and transform the content
Convert the source content into ADF nodes and marks, preserving supported formatting, links, and paragraph structure.
Step 3: Validate the document
Check the JSON structure, node hierarchy, supported content types, and required attributes before submitting the request.
Step 4: Submit the comment through REST API v3
Send the document through the appropriate Jira comment endpoint and capture the response, including validation or permission errors.
Step 5: Verify the rendered comment
Test representative scenarios in Jira, including plain text, multiple paragraphs, formatting, lists, and links. Monitor failures and use actionable error handling to make troubleshooting easier.
This separation makes the conversion logic easier to test and maintain. It also helps developers distinguish between transformation errors, schema validation failures, API errors, and issues with the final rendering.
7. What Developers Should Take Away
ADF is more than a change in comment syntax. It reflects a shift toward structured content, where the hierarchy and meaning of each element are explicitly represented.
For teams building or maintaining Jira Cloud integrations, a few principles are worth keeping in mind:
- Use the expected ADF structure for comment bodies submitted through REST API v3.
- Treat source-to-ADF conversion as a dedicated part of the integration architecture.
- Preserve semantic structure, not just the visible text.
- Validate against the requirements of the specific API context.
- Test the rendered output, not only the API response.
- Build error handling around both content conversion and API submission.
These principles become especially valuable as integrations exchange increasingly rich content across CRM, support, and engineering workflows.
Final Thoughts
Moving content between applications is often more nuanced than moving data fields. A comment can carry context through its formatting, hierarchy, and links, and losing that structure can affect how effectively teams collaborate.
ADF provides a structured way to represent that content in Jira Cloud. The engineering challenge is ensuring that integrations translate content correctly, respect the receiving API's requirements, and verify the final result.
Our work on Salesforce Jira comment synchronization through Sinergify reinforced the importance of treating content transformation as a first-class integration concern, rather than an afterthought.
If you have implemented ADF in a Jira Cloud integration, how are you handling HTML-to-ADF conversion, unsupported elements, or formatting preservation?
Sharing those approaches can help other developers avoid common pitfalls and build more reliable integrations.
I'm Sonal Nagpal, Product Marketing Manager at Sinergify, a Grazitti Interactive product.