Skip to content

CxReports API

The CxReports API allows developers to integrate CxReports into other applications seamlessly. Typical use cases include previewing reports inside iframes and exporting reports to PDF, Excel, Word, and PowerPoint.


Getting Started

The API is available at /api/v1/. To explore it interactively, enable Swagger in your configuration and open it in a browser. A live version is available at the demo environment, though the installed version of your instance may differ — always prefer the locally-enabled Swagger for your version.

Official API clients for various languages are listed on the Developer Resources page.


Authentication

All API requests must include a Bearer token in the Authorization header:

Authorization: Bearer {token}

To generate a token, open the User menu in the top-right corner and select Personal Access Tokens.

Important: Personal Access Tokens must only be used server-side. Do not expose them in client-side JavaScript or iframes. For browser-based use, see Iframe Authentication below.


Workspaces

Most endpoints are scoped to a workspace using the {workspaceId} path parameter, which can be either a numeric ID or a workspace code string.

List workspaces

GET /api/v1/workspaces

Returns all workspaces the authenticated user has access to.

Response 200 OK

[
  {
    "id": 0,
    "name": "string",
    "description": "string",
    "code": "string"
  }
]


Reports

List reports

GET /api/v1/ws/{workspaceId}/reports

Returns all reports in the workspace, optionally filtered by report type.

Parameter Type In Description
workspaceId string path Workspace ID or code
type string query Filter by report type code

Response 200 OK

[
  {
    "id": 0,
    "name": "string",
    "reportTypeId": 0,
    "reportTypeName": "string",
    "reportTemplateName": "string",
    "themeName": "string",
    "isDefault": true
  }
]


List report pages

GET /api/v1/ws/{workspaceId}/reports/{reportIdOrTypeCode}/pages

Returns the pages belonging to a report. Useful for targeted exports that exclude specific pages.

Parameter Type In Description
workspaceId string path Workspace ID or code
reportIdOrTypeCode string path Report ID or report type code

Response 200 OK

[
  {
    "id": 0,
    "name": "string",
    "type": "page"
  }
]


Exporting Reports

Reports can be exported synchronously (the response is the file) or asynchronously (the response is a job ID you poll). Use the async export for large reports or when you need to avoid request timeouts.

Export synchronously (GET)

GET /api/v1/ws/{workspaceId}/reports/{reportIdOrTypeCode}/pdf

Exports a report and returns the file directly. Pass parameters as query strings.

Parameter Type In Description
workspaceId string path Workspace ID or code
reportIdOrTypeCode string path Report ID or report type code
params string (JSON) query Report parameters object
data string (JSON) query Inline data to pass to the report
tempDataId integer query ID of a previously uploaded temporary data object
lang string query Preferred language for the report
timezone string query Preferred timezone
format string query Output format. One of: pdf, docx, xlsx, pptx, html. Defaults to pdf
includeAttachments boolean query If true, wraps the report and its attachments in a ZIP. Defaults to false
template string query Code or ID of the template to use. Defaults to the report's default template
theme string query Code or ID of the theme to use. Defaults to the report's default theme

Response 200 OK — file stream with Content-Type and Content-Disposition headers set.


Export synchronously (POST)

POST /api/v1/ws/{workspaceId}/reports/{reportIdOrTypeCode}/pdf

Same as the GET export above, but accepts parameters as a JSON body. Prefer this over GET when passing large data payloads.

Parameter Type In Description
workspaceId string path Workspace ID or code
reportIdOrTypeCode string path Report ID or report type code

Request body

{
  "params": {},
  "data": {},
  "lang": "string",
  "timezone": "string",
  "format": "pdf",
  "includeAttachments": false,
  "template": "string",
  "theme": "string"
}

Response 200 OK — file stream.


Start an async export

POST /api/v1/ws/{workspaceId}/reports/{reportIdOrTypeCode}/export

Queues a report for generation and immediately returns a temporaryFileId. Poll the status endpoint until the file is ready, then download it.

Parameter Type In Description
workspaceId string path Workspace ID or code
reportIdOrTypeCode string path Report ID or report type code

Request body

{
  "params": {},
  "data": {},
  "lang": "string",
  "timezone": "string",
  "format": "pdf",
  "includeAttachments": false,
  "excludePages": [0],
  "tempDataId": 0,
  "template": "string",
  "theme": "string"
}

Response 202 Accepted

{
  "temporaryFileId": 0
}

Use the returned temporaryFileId with the async export endpoints below.


Async Export: Status and Download

These endpoints are used after starting an async export (or generating a job review document) to check progress and retrieve the file.

Check export status

GET /api/v1/ws/{workspaceId}/exports/{tempFileId}/status

Poll this endpoint periodically until isReady is true.

Parameter Type In Description
workspaceId string path Workspace ID or code
tempFileId integer path Temporary file ID returned from the export request

Response 200 OK

{
  "id": 0,
  "status": "InProgress",
  "isReady": false,
  "errorMessage": null,
  "expiryTime": "2026-03-04T13:00:00.000Z",
  "name": null,
  "contentSize": null,
  "contentType": null
}

Field Description
status Current state: InProgress, Completed, or Failed
isReady true when the file is ready to download
errorMessage Populated only when status is Failed
expiryTime When the temporary file will be automatically deleted
name, contentSize, contentType File metadata, populated once status is Completed

