Skip to main content
Version: 2.x (upcoming)

Reports

The report endpoints aggregate the answers stored in plans and assets: how many items answered a question, what they said, and how that splits by status, blueprint, period, tenant, or another answer. They back the Answers admin page and can be called directly for dashboards or scheduled extracts.

All endpoints live under api/report and require the x-tenant header described in Addressing an organisation.

Scope and permissions​

Every endpoint works in one of two scopes:

ScopeHow to ask for itReadsPermissions
Tenant (default)installationWide omitted or falseThe plans, assets, templates, and blueprints of the tenant in the x-tenant header. Rows of other tenants, including the default tenant's, are excluded.BrowseReport; ExportReport for the CSV
InstallationinstallationWide: true (a query parameter on the outline endpoints)Every tenant of the installation.BrowseInstallationReport; ExportInstallationReport for the CSV

By default BrowseReport and ExportReport are granted to the Admin, InstallationAdmin, and TenantAdmin roles, and the two installation permissions to Admin and InstallationAdmin. Reports are tenant-wide: the caller's own plan memberships do not narrow them.

Addressing a question​

A report reads one or more questions. A question is addressed in one of two ways:

FormFieldsReads
By fieldsetfieldSetId, fieldIdsThe named fields of one fieldset, in every version of one template or blueprint lineage, deleted versions included (descriptionTemplateGroupId / planBlueprintGroupId required). Field ids are stable across versions.
By semanticsemanticEvery field tagged with that semantic (case- and whitespace-insensitive), in every version in scope. When all questions are semantic the group id may be omitted, and every lineage in scope that carries the semantic is read.

Ids and numbering come from the outline or search endpoints below; never guess them.

Endpoints​

Search questions​

POST api/report/questions/search

{ "like": "repositor", "subject": 0, "limit": 20, "installationWide": false, "includeSources": false }

subject is optional (0 = assets, 1 = plans; both when omitted). The search matches question numbering (prefix), fieldset title and description, and field labels, in the current version of each lineage. It also matches the names of semantics and the titles of the questions carrying them. limit defaults to 30.

{
"questions": [
{
"subject": 0,
"groupId": "7ae1c3d3-91a9-4315-9aec-b0f173010f2a",
"groupLabel": "FCT",
"tenantCode": null,
"versionCount": 2,
"fieldSetId": "8f1c…",
"numbering": "5.2.4",
"title": "In which repository will the data be deposited?",
"hasMultiplicity": false,
"fields": [ { "id": "a1…", "label": "Repository", "fieldType": "referenceTypes", "controlsOtherFields": false, "semantics": ["rda.dataset.distribution.host.title"] } ],
"allFields": [ "…the fields above plus any control fields…" ]
}
],
"semantics": [
{
"subject": 0,
"semantic": "rda.dataset.distribution.host.title",
"label": "Repository",
"titles": ["Repository", "In which repository will the data be deposited?"],
"groupCount": 4,
"groupLabels": ["FCT", "Horizon Europe DMP", "…"],
"fieldTypes": ["referenceTypes", "freetext"]
}
],
"sources": null
}

A semantic's identity is the tag string itself, compared case- and whitespace-insensitively (RDA.Dataset.Type and rda.dataset.type are one question). label is the fieldset title most templates give it and titles every distinct wording, most common first. A long list hints at loose tagging.

fields are the fields counted by default. When a fieldset holds a yes/no field (fieldType booleanDecision), the yes/no fields are the question and are the only fields listed. Otherwise a tick box whose only role is to reveal a sibling (controlsOtherFields: true on a checkBox field) is left out. allFields has every field. With an empty like the response lists only the semantics in use, ordered by how many lineages share them. limit caps the question hits and the semantic hits separately.

On an installation-wide search, tenantCode on each question hit names the tenant that owns the lineage; it is null otherwise.

With includeSources: true the response also carries sources: the template and blueprint lineages whose name contains like (all of them when like is empty), ordered by name and then tenant, and capped by limit. The admin page uses it to browse the lineages of every tenant, which the template and blueprint listings do not offer.

"sources": [
{ "subject": 0, "groupId": "7ae1c3d3-…", "label": "FCT", "tenantCode": "fct", "versionCount": 2 }
]

Outline of a lineage​

GET api/report/outline/description-template/{groupId} GET api/report/outline/plan-blueprint/{groupId}

The numbered question tree of the newest version of the lineage: sections, fieldsets and fields with ids, numbering as the template editor shows it (5.2.4), titles, field types and semantics. Blueprint outlines leave out system fields (title, description, language, contact, access rights), which are already available as filters and export columns.

Add ?installationWide=true to look up a lineage of another tenant; it requires BrowseInstallationReport.

Run a report​

POST api/report/query

