Skip to main content

UC-011 — Export Delivery Reports and History

FieldValue
IDUC-011
GoalExport delivery reports, message history and contacts as CSV
ChannelAll (SMS, RCS, WhatsApp)
Complexity⭐⭐⭐ Advanced
Estimated time15 minutes
APIs involvedPOST /api/partner-gateway/v1/exports/delivery-reports, GET /exports, GET /exports/{exportId}, POST /exports/{exportId}, POST /exports/contacts, GET /messages/history, POST /messages/history/export

Real-world scenarios​

  • Banca Adriatica — Monthly billing report: On the first day of each month, the finance team exports all the delivery reports of the previous month to reconcile SMS and WhatsApp sending costs.
  • FashionOutlet — Campaign performance analysis: After the Black Friday campaign, marketing exports the reports to compute delivery, open and conversion rates per channel.
  • FarmaExpress — Compliance audit: For GDPR requirements, the DPO exports the full history of messages sent in a quarter, with recipient details.

Prerequisites​

Before you begin, make sure you have:

  • Active API Key → How to get one
  • Messages to export → messages sent in the period you want to report on, or a campaignId

Export flow​

Step-by-step guide​

Step 1 — Request the delivery-report export​

Export the delivery reports for a date range. Dates use the format yyyy-MM-dd HH:mm:ss.SSSZ:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/exports/delivery-reports" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"startDateTime": "2026-03-01 00:00:00.000+0100",
"endDateTime": "2026-03-31 23:59:59.000+0200",
"sendType": "API",
"exportFormat": "CSV"
}'

Response: 202 Accepted -- the export job is queued.

You can also export a specific campaign instead of a date range:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/exports/delivery-reports" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"campaignId": 1584,
"exportFormat": "CSV"
}'
ParameterTypeDescription
startDateTimestringStart of the range (yyyy-MM-dd HH:mm:ss.SSSZ)
endDateTimestringEnd of the range
senderstringFilter by sender
recipientstringFilter by recipient
campaignIdintegerCampaign ID (alternative to the date range)
sendTypestringSend type: WEB, WEB_API, API
subAccountIdstringFilter by sub-account
exportFormatstringFormat: CSV (default) or EXCEL

A request with neither campaignId nor a date range, or with a date in the wrong format, is answered 400.

Step 2 — List the exports​

Check the status of your exports. The list is paginated with page (0-based) and limit (default 10):

curl -X GET "https://api.qlara.ai/api/partner-gateway/v1/exports?page=0&limit=10" \
-H "X-Api-Key: YOUR_API_KEY"

Response:

{
"data": [
{
"id": 42,
"type": "DELIVERY_REPORT",
"detail": {
"startDateTime": "2026-03-01T00:00:00+01:00",
"endDateTime": "2026-03-31T23:59:59+02:00",
"sendType": "API",
"exportFormat": "CSV"
},
"status": "COMPLETED",
"createdAt": "2026-04-01 08:15:00.000+0200",
"expiresAt": "2026-04-08 08:15:00.000+0200",
"isAvailableForDownload": true
},
{
"id": 41,
"type": "CONTACTS",
"detail": {
"listIds": [10, 11],
"exportFormat": "CSV"
},
"status": "COMPLETED",
"createdAt": "2026-03-28 14:30:00.000+0100",
"expiresAt": "2026-04-04 14:30:00.000+0200",
"isAvailableForDownload": false
}
],
"page": 0,
"limit": 10,
"totalCount": 2,
"totalPages": 1
}
StatusMeaning
PENDINGThe export is queued or being processed
COMPLETEDThe file is ready for download
FAILEDThe export ran into an error

Step 3 — Check availability​

Before downloading, check that isAvailableForDownload is true. If the link has expired (isAvailableForDownload: false), regenerate it:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/exports/41" \
-H "X-Api-Key: YOUR_API_KEY"

Response: 202 Accepted -- the link will be regenerated. Wait a few seconds and check again with GET /exports. An export that has not expired yet is answered 400 (just download it), an unknown exportId 404.

Step 4 — Download the file​

When the status is COMPLETED and isAvailableForDownload is true:

