.dnm Format
The native, portable, enterprise-ready file format for Donum reports. Everything your report will ever need — layout, data schema, permissions, audit log, version history — in one portable file.
On this page
What is .dnm?
.dnm stands for Donum Narrative Manifest. It is the native file format of Donum — analogous to .fig for Figma, .pbix for Power BI, or .sketch for Sketch.
Every report created in Donum can be exported as a .dnm file and imported back — on any account, any workspace, any device — with pixel-perfect fidelity. The format is designed to be lossless, self-contained, and inspectable without proprietary tooling.
File Variants
A single .dnm extension covers three distinct use cases, distinguished by flags inside manifest.json:
Full Report
format_variant: "full"The default. Contains everything: layout, data schema, cached snapshots, design system, version history, audit log, permissions, and assets. Import it anywhere and get a complete report.
Use when: Backup, transfer between workspaces, archive, compliance.
Template
is_template: trueLayout and design system are intact. Live data is stripped and replaced with placeholder values. Variables are defined so recipients can fill in their own data sources on import.
Use when: Agency templates, starter kits, marketplace listings.
Style Patch
is_override_only: trueContains only overrides.json and design-system.json. Apply to an existing report to update its visual style without modifying its content or data.
Use when: Updating a report's visual style independently of its content.
What's Inside
A .dnm file is a structured archive containing your report's layout, theme, data schema, permissions, and history — all in one portable file.
The archive is self-contained and lossless. Everything needed to reconstruct the report — including assets, version history, and access configuration — is included. Credentials are never stored.
Schema Reference
Complete field-by-field reference for every file in the archive. All JSON examples are valid, complete, and copy-pasteable.
manifest.json
The identity card for the archive. Contains metadata, format flags, and an integrity seal.
{
"dnm_version": "2.0.0",
"app_version": "1.0.0",
"format_variant": "full",
"is_template": false,
"is_override_only": false,
"is_enterprise": true,
"report_id": "rpt_4Xk9mN2pQr7vLwE1",
"report_name": "Q1 2026 Investor Update",
"description": "Quarterly update covering MRR, churn, and pipeline metrics.",
"tags": ["investor", "quarterly", "finance"],
"thumbnail": "assets/thumbnail.png",
"created_at": "2026-01-15T09:00:00Z",
"last_modified": "2026-03-15T14:22:00Z",
"author": {
"id": "usr_aR3xB9cD",
"name": "Alex Rivera",
"email": "alex@acmecorp.com"
},
"workspace": {
"id": "ws_prod_01",
"name": "Acme Corp",
"tier": "enterprise"
},
"page_count": 3,
"tile_count": 24,
"has_live_data": true,
"has_user_overrides": false,
"has_version_history": true,
"has_comments": false,
"has_permissions": true,
"has_cadence": true,
"data_sources": ["stripe", "hubspot", "google_analytics"],
"design_system_id": "ds_brand_acme_v3",
"theme_id": "theme_corporate_dark",
"export_formats_used": ["pdf", "dnm"],
"canvas_size": {
"width_px": 1440,
"height_px": 900,
"preset": "widescreen"
},
"checksum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
dnm_version | string | ✓ | — | Format version of this archive. |
format_variant | enum | ✓ | "full" | "full" | "template" | "override_only". Indicates the type of archive. |
is_template | boolean | ✓ | false | Whether this archive is a report template. |
is_override_only | boolean | ✓ | false | Whether this archive is a style patch only. |
is_enterprise | boolean | ✓ | false | Whether this archive contains enterprise-only files. |
report_id | string | ✓ | — | Source report identifier. |
report_name | string | ✓ | — | Report display name. |
description | string | — | — | Optional description. |
tags | string[] | — | [] | Searchable tags. |
thumbnail | string | null | ✓ | — | Path to thumbnail inside assets/. |
page_count | number | ✓ | — | Number of pages in the report. |
tile_count | number | ✓ | — | Total number of tiles. |
has_live_data | boolean | ✓ | — | Whether the report has data connector bindings. |
data_sources | string[] | — | [] | List of connector types used. Never contains credentials. |
design_system_id | string | ✓ | — | ID of the embedded design system. |
canvas_size | object | — | — | Canvas dimensions: width_px, height_px, and optional preset. |
checksum | string | ✓ | — | Integrity seal for tamper detection. |
report.json
The full layout definition. Contains all tabs, tiles, grid positions, data bindings, and display configuration.
{
"id": "rpt_4Xk9mN2pQr7vLwE1",
"name": "Q1 2026 Investor Update",
"tabs": [
{
"id": "tab_overview",
"label": "Overview",
"tiles": [
{
"id": "tile_mrr",
"type": "kpi",
"grid": {
"col_start": 1,
"col_span": 4,
"row_start": 1,
"row_span": 2
},
"data_binding": {
"source": "stripe",
"metric": "mrr",
"aggregation": "sum",
"period": "current_month"
},
"display": {
"label": "Monthly Recurring Revenue",
"format": "currency",
"currency": "USD",
"comparison": "previous_month",
"show_trend": true
}
},
{
"id": "tile_revenue_chart",
"type": "line_chart",
"grid": {
"col_start": 5,
"col_span": 8,
"row_start": 1,
"row_span": 4
},
"data_binding": {
"source": "stripe",
"metric": "revenue",
"aggregation": "sum",
"period": "last_12_months",
"group_by": "month"
},
"display": {
"label": "Revenue Trend",
"x_axis": "month",
"y_axis": "revenue",
"show_legend": true,
"color_scheme": "brand"
}
}
]
}
],
"variables": [],
"global_filters": []
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id | string | ✓ | — | Report ID (matches manifest.report_id). Replaced with new UUID on import. |
name | string | ✓ | — | Report display name. |
tabs | Tab[] | ✓ | — | Ordered list of report pages/tabs. |
tabs[].id | string | ✓ | — | Unique tab identifier. |
tabs[].label | string | ✓ | — | Tab display name. |
tabs[].tiles | Tile[] | ✓ | — | Tiles on this tab. |
tiles[].grid | object | ✓ | — | { col_start, col_span, row_start, row_span } — 1-based grid coordinates. |
tiles[].type | string | ✓ | — | Tile type: kpi | line_chart | bar_chart | table | text | image | progress | gauge | heatmap | … |
tiles[].data_binding | object | — | — | Source connector, metric, aggregation, period, and filters for this tile. |
tiles[].display | object | ✓ | — | Label, format, color scheme, legend, comparison period, and other display options. |
variables | Variable[] | — | [] | Template variables — defined when is_template: true, filled in by the importer. |
global_filters | Filter[] | — | [] | Report-wide filter state applied to all data-bound tiles. |
design-system.json
The complete theme contract. Defines color tokens, the full typography scale, spacing, shadows, and chart color palettes. Every tile derives its visual appearance from this document.
{
"id": "ds_brand_acme_v3",
"version": "3.0.0",
"colors": {
"primary": "#dc2e3e",
"secondary": "#1a1a2e",
"accent": "#e94560",
"background": "#0f0f1a",
"surface": "#1a1a2e",
"text_primary": "#ffffff",
"text_secondary": "#a0aec0",
"text_muted": "#4a5568",
"border": "#2d3748",
"success": "#48bb78",
"warning": "#f6ad55",
"danger": "#fc8181",
"chart_palette": [
"#dc2e3e", "#3182ce", "#38a169",
"#d69e2e", "#805ad5", "#dd6b20"
]
},
"typography": {
"heading_font": "Syne",
"body_font": "Space Grotesk",
"mono_font": "JetBrains Mono",
"scale": {
"h1": { "size": 36, "weight": 700, "line_height": 1.2, "letter_spacing": -0.02 },
"h2": { "size": 28, "weight": 700, "line_height": 1.3, "letter_spacing": -0.01 },
"h3": { "size": 22, "weight": 600, "line_height": 1.4, "letter_spacing": 0 },
"body": { "size": 15, "weight": 400, "line_height": 1.6, "letter_spacing": 0 },
"small": { "size": 12, "weight": 400, "line_height": 1.5, "letter_spacing": 0 },
"label": { "size": 11, "weight": 600, "line_height": 1.4, "letter_spacing": 0.05 }
}
},
"spacing": {
"tile_gap": 12,
"tile_padding": 20,
"border_radius": 8
},
"shadows": {
"tile": "0 1px 3px rgba(0,0,0,0.2), 0 1px 2px rgba(0,0,0,0.12)",
"card": "0 4px 6px rgba(0,0,0,0.15)"
}
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
id | string | ✓ | — | Unique design system identifier. Referenced in manifest.design_system_id. |
version | string | ✓ | — | Semver version of this design system snapshot. |
colors | object | ✓ | — | All color tokens: primary, secondary, accent, background, surface, text variants, border, success, warning, danger, and chart_palette array. |
colors.chart_palette | string[] | ✓ | — | Ordered list of hex colors cycled across data series in charts. |
typography | object | ✓ | — | Font family names and the full type scale. |
typography.heading_font | string | ✓ | — | Font family for all heading tiles. Must be available in assets/ if custom. |
typography.body_font | string | ✓ | — | Font family for body text and KPI labels. |
typography.mono_font | string | ✓ | — | Monospace font for code and data table cells. |
typography.scale | object | ✓ | — | Named text styles: h1, h2, h3, body, small, label. Each has size (px), weight, line_height, letter_spacing. |
spacing | object | ✓ | — | tile_gap (px between tiles), tile_padding (inner tile padding), border_radius. |
shadows | object | — | — | CSS box-shadow strings for tile and card elevations. |
overrides.json
User-applied style customizations layered on top of the base design system. Only changed values are stored — unchanged tokens remain at their design-system defaults. Present only when the report owner has applied overrides.
{
"version": "1.0.0",
"applied_at": "2026-03-10T11:30:00Z",
"applied_by": "usr_aR3xB9cD",
"overrides": {
"colors": {
"primary": "#c41e2e",
"accent": "#e83250"
},
"typography": {
"heading_font": "Playfair Display",
"body_font": "Libre Baskerville"
},
"tile_overrides": [
{
"tile_id": "tile_mrr",
"display": {
"label": "MRR (Board View)"
}
}
]
},
"base_design_system_id": "ds_brand_acme_v3",
"base_design_system_version": "3.0.0"
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
version | string | ✓ | — | Overrides schema version. |
applied_at | string | ✓ | — | ISO 8601 timestamp when overrides were last applied. |
applied_by | string | ✓ | — | User ID who applied the overrides. |
overrides.colors | object | — | — | Partial color token overrides. Keys match tokens in design-system.json. |
overrides.typography | object | — | — | Font family overrides. Only heading_font and body_font are currently supported. |
overrides.tile_overrides | object[] | — | — | Per-tile overrides identified by tile_id. Only the changed display fields are stored. |
base_design_system_id | string | ✓ | — | ID of the design system these overrides are based on. Mismatch triggers a warning on import. |
permissions.json
Viewer access control and row-level security (RLS) configuration. Present only when access restrictions are configured on the report.
{
"version": "1.0.0",
"default_access": "none",
"require_authentication": true,
"expiry_date": null,
"allowed_domains": ["acmecorp.com", "investor.acmecorp.com"],
"viewers": [
{
"identity_ref": "usr_investor_001",
"role": "viewer",
"rls_filters": [
{
"table": "revenue_events",
"column": "region",
"operator": "eq",
"value": "us-west"
}
]
},
{
"identity_ref": "group:board_members",
"role": "viewer",
"rls_filters": []
}
],
"rls": {
"enabled": true
}
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
default_access | enum | ✓ | "none" | Default access level for unauthenticated or unlisted viewers. |
require_authentication | boolean | ✓ | — | Whether viewers must authenticate before accessing the report. |
expiry_date | string | null | — | — | Date after which the published link becomes inactive. |
allowed_domains | string[] | — | [] | Email domain allowlist for viewer access. |
viewers | Viewer[] | — | — | Explicit viewer access list. |
cadence.json
Defines the recurring delivery schedule for this report. Present when a cadence has been configured.
{
"enabled": true,
"frequency": "monthly",
"schedule": {
"day_of_month": 1,
"hour_utc": 8,
"timezone": "America/New_York"
},
"recipients": [
{
"type": "email",
"address": "board@acmecorp.com",
"format": "pdf",
"personalized": false
},
{
"type": "workspace_recipient",
"recipient_id": "recip_board_group",
"format": "live_link",
"personalized": true
}
],
"next_run": "2026-04-01T08:00:00Z"
}| Field | Type | Required | Default | Description |
|---|---|---|---|---|
enabled | boolean | ✓ | — | Whether recurring delivery is active. |
frequency | enum | ✓ | — | Delivery frequency. |
schedule | object | ✓ | — | Delivery timing configuration. |
recipients | Recipient[] | ✓ | — | List of delivery destinations. |
Import & Export Guide
Exporting a .dnm
Export any Donum report from the report editor (⋯ menu → Export → .dnm) or via the API.
GET /api/v1/reports/{report_id}/export?format=dnm
&include_history=true
&embed_assets=true
&include_comments=false
# Response headers:
Content-Type: application/octet-stream
Content-Disposition: attachment; filename="q1-report.dnm"Importing a .dnm
Import via the dashboard (Reports → Import → Upload .dnm) or via the API.
{
"report_id": "rpt_newId123",
"name": "Q1 2026 Investor Update",
"warnings": [
"2 connection(s) set to disconnected. Re-authenticate in workspace settings."
],
"created_at": "2026-03-15T15:01:33Z"
}Security Model
The .dnm format is designed so that credentials are never written into the archive, regardless of what connectors the report uses.
| Concern | Approach |
|---|---|
| Credentials | Never embedded. Connector credentials are stored in the workspace and resolved at runtime — not in the file. |
| Tamper detection | Layered integrity checks across all internal files and the archive as a whole. Mismatch shows a warning on import. |
| Encryption | Optional at-rest encryption on export (enterprise plan). File is unreadable without the workspace decryption key. |
| Expiry | expiry_date in permissions.json makes the published link read-only after the specified date. |
| Domain restriction | allowed_domains in permissions.json limits who can view the published report by email domain. |
| Row-level security | Data filtered per viewer at query time. Configured in permissions.json. |
| Audit trail | Significant actions are logged with full timestamps. Audit history is exportable for compliance reporting. |
| Credential scan | Files are scanned for credential-like content on import. Import is rejected if any are found. |
Incremental Refresh
Incremental refresh allows reports connected to large datasets to refresh efficiently by limiting how much data is queried on each cycle. The policy is configured in data/refresh-policy.json and is available on enterprise plans.
Versioning
.dnm files include version history, allowing any prior state of the report to be restored. Version snapshots are stored inside the archive and are optional — you can choose to include or exclude them on export.
.dnm at Scale
In enterprise deployments with 100+ reports, the .dnm format integrates into existing data pipelines and governance workflows without requiring custom tooling.
One file, multiple viewers
A single published .dnm can serve personalized data to different viewers via RLS — no separate files needed per viewer.
Publish / Draft separation
Reports have independent draft and published states. Changes are never exposed to viewers until explicitly published.
Audit compliance
Full audit history is included in the archive and exportable for compliance reporting. Chain of custody is preserved across workspaces.
API-first
Import, export, and refresh operations are all available via REST API, enabling automated report workflows.
Portable
Reports can be transferred between accounts, workspaces, and devices with full fidelity. No proprietary lock-in.
Bulk operations
Import and export large numbers of reports via API. Use templates to standardize report structure across your organization.
Format Changelog
Changes to the .dnm format schema. Application release notes are on the Changelog page.
| Version | Date | Changes |
|---|---|---|
2.0.0 | Mar 2026 | Added refresh-policy.json, permissions.json with RLS, audit-log.json, publish/draft model, two-layer tamper detection (package_hash + manifest seal), credential contamination scan on import. |
1.1.0 | Feb 2026 | Added overrides.json for user style customization, cadence.json for recurring delivery, typography contract in design-system.json (scale object with named text styles). |
1.0.0 | Jan 2026 | Initial release. Core layout (report.json), design system, version history, binary asset embedding, checksum.json (per-file SHA-256). |
Was this page helpful?