Responses: 404 Not Found — file has expired, been deleted, or the ID is invalid.


Download exported file

GET /api/v1/ws/{workspaceId}/exports/{tempFileId}/content

Downloads the generated file. Only call this after confirming status is Completed and isReady is true.

Parameter Type In Description
workspaceId string path Workspace ID or code
tempFileId integer path Temporary file ID

Response 200 OK — file stream with Content-Type (e.g. application/pdf, application/vnd.openxmlformats-officedocument.spreadsheetml.sheet) and Content-Disposition headers set.

Responses: 400 Bad Request — file is not yet ready or content is empty. 404 Not Found — file not found or expired.

Async export flow

POST /export  →  { temporaryFileId }
GET /exports/{id}/status  (poll until isReady = true)
GET /exports/{id}/content  →  file download

Temporary Data

Large or sensitive data payloads can be uploaded once and referenced by ID in subsequent report export requests, avoiding repeated transmission.

Upload temporary data

POST /api/v1/ws/{workspaceId}/temporary-data
Parameter Type In Description
workspaceId string path Workspace ID or code

Request body

{
  "content": {},
  "expiryDate": "2026-03-04T13:00:00.000Z"
}

Response 200 OK

{
  "tempDataId": 0,
  "expiryDate": "2026-03-04T13:00:00.000Z"
}

Pass the returned tempDataId as a parameter in export requests.


Jobs

Jobs process batches of report entries. A typical job workflow is: start a run → poll status → (optionally) generate a review document → deliver.

List jobs

GET /api/v1/ws/{workspaceId}/jobs

Response 200 OK

[
  {
    "id": 0,
    "name": "string",
    "description": "string",
    "code": "string",
    "reviewRequired": true,
    "isActive": true,
    "lastRunTime": "2026-03-04T13:00:00.000Z"
  }
]


Start a job run

POST /api/v1/ws/{workspaceId}/jobs/{jobIdOrCode}/runs
Parameter Type In Description
workspaceId string path Workspace ID or code
jobIdOrCode string path Job ID or code

Request body

{
  "params": {},
  "data": {}
}

Response 200 OK

{
  "jobRunId": 0
}


Get job run status

GET /api/v1/ws/{workspaceId}/jobs/{jobIdOrCode}/runs/{jobRunId}/status
Parameter Type In Description
workspaceId string path Workspace ID or code
jobIdOrCode string path Job ID or code
jobRunId integer path Job run ID returned when the run was started

Response 200 OK

{
  "finished": false,
  "entries": 0,
  "status": {
    "queued": 0,
    "review": 0,
    "completed": 0,
    "errors": 0
  }
}


Generate a review document

POST /api/v1/ws/{workspaceId}/jobs/{jobIdOrCode}/runs/{jobRunId}/generate-review-document

Generates a consolidated document for reviewing the job run's entries. Returns a temporaryFileId — use the async export endpoints to track and download the result.

Parameter Type In Description
workspaceId string path Workspace ID or code
jobIdOrCode string path Job ID or code
jobRunId integer path Job run ID

Response 202 Accepted

{
  "temporaryFileId": 0
}


Deliver a job run

POST /api/v1/ws/{workspaceId}/jobs/{jobIdOrCode}/runs/{jobRunId}/deliver

Delivers all entries for the job run after review and approval. Only applicable when reviewRequired is true on the job.

Parameter Type In Description
workspaceId string path Workspace ID or code
jobIdOrCode string path Job ID or code
jobRunId integer path Job run ID

Responses: 200 OK on success. 404 Not Found if the job run does not exist.


Report Types

List report types

GET /api/v1/ws/{workspaceId}/report-types

Response 200 OK

[
  {
    "id": 0,
    "name": "string",
    "description": "string",
    "code": "string",
    "defaultReportId": 0,
    "defaultReportName": "string"
  }
]


Report Templates

List templates

GET /api/v1/ws/{workspaceId}/templates

Response 200 OK

[
  {
    "id": 0,
    "name": "string",
    "code": "string"
  }
]


Themes

List themes

GET /api/v1/ws/{workspaceId}/themes

Response 200 OK

[
  {
    "id": 0,
    "name": "string",
    "code": "string"
  }
]


Iframe Authentication

Personal Access Tokens must not be used client-side. To authenticate reports embedded in iframes, use a short-lived Nonce token instead.

How it works

  1. Server-side: Call POST /api/v1/nonce-tokens using your PAT to create a single-use Nonce.
  2. Client-side: Append the value to your iframe URL as ?nonce={value}.
  3. On the first request, the Nonce is exchanged for a session cookie. All subsequent iframe requests are authenticated via that cookie.

Create a nonce token

POST /api/v1/nonce-tokens

No request body or parameters required.

Response 200 OK

{
  "nonce": "string"
}

See the Consumer Demo App on GitHub for a complete integration example.


HTTP Status Codes

Code Meaning
200 OK Request succeeded
202 Accepted Async job accepted and queued
400 Bad Request Invalid request, e.g. file not ready for download
401 Unauthorized Missing or invalid Bearer token
404 Not Found Resource not found, expired, or deleted