report_definitions.publish
What it does
Publish an immutable custom report definition, or a new version by id. Queries must be books-only read-only SQL. A version 1 report binds fixed values; a version 2 report declares the parameters a viewer may set, within bounds.
Before you send it
An authorized OAuth connection may call it, including a headless client. Effective membership, application grant and token permissions still apply. Describe report_definitions.publish through GET /v1/catalog/commands/{name} before acting.
This command does not accept source_document_id in its envelope. Any input evidence requirements remain as documented below.
Inputs
Put these fields inside the envelope’s input object. The outer envelope names the command, a stable idempotency_key and effective_at; request and recovery rules explain those separately. Use exact minor-unit integer strings for monetary fields. Take existing IDs from prior reads or command results; choose a new identity only where the command asks for one.
Required means required within its containing object; an optional parent can be omitted.
| Field | Type | Required | Meaning and accepted values |
|---|---|---|---|
id | string | No | Pattern: "^rpt_[0-9A-HJKMNP-TV-Z]{26}$". |
definition | object | Yes | economico.report/1 has query and text blocks, and a query binds fixed params to ? in order. economico.report/2 adds parameters (bound by name, :month), layout, chart blocks, and width and caption on any block; its queries take no params. |
definition.spec | string | Yes | Choose "economico.report/1", "economico.report/2". Example: "economico.report/1". |
definition.report_schema | number | Yes | Must be 1. Example: 1. |
definition.title | string | Yes | Example: "Example". |
definition.description | string | No | |
definition.layout | string | No | Version 2. Default grid. Choose "grid", "document". |
definition.parameters | array | No | Version 2, in the order shown. A query binds :name; a month also gives :name_start, :name_end and :name_next, a date_range :name_from and :name_to. Every parameter has a default, so the report runs with nothing chosen. Items: object. Maximum items: 8. |
definition.parameters[].name | string | Yes | Pattern: "^[a-z][a-z0-9_]{0,31}$". |
definition.parameters[].type | string | Yes | Choose "month", "date", "date_range", "choice", "integer". |
definition.parameters[].label | string | Yes | |
definition.parameters[].default | schema-defined | Yes | month: last_complete_month, this_month or YYYY-MM. date: today or YYYY-MM-DD. date_range: last_12_months, year_to_date, last_complete_month or {from, to}. choice: one of its option values. integer: a whole number from min to max. |
definition.parameters[].options | array | No | choice only. Items: object. Maximum items: 50. |
definition.parameters[].options[].value | string | Yes | |
definition.parameters[].options[].label | string | Yes | |
definition.parameters[].min | integer | No | integer only. |
definition.parameters[].max | integer | No | integer only. |
definition.blocks | array | Yes | Minimum items: 1. Maximum items: 12. |
After acceptance
When the command emits events, its documented effects and receipt are recorded in the command transaction. The response returns commandId, replayed, the command-specific result below and emitted events with their IDs and CIDs. A command is not automatically a cash movement or revenue recognition: use the behavior above to determine what this command records.
Inspect result and the affected records or reports before continuing. Save returned identifiers for later calls. Fetch GET /v1/commands/{id} with commandId to recover the accepted receipt; retry the same intent with the same idempotency key if the response was lost. Some commands can succeed with events: [] and return a transient result and commandId without persisting a receipt. A lookup of that ID can return null; retain the returned result and verify the affected record. Retrying can re-evaluate the current state rather than replay a stored result. A domain no_change is a separate success outcome with no persisted receipt.
Result fields
Required means required within its containing object; an optional parent can be omitted.
| Field | Type | Required | Meaning and accepted values |
|---|---|---|---|
id | string | Yes | Pattern: "^rpt_[0-9A-HJKMNP-TV-Z]{26}$". |
version | integer | Yes | Minimum: 1. |
reportSchema | integer | Yes | Minimum: 1. |
title | string | Yes | |
description | string or null | Yes | |
documentId | string | Yes | |
cid | string | Yes | |
status | string | Yes | Choose "published", "archived". |
All commands · Operation and errors · Reusable schemas
Keep credentials out of prompts; rehearse writes only in a disposable sandbox.
Exact request schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"type": "object",
"properties": {
"name": {
"const": "report_definitions.publish"
},
"input": {
"type": "object",
"properties": {
"id": {
"type": "string",
"pattern": "^rpt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"definition": {
"type": "object",
"description": "economico.report/1 has query and text blocks, and a query binds fixed params to ? in order. economico.report/2 adds parameters (bound by name, :month), layout, chart blocks, and width and caption on any block; its queries take no params.",
"properties": {
"spec": {
"enum": [
"economico.report/1",
"economico.report/2"
]
},
"report_schema": {
"const": 1
},
"title": {
"type": "string"
},
"description": {
"type": "string"
},
"layout": {
"enum": [
"grid",
"document"
],
"description": "Version 2. Default grid."
},
"parameters": {
"type": "array",
"maxItems": 8,
"description": "Version 2, in the order shown. A query binds :name; a month also gives :name_start, :name_end and :name_next, a date_range :name_from and :name_to. Every parameter has a default, so the report runs with nothing chosen.",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"pattern": "^[a-z][a-z0-9_]{0,31}$"
},
"type": {
"enum": [
"month",
"date",
"date_range",
"choice",
"integer"
]
},
"label": {
"type": "string"
},
"default": {
"description": "month: last_complete_month, this_month or YYYY-MM. date: today or YYYY-MM-DD. date_range: last_12_months, year_to_date, last_complete_month or {from, to}. choice: one of its option values. integer: a whole number from min to max."
},
"options": {
"type": "array",
"description": "choice only.",
"maxItems": 50,
"items": {
"type": "object",
"properties": {
"value": {
"type": "string"
},
"label": {
"type": "string"
}
},
"required": [
"value",
"label"
],
"additionalProperties": false
}
},
"min": {
"type": "integer",
"description": "integer only."
},
"max": {
"type": "integer",
"description": "integer only."
}
},
"required": [
"name",
"type",
"label",
"default"
],
"additionalProperties": false
}
},
"blocks": {
"type": "array",
"minItems": 1,
"maxItems": 12,
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"type": {
"const": "query"
},
"title": {
"type": "string"
},
"sql": {
"type": "string"
},
"params": {
"type": "array",
"description": "Version 1 only. Fixed bindings: text, safe integers or null. Fractions belong in SQL, or bind decimal text and CAST it.",
"items": {
"anyOf": [
{
"type": "string"
},
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{
"type": "null"
}
]
}
},
"width": {
"enum": [
"full",
"half",
"third"
],
"description": "Version 2. Default full."
},
"caption": {
"type": "string",
"description": "One line under the block, e.g. booked or recognised."
}
},
"required": [
"type",
"title",
"sql"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"type": {
"const": "text"
},
"markdown": {
"type": "string"
},
"width": {
"enum": [
"full",
"half",
"third"
],
"description": "Version 2. Default full."
},
"caption": {
"type": "string",
"description": "One line under the block, e.g. booked or recognised."
}
},
"required": [
"type",
"markdown"
],
"additionalProperties": false
},
{
"type": "object",
"description": "Version 2. Draws the query's rows: x along the bottom (months, dates or names), y one column for a bar chart or a list of up to four for a line chart. Money y columns (*_minor) need currency selected beside them and draw one chart per currency.",
"properties": {
"type": {
"const": "chart"
},
"title": {
"type": "string"
},
"sql": {
"type": "string"
},
"mark": {
"enum": [
"bar",
"line"
]
},
"x": {
"type": "string"
},
"y": {
"anyOf": [
{
"type": "string"
},
{
"type": "array",
"items": {
"type": "string"
},
"minItems": 1,
"maxItems": 4
}
]
},
"width": {
"enum": [
"full",
"half",
"third"
],
"description": "Version 2. Default full."
},
"caption": {
"type": "string",
"description": "One line under the block, e.g. booked or recognised."
}
},
"required": [
"type",
"title",
"sql",
"mark",
"x",
"y"
],
"additionalProperties": false
}
]
}
}
},
"required": [
"spec",
"report_schema",
"title",
"blocks"
],
"additionalProperties": false
}
},
"required": [
"definition"
],
"additionalProperties": false
},
"idempotency_key": {
"type": "string",
"minLength": 1,
"maxLength": 256
},
"effective_at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z))$"
}
},
"required": [
"name",
"input",
"idempotency_key",
"effective_at"
],
"additionalProperties": false
}Accepted command receipt
{
"type": "object",
"required": [
"commandId",
"replayed",
"result",
"events"
],
"properties": {
"commandId": {
"type": "string"
},
"replayed": {
"type": "boolean"
},
"imported": {
"const": true,
"description": "The command's events are history from before the business joined Economico, recorded as an import: free of monthly events."
},
"result": {
"type": "object",
"additionalProperties": false,
"properties": {
"id": {
"type": "string",
"pattern": "^rpt_[0-9A-HJKMNP-TV-Z]{26}$"
},
"version": {
"type": "integer",
"minimum": 1
},
"reportSchema": {
"type": "integer",
"minimum": 1
},
"title": {
"type": "string"
},
"description": {
"type": [
"string",
"null"
]
},
"documentId": {
"type": "string"
},
"cid": {
"type": "string"
},
"status": {
"enum": [
"published",
"archived"
]
}
},
"required": [
"id",
"version",
"reportSchema",
"title",
"description",
"documentId",
"cid",
"status"
]
},
"events": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "integer"
},
"cid": {
"type": "string"
}
}
}
}
}
}Example request
{
"name": "report_definitions.publish",
"input": {
"definition": {
"spec": "economico.report/1",
"report_schema": 1,
"title": "Example",
"blocks": [
{
"type": "query",
"title": "Parties",
"sql": "SELECT name FROM parties LIMIT 10"
}
]
}
},
"effective_at": "2026-09-01T00:00:00Z",
"idempotency_key": "report_definitions.publish-example-0"
}