Report definitions
A report definition is the design of a report: its sections, language variants and branding. Two kinds share one list, told apart by owner: Aleta's standard catalog (owner: "aleta"), read-only and the same for every firm, and your firm's own definitions (owner: "tenant"), which you create, change and archive here. Reads need reports:read and the reports module at read; writes need reports:write and an operator seat (owner, admin, advisor) or a group with the reports module at read_write. Every write takes ?dry_run=true and an Idempotency-Key header and is logged in the change history.
You see your firm's definitions of the clients and lenses you see; one with neither a client nor a lens is firm-wide. An Aleta definition is copied before it is used: create your own with copy_from.
The report definition object
idstringStable identifier for the definition. A UUID — treat it as opaque.
ownerstringaleta(Aleta's standard catalog, read-only) ortenant(your firm's own).namestring or nullThe definition's name.
nullfor a definition from the legacy platform that had none.kindstring or nullThe report family. Your own definitions only.
formatstring or nullpdforcsv. Aleta definitions only: your own render to the format a subscription or report run asks for.category, description, codestring or nullAleta definitions only: the catalog's category and description, and the legacy report code (
M10A,D1B, …) where one exists.languages, default_languagearray of string, string or nullThe languages the document declares and its default.
client_id, lens_idstring or nullThe client or lens the definition belongs to; both
nullfor a firm-wide one.statusstringpublished(Aleta),activeorarchived(your own).revisionstringYour own: the revision a
PATCHchecks withexpected_revision. Aleta's: the published version. A decimal string.originstringlegacyfor a definition mirrored from the legacy platform,v1for every other, also the ones made in the web app. Alegacydefinition is read-only until your firm has moved (409 legacy_managed).updated_atstringISO 8601 in UTC, with microseconds.
archived_at, archived_by, archive_reasonstring or nullSet while the definition is archived;
nullotherwise and on Aleta's.definitionobjectThe document itself. Only on Get a definition. It is the report builder's own format and goes back unchanged in
POSTandPATCH; alegacydefinition shows the legacy platform's fixed report columns in snake_case.
List definitions
Returns Aleta's catalog first, then your own definitions, in the standard v1 list envelope. A filter on kind, client_id or lens_id lists your own only. An unknown owner or kind, or any parameter not listed here, is a 400.
Query parameters
ownerstringaletaortenant; both when absent.kindstringOnly your definitions of this kind.
client_idstringOnly your definitions of this client.
lens_idstringOnly your definitions of this lens.
include_archivedbooleanAlso your archived definitions. Defaults to
false.limitintegerPage size. Defaults to 100, capped at 1 000.
cursorstringOpaque cursor from the previous page's
next_cursor. Omit for the first page.
curl -G https://api.aleta.ai/v1/report-definitions \
-H "Authorization: Bearer {access_token}" \
-d owner=tenant
{
"data": [
{
"id": "0190f5e0-4444-7aaa-8bbb-0123456789ab",
"owner": "tenant",
"name": "Quarterly pack",
"kind": "custom",
"format": null,
"category": null,
"description": null,
"code": null,
"languages": ["da", "en"],
"default_language": "da",
"client_id": "0190f5e0-1111-7aaa-8bbb-0123456789ab",
"lens_id": null,
"status": "active",
"revision": "3",
"origin": "v1",
"updated_at": "2026-10-01T08:15:02.123456Z",
"archived_at": null,
"archived_by": null,
"archive_reason": null
}
],
"next_cursor": null,
"limit": 100
}
Get a definition
Returns one definition with its definition document, also an archived one. A definition you do not see, or an id that is not a UUID, is a 404.
curl https://api.aleta.ai/v1/report-definitions/0190f5e0-4444-7aaa-8bbb-0123456789ab \
-H "Authorization: Bearer {access_token}"
Create a definition
Creates one of your own definitions and answers 201 with it. Send exactly one of definition and copy_from.
A definition created here covers the year to date, as a new report in the report builder does; a copy of one of your own definitions covers the period that one covers. Another period is chosen in the report builder.
Body
namestringRequired unless
copy_fromnames a definition with a name.kindstringThe report family:
quarterly,monthly,annual,custom,mifid_ex_ante,mifid_ex_post,accounting,tax,transaction_register,holdings_snapshot,performance,factsheetorother. The copied definition's, orcustom, when absent.client_id, lens_idstringThe client or lens it belongs to. Leave both out for a firm-wide definition.
definitionobjectA report builder document.
copy_fromstringAn Aleta or own definition to copy. A definition mirrored from the legacy platform cannot be copied: its columns are not a builder document.
Every refusal is a 400 with the reason: an unknown field, both or neither of definition and copy_from, an empty name, an unknown kind, a document the builder cannot read, a copy_from that is not found or is a legacy definition, or a client or lens you do not see.
curl -X POST https://api.aleta.ai/v1/report-definitions \
-H "Authorization: Bearer {access_token}" \
-H "Idempotency-Key: copy-m10a" \
-H "Content-Type: application/json" \
-d '{"copy_from": "0190f5e0-5555-7aaa-8bbb-0123456789ab", "client_id": "0190f5e0-1111-7aaa-8bbb-0123456789ab"}'
Update a definition
Changes one of your own definitions and answers 200 with it. Fields left out are kept; null clears client_id or lens_id.
Body
name, kind, definitionstring, string, objectAs in Create a definition.
client_id, lens_idstring or nullThe new client or lens. Leaving the definition with neither (firm-wide) is for an admin or Aleta only:
403otherwise.expected_revisionstringThe
revisionyou read. A definition changed since is a409with coderevision_mismatch; read it again.statusstringactivebrings back an archived definition.archivedis a400: archive with DELETE.
Refusals, in this order: 400 for an unknown field or an invalid value; 404 for a definition you do not see; 409 read_only for an Aleta definition, with next_action copy (POST /v1/report-definitions with copy_from); 403 for a change that makes it firm-wide; 409 legacy_managed for a legacy definition before your firm has moved; 400 for a client or lens you do not see; 409 in_use for an archived definition without status: active, with next_action restore (this PATCH with status).
curl -X PATCH https://api.aleta.ai/v1/report-definitions/0190f5e0-4444-7aaa-8bbb-0123456789ab \
-H "Authorization: Bearer {access_token}" \
-H "Content-Type: application/json" \
-d '{"name": "Quarterly pack (2026)", "expected_revision": "3"}'
Archive a definition
Archives one of your own definitions: it is never deleted, stays readable with status: archived, and is no longer rendered. Answers 204, also when it is archived already. ?reason= is kept as archive_reason. Any query parameter other than reason and dry_run is a 400.
A definition an active report subscription renders is a 409 in_use. Its next_action names one of those subscriptions you can see: pause (PATCH /v1/report-subscriptions/{id} with status), or ask_aleta when Aleta set the subscription up. An Aleta definition is a 409 read_only, a legacy definition before your firm has moved a 409 legacy_managed.
curl -X DELETE "https://api.aleta.ai/v1/report-definitions/0190f5e0-4444-7aaa-8bbb-0123456789ab?reason=replaced" \
-H "Authorization: Bearer {access_token}"