Manage data exports using APIs
Data exports use the following three report service operations:
Integration guide
- Use Create report to specify the scope, dataset, and optional filters. Save the
reportIdreturned in the HTTP202 Acceptedresponse. If the service returns400with code4122, use the existing report ID fromadditionalDetailsinstead. - Use Get report status with the
reportId. Continue polling while the report isINITIATEDorIN_PROGRESS. Check the report state even when the status request returns HTTP200. - When the report is
COMPLETED, download the file usingdownloadLink.url. ForFAILEDorARCHIVEDreports, create a new report if another export is required. - Use List reports to retrieve previously created reports. Follow
links.nextwhen more results are available.
For request failures, see HTTP status codes and Error codes for data exports.
Authentication and request headers
Use the standard authentication and request headers described in API authentication and access and API request header. No additional report-specific request headers are required.
Do not include a partner identifier in the request body. The authenticated partner can access only its own reports and data.
Create report
Sample request URL: POST <env root url>/v3/reports
Submit the scope, a single dataset selection, and optional filters. Report processing is asynchronous. A successful request returns an HTTP 202 Accepted response with a reportId and an INITIATED status. The response does not contain the report file.
Request body
The following example requests a reseller-scoped churn report:
{
"scope": {
"level": "reseller",
"ids": ["R123"]
},
"datasets": [
{
"dataset": "propensity",
"type": "churn",
"filters": {
"probability": ["HIGH", "MEDIUM"]
}
}
],
"format": "csv"
}
Request parameters
scopescope.levelpartner or reseller.scope.idsdatasetsdatasets[].datasetpropensity.datasets[].typechurn or seat_expansion.datasets[].filtersdatasets[].filters.probabilityHIGH, MEDIUM, or LOW. If omitted, all values are included. Duplicates are removed.formatcsv, which is also the default.For partner scope, use "scope": {"level": "partner"}. The source field is read-only and must not be sent in the request. There is no force-refresh request field. Unknown fields and filters unsupported for the selected dataset and type return code 1121.
Response body
HTTP 202 Accepted:
{
"reportId": "550e8400-e29b-41d4-a716-446655440000",
"scope": {
"level": "reseller",
"ids": ["R123"]
},
"datasets": [
{
"dataset": "propensity",
"type": "churn",
"filters": {
"probability": ["HIGH", "MEDIUM"]
}
}
],
"format": "csv",
"status": "INITIATED",
"source": "API",
"creationDate": "2026-10-22T10:15:30Z",
"links": {
"self": {
"uri": "/v3/reports/550e8400-e29b-41d4-a716-446655440000",
"method": "GET",
"headers": []
}
}
}
Note: A blank probability or reasons column does not indicate LOW propensity or missing data. It indicates that the product did not match the requested probability filter.
Response parameters
reportIdscopedatasetsformatcsv.statusINITIATED when a new report is accepted.sourceAPI for a partner integration or Bridge for the Bridge UI.creationDatelinks.selfuri, method, and headers.Duplicate request handling
If a matching report for the authenticated partner is already INITIATED or IN_PROGRESS, the service does not create another report. HTTP 400 returns code 4122 and the existing report identifier:
{
"code": "4122",
"message": "This request is already being processed. Please wait a moment and try again.",
"additionalDetails": ["reportId: 550e8400-e29b-41d4-a716-446655440000"]
}
Use Get report status to poll the existing report using the identifier in additionalDetails.
The service determines whether requests match by comparing the authenticated partner and the normalized request body:
- JSON field order is ignored.
- Array values are deduplicated and sorted, so their order is ignored.
- Defaults are applied before comparison. Omitting
formatmatches"format": "csv". scope.idsis ignored for partner scope.
If the matching report is COMPLETED, FAILED, or ARCHIVED, or there is no match, the service creates a new report and returns HTTP 202. Completed reports are not automatically reused.
Get report status
Sample request URL: GET <env root url>/v3/reports/{report-id}
Check the report status using the reportId returned by Create report. The operation returns only reports owned by the authenticated partner.
Path parameters
report-idreportId returned when the report was accepted, or the existing report ID returned with code 4122.Response body
Completed response
HTTP 200, with response header Cache-Control: no-store:
{
"reportId": "550e8400-e29b-41d4-a716-446655440000",
"status": "COMPLETED",
"source": "API",
"updatedDate": "2026-10-22T10:20:10Z",
"downloadLink": {
"url": "https://s3.amazonaws.com/bucket/path/to/report?X-Amz-Signature=...",
"expiresAt": "2026-10-22T11:20:10Z"
},
"links": {
"self": {
"uri": "/v3/reports/550e8400-e29b-41d4-a716-446655440000",
"method": "GET",
"headers": []
}
}
}
updatedDate indicates the UTC time of the most recent status change. downloadLink is included only for COMPLETED reports. Its url is a short-lived pre-signed link, and expiresAt specifies when the link expires in UTC. The expiresAt value does not indicate when the report retention period ends. Call Get report status again to obtain a fresh link. Do not cache the completed status response.
Failed response
An HTTP 200 response indicates that the status request succeeded. It does not indicate that report generation succeeded:
{
"reportId": "550e8400-e29b-41d4-a716-446655440000",
"status": "FAILED",
"source": "Bridge",
"updatedDate": "2026-10-22T10:20:10Z",
"additionalDetails": ["Report generation failed. Create a new report to retry."],
"links": {
"self": {
"uri": "/v3/reports/550e8400-e29b-41d4-a716-446655440000",
"method": "GET",
"headers": []
}
}
}
additionalDetails is included only for FAILED reports and contains partner-facing failure reasons. It does not include internal service names, stack traces, or storage errors. Use Create report to submit a new report.
Response parameters
reportIdstatusINITIATED, IN_PROGRESS, COMPLETED, FAILED, or ARCHIVED.sourceAPI or Bridge.updatedDatedownloadLinkCOMPLETED reports.downloadLink.urldownloadLink.expiresAtadditionalDetailsFAILED reports.links.selfuri, method, and headers.Status handling
COMPLETED200 with downloadLink.INITIATED, IN_PROGRESS, or ARCHIVED200 without downloadLink.FAILED200 without downloadLink, with failure reasons in additionalDetails.404, code 1181, message Invalid Report ID.See the report lifecycle and Error codes for data exports to distinguish report state from request errors.
List reports
Sample first-page request URL: GET <env root url>/v3/reports?limit=10&offset=0
Use this operation to retrieve reports for the authenticated partner. Results are ordered by creationDate, with the newest reports first. Sorting is not configurable.
Query parameters
limit10, and the maximum is 50.offset0.Response body
HTTP 200. The following example is for GET <env root url>/v3/reports?limit=1&offset=0 and shows one result with another page available:
{
"totalCount": 2,
"count": 1,
"limit": 1,
"offset": 0,
"items": [
{
"reportId": "550e8400-e29b-41d4-a716-446655440000",
"scope": { "level": "reseller", "ids": ["R123"] },
"datasets": [
{
"dataset": "propensity",
"type": "churn",
"filters": { "probability": ["HIGH", "MEDIUM"] }
}
],
"format": "csv",
"status": "COMPLETED",
"source": "API",
"creationDate": "2026-10-22T10:15:30Z",
"links": {
"self": {
"uri": "/v3/reports/550e8400-e29b-41d4-a716-446655440000",
"method": "GET",
"headers": []
}
}
}
],
"links": {
"self": { "uri": "/v3/reports?limit=1&offset=0", "method": "GET", "headers": [] },
"next": {
"uri": "/v3/reports?limit=1&offset=1",
"method": "GET",
"headers": []
}
}
}
Response parameters
totalCountcountlimitoffsetitemscreationDate descending.items[].reportIditems[].scopeitems[].datasetsitems[].formatcsv.items[].statusINITIATED, IN_PROGRESS, COMPLETED, FAILED, or ARCHIVED.items[].sourceAPI for a partner integration or Bridge for the Bridge UI.items[].creationDateitems[].links.selflinks.selflinks.nextlinks.prevLink objects contain uri, method, and headers. Use Get report status for a selected report to obtain its download link.
Pagination
Pagination uses limit and offset. Follow links.next to retrieve the next page and links.prev to retrieve the previous page. These links are omitted when there is no corresponding page.
Download the file
After Get report status returns a COMPLETED status with downloadLink, download the CSV separately using downloadLink.url:
GET <downloadLink.url>
Use the returned pre-signed URL as provided. Do not construct or modify the hostname, filename, signature, or expiration information. Treat the pre-signed URL as a credential and protect it accordingly. If the URL reaches downloadLink.expiresAt while the report remains COMPLETED, call Get report status again with the same reportId to obtain a fresh link to the same retained file. Download link expiry does not affect report retention or cause the report to become ARCHIVED.
Report retention
Retention begins when a report becomes COMPLETED:
churnseat_expansionWhen retention ends, the report becomes ARCHIVED and its file is no longer available. Use Create report to request a new report. Download link expiry and report retention are independent. downloadLink.expiresAt indicates only when the download link expires.
Report file format
Reports are UTF-8 CSV files with a header row and one row per customer. Columns depend on datasets[].type. Dates use YYYY-MM-DD in UTC. Each reasons field contains reasonCode=value pairs separated by semicolons and is enclosed in double quotation marks.
Churn report
For type: "churn":
reseller_idcustomer_idcreative_cloud_probabilityHIGH, MEDIUM, or LOW.creative_cloud_reasonsdocument_cloud_probabilityHIGH, MEDIUM, or LOW.document_cloud_reasonsanniversary_daterefresh_dateWhen a probability filter is supplied, a customer row is included if the Creative Cloud or Document Cloud probability matches the specified filter. Columns for a product that does not match the filter are left empty.
Seat expansion report
For type: "seat_expansion":
reseller_idcustomer_idprobabilityHIGH, MEDIUM, or LOW.predicted_addon_sizereasonsanniversary_daterefresh_dateHTTP status codes
The following HTTP status codes apply to the report service APIs, not to the separate file download:
202 Accepted200 OKstatus to determine the report outcome, including FAILED or ARCHIVED.400 Bad RequestadditionalDetails.404 Not Found1181, Invalid Report ID.401 Unauthorized and 403 Forbidden500 Internal Server Error503 Service UnavailableSee Error codes for data exports for the application codes, operation-specific mappings, and error response examples.