Exports endpoints to start a click export for an organization or one link, poll its status, and download the identical CSV file as often as you need.
A click export is a background job. You start it with one request, watch its status, and download the finished file when it is complete, so a large export never times out a request. Every export is a snapshot: it holds the clicks that were committed when the job was cut, minus any click deleted before its page was read. A click that arrives later is never in it. Running the same request again creates a new job with a new snapshot, and its file can differ.
Authentication and Permissions
Exports use an API key with the analytics:read or links:read scope. SDK keys are refused with 403 KEY_TYPE_FORBIDDEN, and an SDK key tied to one app is refused the same way it is on every other route. A member sees the organization's export jobs by default. Free organizations can export even when analytics is gated.
Start an Export
POST/exports
Start a click export
Starts a background job that exports click rows for the organization, or for one link. The export is a snapshot: it holds the clicks committed when the job was cut. Requires an API key with the analytics:read or links:read scope. SDK keys are refused. Poll the job with GET /exports/{id}, then download the file.
Request Body
Field
Type
Description
since*
string
Start of the window, inclusive.
until*
string
End of the window, exclusive. Must be after since.
link_id
string
Export the clicks of one link. Omit to export the whole organization.
job_id
string
A job id you generate. Repeating the request with the same id and body returns the same job.
Responses
202The job was created
Field
Type
Description
job*
object
A click export job and its manifest. The same object is returned when the job is created, while it runs, and after it completes.
400Invalid request, including a body that is not valid JSON
Field
Type
Description
error*
object
401Unauthorized
Field
Type
Description
error*
object
403Forbidden
Field
Type
Description
error*
object
404Not found
Field
Type
Description
error*
object
409The job_id was already used for a different request (code EXPORT_JOB_ID_CONFLICT), the organization already has an export running (code EXPORT_IN_PROGRESS), or its stored exports are at their size limit (code EXPORT_QUOTA_EXCEEDED)
Field
Type
Description
error*
object
422No part of the requested window is within your plan's data retention (code RETENTION_WINDOW_UNAVAILABLE). No job is created.
Field
Type
Description
error*
object
503Exports are not available yet (code EXPORTS_UNAVAILABLE). Retry later.
Field
Type
Description
error*
object
The window is clipped once to your plan's data retention, and the response shows the window that was actually exported in window_from and window_to. A window that lies wholly before your plan's retention has nothing to export: the request returns 422 RETENTION_WINDOW_UNAVAILABLE and creates no job. Send your own job_id to make the request safe to repeat: the same id with the same body returns the same job, and the same id with a different body returns 409 EXPORT_JOB_ID_CONFLICT.
An organization has one export in flight at a time. While a job is created, cut or running, starting another returns 409 EXPORT_IN_PROGRESS; start the next one after the first is complete or failed. An organization whose unexpired exports already hold 10 GB of stored files gets 409 EXPORT_QUOTA_EXCEEDED until older exports expire. Neither refusal creates a job.
Get an Export
GET/exports/{id}
Get an export job
Returns the job status and manifest. A job that does not exist and a job in another organization both return 404.
Parameters
Name
Type
In
Description
id*
string
path
Responses
200The export job
Field
Type
Description
job*
object
A click export job and its manifest. The same object is returned when the job is created, while it runs, and after it completes.
400Invalid ID
Field
Type
Description
error*
object
401Unauthorized
Field
Type
Description
error*
object
403Forbidden
Field
Type
Description
error*
object
404Not found
Field
Type
Description
error*
object
503Exports are not available yet (code EXPORTS_UNAVAILABLE). Retry later.
Field
Type
Description
error*
object
A job moves through created, cut, running, and then complete or failed. There is no expired status: a job is expired once expires_at has passed. A job that does not exist and a job in another organization both return 404.
Download an Export
GET/exports/{id}/download
Download an export file
Streams the CSV file of a complete export. Every download returns identical bytes. The error body of a refusal carries the manifest in details.manifest. A job past its expires_at returns 410 whatever its status.
Parameters
Name
Type
In
Description
id*
string
path
Responses
200The CSV file400Invalid ID
Field
Type
Description
error*
object
401Unauthorized
Field
Type
Description
error*
object
403Forbidden
Field
Type
Description
error*
object
404Not found
Field
Type
Description
error*
object
409The export failed (code export_failed) or is not ready yet (code export_not_ready)
Field
Type
Description
error*
object
410The export has expired (code export_expired)
Field
Type
Description
error*
object
503The stored file is temporarily unavailable, or exports are not available yet (code EXPORTS_UNAVAILABLE). Retry.
Field
Type
Description
error*
object
Downloads follow one rule, checked in this order:
Condition
Response
expires_at has passed, whatever the status
410 export_expired with the manifest
The job failed
409 export_failed with the manifest
The job is not complete yet
409 export_not_ready
The job is complete and unexpired
200 with the CSV file
Every download of a complete job returns identical bytes. The ETag header and the manifest sha256 are the SHA-256 of the whole file.