Page block types
Every block a page or dashboard can contain, with its stored settings, nesting rules, data dependencies, and limitations.
A Page or Dashboard stores one row per block. Every row has a kind, an order key, a JSON manifest for that kind, and an optional parent. Text is rich inline content: text and hard breaks can carry bold, italic, underline, strikethrough, code, link, colour, and comment marks. Inline content can also contain user, item, record, date, and field mentions, maths, and footnotes.
The canonical block vocabulary below is generated from the contract.
Canonical contract values:
paragraphheading_1heading_2heading_3heading_4heading_5heading_6bulleted_list_itemnumbered_list_itemto_dotogglequotecalloutcodedividerimagebookmarkembedfilevideoaudiocolumn_listcolumndatabase_viewpage_linktable_of_contentsequationtablesynced_pagefootnotemetricinsightactivity_feedbuttonform_embeddrive_embedcontroltemplate_textdashboard_tabsrepeatdocagendaclock_intimesheettabstabmermaidbreadcrumbrecord_embedconnector_view
Text blocks
Paragraph paragraph
The default rich-text block. It stores rich content, a palette colour, horizontal and vertical alignment, and dashboard card appearance. A Paragraph may contain child blocks, which is how indented content is represented.
Heading 1 heading_1
The largest rich-text heading. It has the same colour, alignment, vertical
alignment, and card appearance settings as a Paragraph. Headings contribute to
a Table of contents. Setting toggleable makes it a toggle heading: its child
blocks fold under it, and only a toggle heading takes an indented block. A
plain heading stays a flat section title.
Heading 2 heading_2
A second-level rich-text heading. Its settings, toggleable option and Table
of contents behaviour match Heading 1; only its semantic and visual level
differ.
Heading 3 heading_3
A third-level rich-text heading with the same colour, alignment, appearance, and outline behaviour as the other headings.
Heading 4 heading_4
A fourth-level rich-text heading. Use it below a Heading 3 in a document outline; it has no kind-specific settings beyond the shared heading settings.
Heading 5 heading_5
A fifth-level rich-text heading. It is stored as its own kind so the document outline and renderer retain the intended hierarchy.
Heading 6 heading_6
The smallest rich-text heading. It completes the six stored outline levels and has the same shared heading settings.
Bulleted list item bulleted_list_item
One unordered-list row. It stores rich content and colour and may contain children for nested content. Alignment is deliberately not stored because the list gutter stays left-anchored.
Numbered list item numbered_list_item
One ordered-list row. Consecutive items are rendered as a numbered sequence. It stores rich content and colour and may contain children; it has no alignment setting.
To-do to_do
A rich-text task with a checked boolean and colour. Ticking it writes the
block manifest; it is not a database Checkbox and does not become filterable in
a database view. It may contain child blocks.
Toggle toggle
A rich-text disclosure label whose child blocks are the collapsible content. It stores rich content and colour. The open or closed editor state is not part of its persisted manifest.
Quote quote
An aligned rich-text quotation. It supports colour, horizontal and vertical alignment, dashboard appearance, and child blocks.
Callout callout
A highlighted aside with rich content, an optional icon (an emoji), colour,
and a variant tone: info, success, warning, danger, or neutral.
Without an icon the tone’s default emoji shows. It can contain child blocks.
It does not store the broader dashboard card appearance settings used by
Paragraph and Quote.
Code code
A code block stores plain code, a language identifier, an optional caption,
and whether long lines wrap. It is not rich text and Snoze does not execute it;
use a Code Action when code must run.
Divider divider
A horizontal or vertical separator. It stores orientation plus dashboard
background, border, radius, shadow, and padding appearance. It contains no
content.
Media and link blocks
Image image
An image can reference an uploaded fileId or a URL. It stores a rich caption,
numeric width, alignment, and a full-width switch. A URL is presentation data;
the manifest does not promise that Snoze has copied the remote asset.
Bookmark bookmark
A rich link preview. It stores the URL plus cached title, description, image, site name, icon, and a rich caption. Those preview fields are a snapshot and may become stale when the destination changes.
Embed embed
An external URL shown inline. It stores height, alignment, full-width state,
and a rich caption. An optional provider (youtube, vimeo, loom,
figma, google_maps, spotify, codepen, miro, google_drive) shapes
the empty block’s prompt and accepts only that provider’s links. Whether the
destination renders depends on that site’s embedding policy; a valid URL does
not guarantee it permits framing.
File file
An uploaded or linked file tile. It stores fileId or URL, display name, byte
size, and a rich caption. This is page content, separate from a File field on a
database record.
Video video
An uploaded or linked video with a rich caption, width, alignment, and full-width state. The manifest does not define transcoding or a guaranteed set of remote video hosts.
Audio audio
An uploaded or linked audio clip with a rich caption. It stores fileId or
URL, but has no width or alignment settings.
Layout and structure blocks
Column list column_list
The structural parent for side-by-side Columns. It has no manifest settings
and may contain only column blocks. A Column list cannot be placed inside a
Column or another Column list.
Column column
One child of a Column list. widthRatio controls its share of the row. It can
contain ordinary blocks, but not a Column or Column list, and it cannot exist at
the document root.
Tabs tabs
A tabbed container. It has no settings and may contain only tab blocks; one
panel shows at a time, and which one is open is each viewer’s own view state.
Tabs cannot be nested inside tabs. Exports and phones show every panel in
order.
Tab tab
One panel of a Tabs block, with a label of up to 80 characters. It holds
ordinary blocks and cannot exist outside a Tabs block.
Breadcrumb breadcrumb
The page’s place in the workspace: its parent folders and pages, resolved live from the item tree, so moving the page updates the trail. It has no settings.
Mermaid diagram mermaid
Mermaid source in code (up to 20,000 characters) with an optional rich
caption, shown as a rendered diagram beside its code while editing. Rendering
uses Mermaid’s strict security level: no click handlers, scripts or raw HTML.
Table of contents table_of_contents
A computed outline of the page’s heading blocks. It has no stored settings or hand-written entries; the client derives the outline from Heading 1–6 blocks.
Equation equation
A display-maths block. It stores a formula string and optional rich caption. Its schema accepts the string; whether a particular expression renders is up to the maths renderer.
Table table
A static grid with row and column counts, a two-dimensional array of rich-text cells, and optional column widths. It has no typed fields, filters, sorts, or records. Use a Database view for data that needs those features.
Footnote footnote
The stored body for a footnote, identified by footnoteId and containing rich
text. Inline footnote nodes refer to it. It is not a page footer or citation
manager.
Workspace and data blocks
Database view database_view
An inline view of a database. New embeds store databaseId, viewKind, and an
owned viewManifest, so changing the embed does not mutate a saved database
view; viewId is a legacy saved-view pointer. Parameter filters can bind
dashboard parameters into the view, selectionParam can publish the current
selection, and restrictAccess hides the embed from people without target
access. The block also supports dashboard card appearance.
Page link page_link
A card that opens another workspace item by itemId. It can enforce target
access with restrictAccess and supports dashboard card appearance. It is a
reference, not a copy of the target page.
Synced page synced_page
A live rendering of another block surface selected by surfaceId, with an
option to show its title. Edits affect the referenced surface rather than a
detached copy. The current contract does not store a frozen version or a
fallback snapshot if that surface becomes unavailable.
Metric metric
A data widget: one or more metrics drawn as a number (KPI), line, area,
column, bar, combo, donut, funnel, waterfall, table, leaderboard, progress,
gauge, or heatmap. A metric is either an aggregate — count, count_unique,
sum, avg, median, min, max, or latest over a database or a Snoze
app (time entries, shifts, calendar events, activity), with an
optional filter and date field — or a formula over other metrics, such as
[Revenue] - [Expenses], which may combine different databases.
On a Dashboard, metrics usually live in the dashboard’s metric library so every widget reads the same definition; a widget can also carry its own. The widget groups by a date grain, a field, or a shared field, can split series by a second grouping, and follows the dashboard’s period and comparison unless it sets its own. It also sets sort, a top-N limit with the rest folded into Other, whether empty groups show, and visual options (stacking, labels, legend, sparkline, target, thresholds). Metric presentation covers number, currency, percent, and duration formats, decimals, compact notation, prefix and suffix, whether higher is better, and a target.
Metrics saved before the metric library (a single databaseId, fn,
fieldKey, and display) still render, and are upgraded to the current
shape the next time they are edited.
Insight insight
A durable written briefing. It stores title, body, the prompt that produced it, refresh time, and source item IDs. Refreshing writes ordinary block data, so everyone sees the same reviewable result; it is not recomputed separately for each viewer. It supports access restriction and card appearance.
Activity feed activity_feed
A recent-workspace-events feed with an optional item limit and dashboard card appearance. The client caps the catch-up feed; this is not an unbounded event archive or a configurable event query.
Form embed form_embed
An inline workspace Form selected by item ID. It uses the form’s own questions,
validation, target database, and submission behaviour. restrictAccess
controls whether a viewer without target access sees it, and card appearance
controls its dashboard frame.
Drive embed drive_embed
The workspace drive and folder browser, optionally starting at folderId.
With no folder it starts at the workspace root. It owns its navigation state
and supports access restriction and dashboard card appearance.
Interactive dashboard blocks
Button button
A labelled control bound either to a saved Action by actionId or to a local
command: open an item, set a dashboard parameter, or open a dashboard tab.
Legacy inline refresh/create/open bindings still decode, but editors migrate
them when possible. Server actions retain their own permissions and run
history; a button is not an authority bypass.
Control control
An input that writes a named dashboard parameter. Its control can be select,
search, date, member, segmented, or toggle, with an optional label and
placeholder. Other blocks must explicitly bind to the same parameter name;
the control does not filter every widget automatically.
Template text template_text
Presentation text with a template string and an explicit token list. Tokens can read dashboard parameters and data exposed by the runtime. They render as ordinary text, not HTML and not an unrestricted expression language. The block also supports alignment and card appearance.
Dashboard tabs dashboard_tabs
A child-bearing tab container with one to eight tab definitions and dashboard card appearance. Its children are assigned to tabs by the dashboard runtime. Tab containers cannot be nested inside each other.
Doc doc
A small document inside a dashboard card: headings, paragraphs, lists,
to-dos, toggles, quotes, callouts, code, dividers, tables, and equations,
edited with the same editor as Pages — including the / menu and Markdown
paste. Its blocks are stored in the widget itself (up to 300), with an
optional title and card appearance. People who can edit the dashboard can
edit a Doc in place without entering edit mode.
Agenda agenda
Upcoming calendar events the viewer can see, for today, this week, the next 7 days, or the next 30 days, optionally limited to chosen calendars and a number of events. It reads as the viewer and shows nothing on published pages.
Clock in clock_in
Clock in and out with the running timer for the viewer, optionally with who on the team is on shift now. It needs time tracking enabled in the workspace.
Timesheet timesheet
Tracked hours per day for this week, last week, this month, or the last 7 days — for the viewer or the whole team, with rows per member or per tracked item. It needs time tracking enabled in the workspace.
Repeat repeat
Repeats its child block subtree for each value in fieldKey, with an optional
label. Relation values scope a copy to each related record; other multi-value
fields expose the current value through a synthetic value key. A Repeat can
contain children but cannot contain another Repeat. It needs a collection in
the surrounding dashboard data context; a field key alone does not fetch a
database.
Record embed record_embed
A live card for one database record, stored as databaseId and recordId.
It shows the record’s title, status, assignee and due date as they change and
opens the record on click. Record access rules still apply to every viewer.
App data connector_view
A live table from a connected app — Linear or Jira issues, Stripe invoices, a
Notion database — shown as a table, list, cards or one number. Type /App data, pick the app and table, fill in what to read, then choose columns. It
stores only the setup (action, input, connectionId, display,
columns, limit, title, aggregate); nothing is copied into Snoze. Each
viewer reads the app with their own access, and Save to database copies
the rows shown into a new database when you want them to stay. Private apps
(email) show only to their owner; everyone else sees “Private to its owner”.
Published pages and share links never read an app and show a placeholder.
Nesting and appearance
Paragraph, headings, list items, To-do, Toggle, Quote, Callout, Repeat, Column list, Column, Tabs, Tab, and Dashboard tabs may contain children; a heading holds children as a toggle heading. The structural restrictions described above are validated when blocks are inserted or moved.
Dashboard-capable blocks may store a background, card background and border
colours, border width from 0–4, radius from 0–40, shadow (none, soft,
medium, or bold), and padding (compact, comfortable, or spacious).
Not every block kind opts into those appearance fields.