Reports

Create a report from a composition

Writes a report (or one of the account's own templates) out of a composition: sections copied from the published catalog and/or sections written from scratch whose widgets are given as DSL, bound to the account's connections through data_sources. Follow the discovery chain first: /v1/connections for the bindings, /v1/fields and /v1/integrations/detail for the field ids and data views of every widget, /v1/capabilities for the ceilings and the presets. A section is either catalog -- a section of a published entry, named by its slug and its 0-based position -- or custom, whose widgets are written as DSL. This is NOT the vocabulary of the AI assistant of the app: nothing here is natural language. Every property of the dsl schema is required, unfulfilled included: send null in the optional ones and an empty array in unfulfilled. That field belongs to the AI generator, which lists there what it could not express; a client writing the DSL itself sends an empty array. The data_view of a dsl takes its values from /v1/capabilities (the integrations block), which is not always the data_views list of /v1/integrations/detail: an integration that reads a single level when it is queried can still be drawn at several levels in a report. A refusal names the accepted values in the problem's suggestions. A widget of a custom section whose dsl has visualization: text is a block of prose: it reads no data, so it carries no integration_id, the empty value of every data key and its Markdown in content. Every section, catalog or custom, carries add_summary and show_previous_period, both required and both usually null: add_summary writes an AI summary of that section -- it does not count against the widgets of the section and it spends AI credits of the account when the report is opened, viewed or delivered by a schedule, never when it is written -- and show_previous_period makes its header name the period it is compared against. The add_summary at the root of the body is another thing -- the summary of the WHOLE report -- and it spends AI credits of the account and is off by default. A section summary that cannot be written comes back as a SUMMARY_SECTION_SKIPPED warning with the path of the section, and the rest of the report is written. This endpoint never asks for a confirmation and does not accept if_version. Refusals: 400 VALIDATION_FAILED, whose details.problems name what is wrong with each field -- a catalog slug or position that is not published (TEMPLATE_NOT_FOUND), a parameterized entry used as a section (TEMPLATE_PARAMETERIZED), an integration a section reads from with no data source (MISSING_REQUIRED_FIELD), two entries naming the same integration (ONE_CONNECTION_PER_INTEGRATION), a dsl that does not validate (DSL_INVALID and the codes of the widget DSL) -- or 400 UNKNOWN_PARAM; 403 WRITE_ACCESS_DISABLED when write access is off and PLAN_LIMIT_REACHED when the plan has no room for another report; 404 TEMPLATE_NOT_FOUND only when a catalog section stops being published between the validation and the write; 409 for the idempotency conflicts.

Every write endpoint reads dry_run and idempotency_key; see the Write guarantees section of the introduction.

post/reports/create

Request

  • Base URL: https://api.reportingninja.com/v1
  • URL: https://api.reportingninja.com/v1/reports/create
  • Auth: HTTP bearer

Request body

namestring required

The title of the report, 1 to 60 characters: the name the cover paints. It is what /v1/reports/get answers as name.

internal_namestring

The name the list of the application shows, 1 to 100 characters. Left out, it is the title.

type'report' | 'template'

What to create. Default report.

language'en' | 'es'

Language of the report's own literals. Defaults to the account owner's.

dry_runboolean

Validate and answer what WOULD happen, without writing anything. Default false.

idempotency_keystring

Makes a retry safe: the answer of the first call is replayed for 24 hours to any later call with the same key and the same body.

Response

The call succeeded. This endpoint reports its errors with a real HTTP status, so a 200 always carries status=ok.

status'ok' required

Changes

No recorded changes to this operation across all 1 revision of this API.