Skip to main content

Evidence exports

An export gives your compliance team a file of acceptance records for a period, for an audit, a dispute or a regulator. You create an export with a filter, Propper freezes the matching records at that moment, and you download the result as a CSV or JSONL file.

Every call needs a click:export token. The scope is standalone: click:admin, click:write and click:read do not include it, so request it explicitly (see OAuth scopes). A user token carries it only when the user's role can export evidence.

ResourcePurpose
POST /v1/click/exportsCreate an export.
GET /v1/click/exportsList your organization's exports, newest first.
GET /v1/click/exports/{id}Read an export's status, counts and file list.
GET /v1/click/exports/{id}/files/{name}Download one file.
DELETE /v1/click/exports/{id}Delete an export. Its files then answer 410.

The base path is https://api.propper.ai/v1/click/exports.

Create an export​

curl -X POST https://api.propper.ai/v1/click/exports \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: 5b0f6c1e-0d2a-4c53-9e0f-3f6c2a7d1b10" \
-d '{
"format": "csv",
"filters": {
"from": "2026-01-01T00:00:00Z",
"to": "2026-10-01T00:00:00Z",
"environment": "PRODUCTION",
"outcome": "ACCEPTED"
}
}'
FieldDescription
formatRequired. csv or jsonl.
filters.from, toRequired, inclusive, at most 366 days apart.
filters.templateIdOnly acceptances of this template.
filters.versionIdOnly acceptances of this template version. With templateId, the version must belong to that template.
filters.environmentPRODUCTION or SANDBOX.
filters.outcomeACCEPTED, DECLINED or EXPIRED.
filters.signerRefOnly acceptances by this signer, an exact match on the reference you sent when recording them.
restrictedAccessOptional { "reason", "claimRef" }. Includes records under a legal restriction. See below.
includeEvidenceNot available yet. Sending true is a 400 CLICK_VALIDATION_FAILED.

The filter list is closed. An unknown key, including q, is a 400 CLICK_VALIDATION_FAILED.

Send signerRef in the body

A signerRef filter goes in the POST body and nowhere else. A query string reaches load-balancer and proxy logs, so a signer reference there would be written to logs outside Propper's control. The export is frozen to the matching acceptances when it is created and the reference is then discarded: the export stores only that a signer filter was used, and never returns the value.

Restricted records​

Without restrictedAccess, records under a legal restriction are left out, and counts.restrictedExcluded says how many. To include them, send a reason (DISPUTE_DEFENSE, DISPUTE_ESTABLISH, COURT_ORDER or REGULATOR_REQUEST) and a claimRef, an identifier for the matter of 1 to 128 letters, digits and . _ : / -, starting with a letter or digit. Free text in either field is a 400. Both are recorded in the audit log.

The response​

The API answers 202 Accepted with a Location: /v1/click/exports/{id} header and the job:

{
"data": {
"id": "0d3b6f0a-5f2e-4a5c-9a38-2c1e7b4d9f10",
"status": "READY",
"format": "csv",
"includeEvidence": false,
"filters": {
"from": "2026-01-01T00:00:00Z",
"to": "2026-10-01T00:00:00Z",
"environment": "PRODUCTION",
"outcome": "ACCEPTED"
},
"asOf": "2026-10-29T17:02:11Z",
"rowCount": 1240,
"counts": { "accepted": 1240, "declined": 0, "expired": 0, "restrictedExcluded": 0 },
"files": [{ "name": "rows.csv", "contentType": "text/csv", "rows": 1240 }],
"createdAt": "2026-10-29T17:02:11Z",
"expiresAt": "2026-11-05T17:02:11Z"
}
}

asOf is the moment the records were frozen: acceptances recorded later are not in the export. Send an X-Idempotency-Key so a retry after a timeout returns the same export instead of creating a second one. The key is scoped to your client and the request body, so it cannot replay another client's export.

Status values​

StatusMeaning
PENDINGAccepted, not started.
PROCESSINGBeing prepared.
READYFiles can be downloaded.
FAILEDCould not be prepared. Create a new export.
EXPIREDPast expiresAt. Files answer 410.
DELETEDDeleted with DELETE. Files answer 410.
VOIDEDWithdrawn because a signer it covers was erased. Files answer 410.

