API reference
The official Datapublica Business Register API is JSON over HTTPS at https://query.datapublica.dk. Every endpoint below requires Authorization: Bearer <personal-api-token> and a paid Datapublica plan.
The endpoint list is exhaustive for public API v1. Anonymous endpoints used by the datapublica.dk website are not part of the official API.
Shared conventions
- Query parameters use their exact camel-case or lowercase spelling shown below.
- Search pagination uses
limitandoffset. - Timeline pagination uses
limitand an opaquecursor; passnext_cursorunchanged. - Entity identifiers must come from search results, except that company routes also accept a CVR number.
- JSON record objects can contain extra dataset fields. Use the documented top-level fields and explicitly named nested fields; do not infer a contract from an extra field.
- Entity detail and portfolio responses expose
build_idas the dataset freshness cue. - You can send a valid caller-generated
x-request-idheader; the server reflects it or generates one. Every response includesx-request-id. Usage-controlled responses can also includeX-Usage-*headers.
Common errors are described in Errors. Endpoint-specific lists below identify expected client and availability failures; every endpoint can also return 500 for an unexpected server error.
Companies
GET /api/companies/search
Authentication: Required personal bearer token.
Searches companies and returns pagination metadata plus company row objects.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
q | query | yes | Non-empty string after trimming. |
limit | query | no | Integer, 1–100; default 20. |
offset | query | no | Integer at least 0; default 0. |
Request:
curl --get 'https://query.datapublica.dk/api/companies/search' \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'q=chr' \
--data-urlencode 'limit=1' \
--data-urlencode 'offset=0'
Response 200:
{
"query": "chr",
"total": 40551,
"limit": 1,
"offset": 0,
"rows": [
{
"cvr_number": "14748105",
"company_name": "CHRISTOFFERSEN & KNUDSEN A/S",
"registered_office": "RØDOVRE",
"city": "Rødovre",
"is_active": true
}
]
}
Common errors: 400 invalid/missing query or pagination, 401 token failure, 403 suspended owner, 503 no active dataset.
GET /api/companies/{identifier}
Authentication: Required personal bearer token. User-level company lookup limits apply.
Returns a company bundle. Use an eight-digit CVR number or an identifier resolved by company search.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded CVR number or recognized company identifier. |
financial_scope | query | no | entity or consolidated_group; filters only the additive scoped financial arrays. |
Request:
curl --header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
'https://query.datapublica.dk/api/companies/14748105'
Response 200 shape and example:
{
"cvr": "14748105",
"build_id": "build_...",
"profile": {
"cvr_number": "14748105",
"company_name": "CHRISTOFFERSEN & KNUDSEN A/S",
"city": "Rødovre",
"is_active": true
},
"latestStatus": {},
"financialsAnnual": [],
"financialsAnnualScoped": [
{
"fiscal_year": 2024,
"statement_scope": "consolidated_group",
"reporting_currency": "EUR"
}
],
"annualReportPeriods": [
{
"filing_id": "filing_...",
"reporting_period_start": "2024-01-01",
"reporting_period_end": "2024-12-31",
"financial_data_status": "pdf_only",
"pdf_source_url": "https://regnskaber.cvrapi.dk/...pdf"
}
],
"financialScopes": {
"available": ["consolidated_group"],
"default": "consolidated_group",
"hasUnknown": false
},
"growth": [],
"growthScoped": [],
"ownership": [],
"companyRelations": {
"legalOwners": [],
"previousLegalOwners": [],
"beneficialOwners": [],
"previousBeneficialOwners": [],
"childCompanies": [],
"previousChildCompanies": [],
"relatedCompanies": []
},
"contacts": [],
"people": [],
"auditors": [],
"coverage": {},
"financialDistressScore": null
}
financialsAnnual and growth remain entity-only compatibility series and never fall back to group rows. annualReportPeriods is a display-oriented filing index; financial_data_status: "pdf_only" identifies an annual report whose official PDF is available at pdf_source_url but whose numeric facts are unavailable. Do not use those rows as numeric observations. Scoped rows carry statement_scope and reporting_currency; values are reported amounts and are not FX-converted. profile, latestStatus, and coverage can be null. Array items are dataset records. Common errors: 400 missing identifier or invalid scope, 401 token failure, 403 suspended owner or usage block, 404 company not found, 503 no active dataset or usage-decision service unavailable.
GET /api/companies/{identifier}/financial-report-sections
Authentication: Required personal bearer token. User-level company lookup limits apply under the company_lookup bucket and companies.detail endpoint key.
Returns curated XBRL annual-report text blocks for one filing. With no selectors, the endpoint uses the latest annual filing for the company bundle's financialScopes.default scope.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded CVR number or recognized company identifier. |
filing_id | query | no | Non-empty string, at most 256 characters; defaults to the latest filing for the resolved scope. |
financial_scope | query | no | entity or consolidated_group; defaults to the company bundle's financialScopes.default. |
reporting_period_start | query | no | ISO date used to disambiguate filings that share a filing_id. |
reporting_period_end | query | no | ISO date used to disambiguate filings that share a filing_id. |
x-company-lookup-request-id | header | no | Request id from a successful company lookup for the same CVR. Compatible reuse avoids a second company lookup charge. |
Request using the defaults:
curl --header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
'https://query.datapublica.dk/api/companies/27626661/financial-report-sections'
Response 200 shape:
{
"cvr": "27626661",
"filingId": "filing_5edd0c9f0f29570143db",
"reportExternalId": "...",
"reportingPeriodStart": "2023-01-01T00:00:00.000Z",
"reportingPeriodEnd": "2023-12-31T00:00:00.000Z",
"fiscalYear": 2023,
"financialScope": "entity",
"sourceReportUrl": null,
"sections": [
{
"sectionId": "...",
"canonicalSectionKey": "primary_activities",
"sectionGroup": "business_and_development",
"displayOrder": 10,
"financialScope": "report_wide",
"contentPlain": "...",
"blocks": [{ "kind": "paragraph", "content": "..." }],
"language": "da",
"isTruncated": false
}
],
"availableReports": [
{
"filingId": "filing_5edd0c9f0f29570143db",
"reportExternalId": "...",
"reportingPeriodStart": "2023-01-01T00:00:00.000Z",
"reportingPeriodEnd": "2023-12-31T00:00:00.000Z",
"fiscalYear": 2023,
"sourceReportUrl": null,
"hasSections": true,
"locked": false
}
]
}
These are thirteen curated canonical keys in the business_and_development, risks_and_material_matters, and commitments_and_security groups, not the complete annual report. contentPlain is capped at 20,000 characters per section; isTruncated: true marks an excerpt, and there is no pagination. Boilerplate is suppressed and content duplicated across scopes is deduplicated, so a missing section is not evidence that the filer wrote nothing. language is per section and usually da. A section's financialScope can be report_wide even for an entity or consolidated_group request. sourceReportUrl can be null. availableReports[].locked is a UI compatibility field and is always false for token-authenticated calls. A PDF-only filing returns sections: [] and remains represented in availableReports. If a company has no scoped numeric annual filing from which to derive financialScopes.default, supply financial_scope explicitly; omitting it returns 400 rather than guessing a scope.
Successful responses include the X-Usage-* headers. Common errors: 400 invalid parameters or no scoped annual filing, 401 token failure, 403 suspended owner or usage block, 404 filing not aligned to the company and scope, 503 no active dataset or usage-decision service unavailable.
GET /api/companies/{identifier}/timeline
Authentication: Required personal bearer token.
Returns company events ordered for cursor pagination.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded CVR number or recognized company identifier. |
limit | query | no | Integer, 1–100; default 50. |
cursor | query | no | Opaque next_cursor value from the previous response. |
Request:
curl --get \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'limit=1' \
'https://query.datapublica.dk/api/companies/14748105/timeline'
Response 200:
{
"events": [
{
"event_id": "registration_notice_timeline_...",
"cvr_number": "14748105",
"category": "registry",
"field_key": "capital",
"occurred_at": "2026-03-25T10:30:00.280Z",
"source": "registration_text_payload",
"metadata": {}
}
],
"next_cursor": "1"
}
truncated_by_plan: true can be present when the owner's plan restricts timeline depth. Common errors: 400 invalid identifier/pagination, 401 token failure, 403 suspended owner, 404 company not found, 503 no active dataset.
GET /api/companies/{identifier}/portfolio
Authentication: Required personal bearer token.
Returns the initial company ownership graph.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded CVR number or recognized company identifier. |
Request:
curl --header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
'https://query.datapublica.dk/api/companies/14748105/portfolio'
Response 200:
{
"root": "company:14748105",
"build_id": "build_...",
"truncated": false,
"nodes": [
{
"nodeId": "company:14748105",
"entityType": "company",
"displayName": "CHRISTOFFERSEN & KNUDSEN A/S",
"companyCvrNumber": "14748105",
"personId": null,
"participantId": null,
"isRoot": true,
"expandUpCount": 1,
"expandDownCount": 0
}
],
"edges": [
{
"edgeId": "company:37933562->company:14748105:legal_owner",
"sourceNodeId": "company:37933562",
"targetNodeId": "company:14748105",
"ownershipLabel": "66.67-89.99%",
"relationshipKind": "legal_owner"
}
]
}
Node objects also include slug/display labels and expansion state; edges include ownership precision and lower/upper percentages. Common errors: 400 missing identifier, 401 token failure, 403 suspended owner, 404 company not found, 503 no active dataset.
People
GET /api/people/search
Authentication: Required personal bearer token.
Searches person identities and returns pagination metadata plus person row objects.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
q | query | yes | Non-empty string after trimming. |
limit | query | no | Integer, 1–100; default 20. |
offset | query | no | Integer at least 0; default 0. |
Request:
curl --get 'https://query.datapublica.dk/api/people/search' \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'q=ole' \
--data-urlencode 'limit=1'
Response 200:
{
"query": "ole",
"total": 26727,
"limit": 1,
"offset": 0,
"rows": [
{
"person_id": "pid_entity_4000350926",
"display_name": "Ole Bjørvig Pedersen",
"slug": "ole-bj-rvig-pedersen",
"identity_confidence": "high",
"company_count": 173
}
]
}
Common errors: 400 invalid/missing query or pagination, 401 token failure, 403 suspended owner, 503 no active dataset.
GET /api/people/{identifier}
Authentication: Required personal bearer token.
Returns the person bundle for an identifier from people search.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded person identifier. |
Request:
curl --header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
'https://query.datapublica.dk/api/people/pid_entity_4000350926'
Response 200:
{
"person_id": "pid_entity_4000350926",
"build_id": "build_...",
"profile": {
"person_id": "pid_entity_4000350926",
"display_name": "Ole Bjørvig Pedersen",
"identity_confidence": "high",
"company_count": 173
},
"currentRoles": [],
"roleHistory": [],
"ownership": [],
"auditorHistory": [],
"contacts": [],
"relatedCompanies": []
}
profile can be null; array items are dataset records. Common errors: 400 missing identifier, 401 token failure, 403 suspended owner, 404 person not found, 503 no active dataset.
GET /api/people/{identifier}/timeline
Authentication: Required personal bearer token.
Returns person events ordered for cursor pagination.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded person identifier. |
limit | query | no | Integer, 1–100; default 50. |
cursor | query | no | Opaque next_cursor value from the previous response. |
Request:
curl --get \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'limit=1' \
'https://query.datapublica.dk/api/people/pid_entity_4000350926/timeline'
Response 200:
{
"events": [
{
"event_id": "person_timeline_role_...",
"person_id": "pid_entity_4000350926",
"category": "role",
"field_key": "executive_board",
"occurred_at": "2026-06-08T00:00:00.000Z",
"source": "registry_participant",
"metadata": {
"event_type": "person_joined_management"
}
}
],
"next_cursor": "1"
}
Common errors: 400 invalid identifier/pagination, 401 token failure, 403 suspended owner, 404 person not found, 503 no active dataset.
GET /api/people/{identifier}/portfolio
Authentication: Required personal bearer token.
Returns the initial ownership graph rooted at a person.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded person identifier. |
Request:
curl --header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
'https://query.datapublica.dk/api/people/pid_entity_4000350926/portfolio'
Response 200:
{
"root": "person:pid_entity_4000350926",
"build_id": "build_...",
"truncated": false,
"nodes": [
{
"nodeId": "person:pid_entity_4000350926",
"entityType": "person",
"displayName": "Ole Bjørvig Pedersen",
"personId": "pid_entity_4000350926",
"isRoot": true
}
],
"edges": [
{
"sourceNodeId": "person:pid_entity_4000350926",
"targetNodeId": "company:15273747",
"ownershipLabel": "100%",
"relationshipKind": "legal_owner"
}
]
}
The complete node and edge shape is the same as the company portfolio response. Common errors: 400 missing identifier, 401 token failure, 403 suspended owner, 404 person not found, 503 no active dataset.
Other participants
Participants represent registry actors that are not resolved as a company or person, such as foreign legal entities.
GET /api/participants/search
Authentication: Required personal bearer token.
Searches other participants and returns pagination metadata plus participant row objects.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
q | query | yes | Non-empty string after trimming. |
limit | query | no | Integer, 1–100; default 20. |
offset | query | no | Integer at least 0; default 0. |
Request:
curl --get 'https://query.datapublica.dk/api/participants/search' \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'q=maersk' \
--data-urlencode 'limit=2'
Response 200:
{
"query": "maersk",
"total": 1,
"limit": 2,
"offset": 0,
"rows": [
{
"participant_id": "pid_owner_enhed_4006813524",
"display_name": "Maersk Broker Asia Limited",
"slug": "maersk-broker-asia-limited",
"display_hint": "foreign_legal_entity",
"country_code": "HK"
}
]
}
Common errors: 400 invalid/missing query or pagination, 401 token failure, 403 suspended owner, 503 no active dataset.
GET /api/participants/{identifier}
Authentication: Required personal bearer token.
Returns the participant bundle for an identifier from participant search.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded participant identifier. |
Request:
curl --header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
'https://query.datapublica.dk/api/participants/pid_owner_enhed_4006813524'
Response 200:
{
"participant_id": "pid_owner_enhed_4006813524",
"build_id": "build_...",
"profile": {
"participant_id": "pid_owner_enhed_4006813524",
"display_name": "Maersk Broker Asia Limited",
"display_hint": "foreign_legal_entity",
"country_code": "HK"
},
"currentRoles": [],
"roleHistory": [],
"ownership": [],
"relatedCompanies": []
}
profile can be null; array items are dataset records. Common errors: 400 missing identifier, 401 token failure, 403 suspended owner, 404 participant not found, 503 no active dataset.
GET /api/participants/{identifier}/timeline
Authentication: Required personal bearer token.
Returns participant events ordered for cursor pagination.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded participant identifier. |
limit | query | no | Integer, 1–100; default 50. |
cursor | query | no | Opaque next_cursor value from the previous response. |
Request:
curl --get \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'limit=1' \
'https://query.datapublica.dk/api/participants/pid_owner_enhed_4006813524/timeline'
Response 200:
{
"events": [
{
"event_id": "other_participant_timeline_...",
"participant_id": "pid_owner_enhed_4006813524",
"category": "ownership",
"field_key": "legal_owner",
"occurred_at": "2017-02-23T00:00:00.000Z",
"source": "company_payload",
"metadata": {}
}
],
"next_cursor": null
}
Common errors: 400 invalid identifier/pagination, 401 token failure, 403 suspended owner, 404 participant not found, 503 no active dataset.
GET /api/participants/{identifier}/portfolio
Authentication: Required personal bearer token.
Returns the initial ownership graph rooted at another participant.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
identifier | path | yes | URL-encoded participant identifier. |
Request:
curl --header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
'https://query.datapublica.dk/api/participants/pid_owner_enhed_4006813524/portfolio'
Response 200:
{
"root": "participant:pid_owner_enhed_4006813524",
"build_id": "build_...",
"truncated": false,
"nodes": [
{
"nodeId": "participant:pid_owner_enhed_4006813524",
"entityType": "participant",
"displayName": "Maersk Broker Asia Limited",
"participantId": "pid_owner_enhed_4006813524",
"displayHint": "foreign_legal_entity",
"isRoot": true
}
],
"edges": []
}
The complete node and edge shape is the same as the company portfolio response. Common errors: 400 missing identifier, 401 token failure, 403 suspended owner, 404 participant not found, 503 no active dataset.
Ownership relation expansion
GET /api/portfolio/entities/{entityType}/{id}/relations
Authentication: Required personal bearer token.
Expands relations around one node without refetching the whole portfolio.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
entityType | path | yes | company, person, or participant. |
id | path | yes | URL-encoded entity identifier without the type prefix. |
direction | query | no | up, down, or both; default both. |
visibleNodeIds | query | no | Comma-separated graph node IDs already visible; duplicates/empty values are ignored and up to 200 distinct IDs are used. |
Request:
curl --get \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'direction=both' \
--data-urlencode 'visibleNodeIds=company:14748105' \
'https://query.datapublica.dk/api/portfolio/entities/company/14748105/relations'
Response 200:
{
"targetNodeId": "company:14748105",
"truncated": false,
"nodes": [
{
"nodeId": "company:37933562",
"entityType": "company",
"displayName": "Example Holding A/S",
"companyCvrNumber": "37933562",
"isRoot": false
}
],
"edges": [
{
"sourceNodeId": "company:37933562",
"targetNodeId": "company:14748105",
"ownershipLabel": "66.67-89.99%",
"relationshipKind": "legal_owner"
}
],
"updatedNode": {
"nodeId": "company:14748105",
"isExpandedUp": true,
"isExpandedDown": true
}
}
updatedNode can be null. Common errors: 400 invalid type/parameters or missing ID, 401 token failure, 403 suspended owner, 404 entity not found, 503 no active dataset.
SQL
Queries run on DuckDB, so use DuckDB SQL syntax and functions.
GET /api/sql
Authentication: Required personal bearer token. SQL usage limits apply.
Executes one read-only SQL statement against the active dataset. Mutating statements, data-definition statements, multiple statements, and statements outside the read-only guard are rejected.
| Parameter | In | Required | Type and rules |
|---|---|---|---|
query | query | conditionally | SQL string, 1–20,000 characters. Supply query or the alias sql. |
sql | query | conditionally | Alias for query; do not send both. |
source | query | no | direct or natural-language; default direct. |
rawInput | query | conditional | Original question, 1–1,000 characters; required when source=natural-language. |
x-request-id | header | no | Caller-generated identifier, up to 128 allowed characters. Reuse the translation request ID when executing translated SQL. |
Request:
curl --get 'https://query.datapublica.dk/api/sql' \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--data-urlencode 'query=SELECT cvr_number, company_name FROM gold.mart_company_profile ORDER BY company_name LIMIT 1'
Response 200:
{
"query": "SELECT cvr_number, company_name FROM gold.mart_company_profile ORDER BY company_name LIMIT 1",
"columns": ["cvr_number", "company_name"],
"rowCount": 1,
"rows": [
{
"cvr_number": "43854968",
"company_name": "!Act A/S"
}
]
}
Common errors: 400 missing/invalid/non-read-only SQL, 401 token failure, 403 suspended owner or usage block, 429 short-term rate limit, 503 no active dataset or usage-decision service unavailable.
POST /api/sql/translate
Authentication: Required personal bearer token. Natural-language usage limits apply.
Translates an English or Danish question into one read-only SQL statement. Translation does not execute the SQL. To execute an accepted sql value against the same natural-language usage reservation, call GET /api/sql with the same x-request-id, source=natural-language, and the exact original question as rawInput. Without that correlation, execution is treated as a separate direct SQL request and SQL usage limits apply separately.
| Field | In | Required | Type and rules | |
|---|---|---|---|---|
query | JSON body | yes | String, 1–1,000 characters after trimming. | |
locale | JSON body | no | en or da; default en. This documentation is English-only, but the request supports both values. | |
maxRows | JSON body | no | Integer, 1–100; default 100. | |
priorTurns | JSON body | no | Array of at most 10 earlier turns, oldest first, each `{"question": string, "sql": string \ | null}. Supplying them lets a follow-up such as "same, but above 50M"` resolve against the earlier questions. |
Every response carries resolvedQuestion: the self-contained question that was actually translated. It equals the trimmed query unless follow-up phrasing was resolved against priorTurns. Store it rather than the raw follow-up text when you keep a history of questions, so each entry still reads correctly on its own.
Request:
REQUEST_ID="$(uuidgen)"
curl 'https://query.datapublica.dk/api/sql/translate' \
--request POST \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--header "x-request-id: $REQUEST_ID" \
--header 'Content-Type: application/json' \
--data '{"query":"Companies with the highest revenue in 2025","locale":"en","maxRows":1}'
Response 200:
{
"status": "ok",
"sql": "SELECT ... FROM gold.mart_company_financials_annual ... LIMIT 1",
"exportSql": "SELECT ... FROM gold.mart_company_financials_annual ... LIMIT 1",
"resolvedQuestion": "Companies with the highest revenue in 2025",
"description": "Returns the active company with the highest reported revenue for the 2025 reporting-period end year.",
"notes": ["Revenue is ranked using the exact annual revenue field, with no fallback metric."],
"assumptions": ["‘In 2025’ is interpreted as reporting-period end year 2025."],
"warnings": [],
"metadata": {
"provider": "openai",
"model": "model-name",
"buildId": "build_...",
"schemaVersion": "sha256:...",
"referencedTables": [
"gold.mart_company_financials_annual",
"gold.mart_company_latest_status"
],
"limit": {
"kind": "default_preview",
"rowCount": 1
}
}
}
Response 422 when clarification is required or the behavior is unsupported:
{
"status": "unsupported",
"sql": null,
"resolvedQuestion": "Delete all inactive companies",
"description": "Deleting inactive companies is a mutating and unsafe operation, which is not supported.",
"notes": ["Only read-only SQL queries can be generated."],
"assumptions": [],
"warnings": ["No data was deleted."],
"metadata": {
"provider": "openai",
"model": "model-name",
"buildId": "build_...",
"schemaVersion": "sha256:...",
"referencedTables": []
},
"error": {
"code": "unsafe_request"
}
}
The alternate 422 outcome has status: "needs_clarification" and error.code: "needs_clarification". Common errors: 400 invalid JSON/body fields, 401 token failure, 403 suspended owner or usage block, 422 handled translation issue, 429 short-term rate limit, 503 no active dataset or usage-decision service unavailable.
For a successful translation, copy the returned sql value into TRANSLATED_SQL and execute it with the correlated request metadata:
TRANSLATED_SQL='SELECT ... FROM gold.mart_company_financials_annual ... LIMIT 1'
curl --get 'https://query.datapublica.dk/api/sql' \
--header "Authorization: Bearer $DATAPUBLICA_API_TOKEN" \
--header "x-request-id: $REQUEST_ID" \
--data-urlencode 'source=natural-language' \
--data-urlencode 'rawInput=Companies with the highest revenue in 2025' \
--data-urlencode "query=$TRANSLATED_SQL"
Error bodies and usage headers
Standard errors use { "error": "message" }. Usage blocks add code, planKey, quotaBucket, limit, used, remaining, windowStart, windowEnd, and resetAt when available. Usage responses can include X-Usage-Bucket, X-Usage-Limit, X-Usage-Remaining, and X-Usage-Reset.
See Errors for retry guidance and Authentication for the one-active-token model.