{
"subject": 0,
"descriptionTemplateGroupId": "7ae1c3d3-91a9-4315-9aec-b0f173010f2a",
"questions": [
{ "fieldSetId": "8f1c…", "fieldIds": ["a1…", "b2…"], "label": "5.2.4 Repository" }
],
"groupBy": [ { "type": 0 } ],
"descriptionSubQuery": { "statusIds": ["…"] },
"planSubQuery": { "planReferenceSubQuery": { "referenceIds": ["…"], "isActive": [1] } },
"latestVersionOnly": true,
"includeInactive": false,
"dateBucket": 0,
"textTopN": 20,
"installationWide": false
}
FieldMeaning
subject0 counts assets (descriptions), 1 counts plans.
descriptionTemplateGroupId, planBlueprintGroupIdThe lineage read. On an asset report, planBlueprintGroupId also narrows to plans built from that blueprint and enables planQuestions.
questionsOne to ten questions, keyed q0, q1, … in request order.
planQuestionsAsset reports only: questions of the parent plan's blueprint, keyed p0, p1, …, available as PlanQuestion breakdowns and as CSV columns.
groupByUp to three dimensions. type is a ReportDimensionType: 0 asset status, 1 plan status, 2 plan access, 3 plan blueprint, 4 plan version status, 5 template version, 6 created period, 7 finalized period, 8 answer to questionKey, 9 plan answer to questionKey, 10 tenant (installation-wide reports only).
descriptionSubQuery, planSubQueryThe asset and plan listing lookups, so anything the listings can filter by applies here. Paging and ordering are ignored.
latestVersionOnlyCount each plan lineage once, by its newest version (default true). The newest version is chosen over the whole lineage before the filters apply, so a status filter that excludes a newer draft drops the plan instead of falling back to its older finalized version.
includeInactiveInclude deleted items (default false).
dateBucketGranularity of date answers and date dimensions: 0 year, 1 month.
textTopNDistinct free-text answers listed before the rest fold into Other text (n).
installationWideCount across every tenant (default false). Requires BrowseInstallationReport, or ExportInstallationReport for the CSV.

The response:

{
"subject": 0,
"sourceGroupId": "7ae1c3d3-…",
"sourceLabel": "FCT",
"sourceVersionCount": 2,
"sourceSpansAllGroups": false,
"subjects": 72,
"distinctPlans": 34,
"dimensions": [ { "type": 0, "label": "Asset status" } ],
"questions": [
{
"key": "q0",
"label": "5.2.4 Repository",
"numbering": "5.2.4",
"fieldType": "referenceTypes",
"multiValue": true,
"states": { "answered": 38, "notAnswered": 34, "notApplicable": 0, "notMigrated": 0 },
"distribution": [ { "value": "POLEN DataHub", "count": 25, "percentOfAnswered": 65.8 } ],
"numberSummary": null
}
],
"crossTab": [
{
"dimensionValues": ["Finalized"],
"subjects": 31,
"distinctPlans": 14,
"questions": [ { "key": "q0", "states": { "…": 0 }, "distribution": [ "…" ] } ]
}
]
}

Answer states are per question, because two questions of the same request can disagree about whether an item answered:

StateMeaning
answeredThe question was visible to the author and a value was given.
notAnsweredVisible and left empty.
notApplicableHidden by a visibility rule for that item, or absent from the version the item was written against. Visibility is re-evaluated per item from the stored answers, because hidden fields are persisted empty.
notMigratedThe item still holds answers in the pre-2.0 shape (planBlueprintValues) and could not be read. Normally 0: the database migrations that run when the API service starts convert pre-2.0 plan values (see the upgrade guide).

Values are counted by label: reference, tag and internal-entry ids are resolved in one batch per type; select and radio options report their option label; booleans report Yes/No; uploads and external identifiers report Provided; dates report their bucket; numbers report the value and feed numberSummary. Rich-text values are stripped of markup and HTML entities are decoded. Values of one question that differ only in case or whitespace are merged under the spelling most items used, in the distribution, the cross tab, and the CSV alike. A Tenant dimension reports tenant codes, with the default tenant under its configured code.

Export CSV​

POST api/report/export/csv

Same body as query. Returns answers_<date>.csv, UTF-8 with a byte order mark, one row per item: on an installation-wide export a Tenant column first, then plan id, plan, plan version, plan status, plan access, plan version status, then asset id, asset, asset status and template version (asset reports) or blueprint version (plan reports), created, finalized, and for each question a value column and a — state column. Plan questions follow, prefixed Plan: . Across lineages, version columns carry the template name (FCT v2).

A cell that starts with =, +, -, @, a tab, or a carriage return is prefixed with ' so spreadsheets do not evaluate it as a formula; plain negative numbers are left as they are.

Errors​

CodeMeaning
190 report-question-not-foundA question names a fieldset, field or semantic that no version in scope carries; a fieldset question without a group id; more than the allowed number of questions or dimensions; a dimension that does not apply to the subject or scope (a Tenant dimension on a tenant report).
191 report-subject-cap-exceededMore items match than REPORT_MAX_SUBJECTS (tenant reports) or REPORT_MAX_SUBJECTS_INSTALLATION (installation-wide reports). The message ends with (matched: <n>, limit: <limit>). Narrow the filters.
192 report-subject-not-supportedReserved.

Auditing​

Every call is recorded with its lookup as Report_Outline (1500000), Report_Query (1500001), Report_ExportCsv (1500002) or Report_SearchQuestions (1500003). The outline entries also record installationWide. See Audit events.

See also​