An export is usually READY in the create response. Poll GET /v1/click/exports/{id} until status is READY anyway, so your integration keeps working if preparation becomes asynchronous.

Download a file​

curl -OJ https://api.propper.ai/v1/click/exports/0d3b6f0a-5f2e-4a5c-9a38-2c1e7b4d9f10/files/rows.csv \
-H "Authorization: Bearer $TOKEN"

files in the job lists the file names to ask for. The body is streamed, never a link, so your token is checked on every download. The response carries:

HeaderValue
Content-Typetext/csv; charset=utf-8 or application/x-ndjson; charset=utf-8
Content-Dispositionattachment; filename="click-export-<id>-rows.csv" (.jsonl for JSONL)
X-Export-RowsThe number of records in the file, frozen at create time.
Cache-Controlprivate, no-store

Check the download is whole before you rely on it:

  • A failure after the first byte closes the connection instead of ending the body cleanly, so a short or broken download is always an error in your HTTP client, never a file that looks complete.
  • A JSONL file ends with a line {"type":"end","rows":N}. Count the record lines and compare with N and X-Export-Rows.
  • A CSV file has one header line followed by X-Export-Rows records.

Row columns​

CSV columns and JSONL keys are the same, in this order.

ColumnContents
acceptanceId, receiptIdThe acceptance and its receipt.
outcome, acceptedAt, startedAtWhat the signer did and when.
templateId, templateName, versionId, version, versionLabel, revisionId, revisionNumber, deploymentId, environmentThe agreement that was served.
locale, consentMethod, evidenceTier, deviceClassHow the acceptance was made.
signerRefThe signer reference you sent. erased: followed by 16 hex characters after an erasure.
emailEmpty for acceptances recorded before email was captured. Pseudonymized after an erasure.
ipAddressThe signer's address. 0.0.0.0 after an erasure.
identityErasedtrue once the signer's identity was erased.
restrictedtrue for a record under a legal restriction (only present when you asked for those).
formatVersion, servedChecksum, resolvedSettingsHash, chainSequence, previousChainHash, chainHash, signatureAlgorithm, signatureKeyId, signatureThe tamper-evident chain and signature of the evidence bundle.
evidenceStatusState of the evidence bundle when the export was created.
evidenceFilesnot_exported_v1 for now: evidence files are not part of an export yet.
screenshotEmpty for now. Later sealed for acceptances that have a screenshot, which is never included in an export.
consentChoicesThe choices the signer made, as a list.

The export never contains the raw user agent, merge data, captured page HTML or debug logs. A CSV cell that starts with =, +, -, @, a tab or a carriage return is prefixed so a spreadsheet does not run it as a formula. JSONL values are not altered.

Delete an export​

DELETE /v1/click/exports/{id} answers 204. It clears the stored filters at once, and every file of the export then answers 410 CLICK_EXPORT_GONE. Exports are deleted for you 7 days after they were created.

Errors​

Errors use the standard body.

StatuserrorCodeWhen
400CLICK_VALIDATION_FAILEDAn unknown or invalid filter, q, a window over 366 days, free text in restrictedAccess, or includeEvidence: true.
401No or invalid token.
403The token does not carry click:export.
404CLICK_NOT_FOUNDThe export, template or version is not your organization's, or the file name is not one of files.
409CLICK_EXPORT_NOT_READYA file was requested before the export was READY.
410CLICK_EXPORT_GONEThe export expired, was deleted or was voided.
422CLICK_EXPORT_TOO_LARGEThe filter matches more rows than one export allows. Narrow the window or add a filter.
429CLICK_EXPORT_LIMIT_REACHEDA concurrency, daily or per-file limit was reached. Wait for Retry-After seconds.

See Limits and retries for the values.

Not available yet​

includeEvidence (evidence files in ZIP parts alongside the rows) is not available yet. Until it is, evidenceFiles is not_exported_v1 and an export has one rows file.