curl -X GET "https://api.qlara.ai/api/partner-gateway/v1/exports/42" \
-H "X-Api-Key: YOUR_API_KEY"

Response:

{
"url": "https://storage.example.com/exports/42.csv?token=abc123def456&expires=1712570100"
}

Use the returned URL to download the CSV file:

curl -o delivery-report-march-2026.csv "https://storage.example.com/exports/42.csv?token=abc123def456&expires=1712570100"

Export contacts​

You can also export contact lists:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/exports/contacts" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"listIds": [10, 11],
"exportFormat": "CSV"
}'

Response: 202 Accepted

ParameterTypeDescription
listIdsarray[int]IDs of the lists to export (alternative to contactIds)
contactIdsarray[int]IDs of the specific contacts to export
excludeContactIdsarray[int]IDs of contacts to exclude (only with listIds)
exportFormatstringFormat: CSV or EXCEL
Export everything

If you specify neither listIds nor contactIds, all the contacts of your account are exported.

Message history​

Browse the history​

To browse your sending history without exporting it, use pagination. channel, from and to are required:

curl -X GET "https://api.qlara.ai/api/partner-gateway/v1/messages/history?channel=SMS&from=2026-03-01T00:00:00%2B01:00&to=2026-03-31T23:59:59%2B02:00&page=0&limit=50" \
-H "X-Api-Key: YOUR_API_KEY"

Export the history as CSV​

For large volumes, export the history asynchronously. Dates are ISO 8601 with an offset; sender and recipient are optional filters:

curl -X POST "https://api.qlara.ai/api/partner-gateway/v1/messages/history/export" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"startDateTime": "2026-03-01T00:00:00+01:00",
"endDateTime": "2026-03-31T23:59:59+02:00",
"sender": "TechStore",
"recipient": "+393471234567"
}'

Response: 202 Accepted with an empty body.

The export covers every channel (SMS, RCS, WhatsApp) and only the messages sent through the API; it has no channel or status filter. The job follows the same flow: check GET /exports and download with GET /exports/{exportId}.

Endpoint summary​

ActionMethodEndpoint
Export delivery reportsPOST/exports/delivery-reports
Export contactsPOST/exports/contacts
Export message historyPOST/messages/history/export
List exportsGET/exports
Download URLGET/exports/{exportId}
Regenerate expired linkPOST/exports/{exportId}
Browse historyGET/messages/history
Behind the scenes

Exports are designed to handle large data volumes without blocking the API:

  1. Queueing -- The POST request creates an asynchronous job and answers 202 Accepted within milliseconds.
  2. Processing -- A background worker collects the data, formats it as CSV/EXCEL and uploads the file to secure storage.
  3. Status -- The status moves from PENDING to COMPLETED (or FAILED). Poll GET /exports to check it.
  4. Download -- The download URL is a pre-signed link with an expiry. Once it has expired, you can regenerate it with POST /exports/{exportId} without resubmitting the request.
  5. Retention -- Exports stay available until expiresAt (typically 7 days). After that the file is removed, but the original parameters are kept for regeneration.

Expected result​

AspectDetail
Action completedDelivery reports, message history or contacts exported as a CSV/Excel file
Channel usedAll (SMS, RCS, WhatsApp)
Delivery confirmationExport status changes from PENDING to COMPLETED; download URL available

Common errors​

ProblemProbable causeSolution
HTTP 401Missing or invalid API KeyCheck X-Api-Key header
HTTP 400 on the export requestNeither campaignId nor a date range, or a date in the wrong formatPass campaignId or startDateTime/endDateTime (yyyy-MM-dd HH:mm:ss.SSSZ for delivery reports, ISO 8601 with offset for the history export)
Export FAILEDThe background job ran into an errorRequest the export again; if it fails again, contact support quoting the X-Request-Id of the request
isAvailableForDownload: false or HTTP 400 on GET /exports/{exportId}Download link has expiredRegenerate the link with POST /exports/{exportId}
HTTP 404 on /exports/{exportId}Wrong exportId, or an export of another accountTake the id from GET /exports
Empty CSVNo messages found for the specified filtersVerify the date range, campaignId, sender and recipient filters

Next steps​