This page describes rich text formatting for the Entities API (for example, fields.description on a feature). The Entities API enforces a strict HTML whitelist: any unsupported tag results in a 400 response.
When sending rich text to the Entities API:
- Always wrap content in a tag (e.g.
<p>text</p>). Plain text is not accepted. - Use only the tags listed in the tables below.
- Close every tag, including void elements (
<br/>,<hr/>). - Quote all attribute values.
- Use numeric character references such as
 rather than named ones such as .
Notes API uses different rulesFeedback (notes) can arrive from many sources and is read-only in the UI, so the Notes API strips visual styling and keeps only semantic tags rather than rejecting input.
| Tag | Description |
|---|---|
<h1>, <h2> | Headers, these two levels only |
<p> | Paragraph |
<b> | Bold |
<i> | Italics |
<u> | Underline |
<code> | Code |
<ul> | Unordered list |
<ol> | Ordered list |
<li> | List item |
<a> | Link |
<hr/> | Horizontal line |
<pre> | Code block |
<blockquote> | Block quote |
<s> | |
<br/> | Line break |
<img> | Image, inside a <p> |
Tables
Give every table a header row. Cells hold text and the inline tags above; a block element inside a cell and a merged cell (colspan, rowspan) are rejected. A table without a header row is accepted, but it is stored with an empty header row, so the first line of the table comes back blank.
| Tag | Description |
|---|---|
<table> | Table |
<thead>, <tbody> | Table sections |
<tr> | Table row |
<th> | Header cell |
<td> | Body cell |
<table>
<thead>
<tr><th>Field</th><th>Type</th><th>Required</th></tr>
</thead>
<tbody>
<tr><td>name</td><td>string</td><td>yes</td></tr>
</tbody>
</table>Checklists
A checklist is an unordered list whose items carry a checkbox. Only <input type="checkbox"/> is required, and checked="checked" is what stores the ticked state. The classes and the read-only attributes below are what a read returns; they are accepted but not required on the way in.
<ul>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" disabled="disabled" readonly="readonly" /> open task</li>
<li class="task-list-item"><input type="checkbox" class="task-list-item-checkbox" checked="checked" disabled="disabled" readonly="readonly" /> done task</li>
</ul>Code blocks with a language
A code block can name its language, which is what keeps syntax highlighting after a round trip. A block with no language stays a bare <pre>.
<pre><code class="language-ruby">Widget.where(active: true)</code></pre>Placeholder links
Some content has no HTML equivalent: mentions of a person or an item, emoji, embeds such as Figma or Loom, and collapsible sections. Reading a description returns each of them as a link whose destination starts with urn:pb:node:.
<p>Owner: <a href="urn:pb:node:mention:6c169e828fab63509a9e884f">Anchor: @Jane Doe</a></p>Those links are how the content is put back when you write the description again.
- Send a link back exactly as you received it and the original content is restored in its place.
- Delete the link and you delete the content it stands for.
- Duplicate the link and you duplicate that content.
- The link text is a label for people reading the HTML and is ignored, so changing it is harmless. Changing the destination is not: a
urn:pb:node:destination that matches nothing is dropped along with the link.
