Skip to main content
Preview. Part of the Migration API — in active design and not yet generally available. Endpoints and payloads may change. See the overview.
GET https://app.vern.so/api/v1/companies/{id}/export.csv
Streams the company’s validated data as a CSV. This is synchronous — there’s no run to poll and no destination involved. Columns come out in template order, RFC 4180-escaped. This is the file export path: download the CSV, or relay it into your own storage bucket (below). To push rows into a destination API instead, see Export to a destination.

Authentication

Requires an x-api-key header. See Authentication.

Query parameters

sheet_id
string
Which sheet to export. Provide it to download a single sheet as .csv. Omit it to download every sheet in the workbook as a .zip. (Single-sheet CSV comes first in preview; the multi-sheet ZIP is still being built.)
filter
string
default:"valid"
valid (the default — a cleaning product shouldn’t emit dirty rows) returns only fully clean rows: any row with even one cell that failed validation is excluded entirely, so the row count can be lower than the workbook’s total. all returns every row, including those with invalid cells.

Response

200 OK. A single sheet returns Content-Type: text/csv; a whole workbook returns application/zip. Both carry a Content-Disposition attachment header, and the body is streamed.

Errors

StatusMeaning
400filter not one of valid / all.
401API key missing or invalid.
404No such sheet, or the company isn’t in your account.
429Rate limit hit — back off and retry.
500Server error.

Example

# one sheet, valid rows only (default)
curl "https://app.vern.so/api/v1/companies/c0a8012e-4f1b-4d3a-9b2c-7e6f5a4b3c2d/export.csv?sheet_id=7a1c2b3d-4e5f-4061-8a9b-0c1d2e3f4a5b" \
  -H "x-api-key: $VERN_API_KEY" \
  -o contacts-clean.csv

# whole workbook as a ZIP
curl "https://app.vern.so/api/v1/companies/c0a8012e-4f1b-4d3a-9b2c-7e6f5a4b3c2d/export.csv" \
  -H "x-api-key: $VERN_API_KEY" \
  -o acme-clean.zip

# include rows with invalid cells
curl "https://app.vern.so/api/v1/companies/c0a8012e-4f1b-4d3a-9b2c-7e6f5a4b3c2d/export.csv?sheet_id=7a1c2b3d-4e5f-4061-8a9b-0c1d2e3f4a5b&filter=all" \
  -H "x-api-key: $VERN_API_KEY" \
  -o contacts-all.csv

Into your own storage

The endpoint hands you the file in the HTTP response — Vern doesn’t push it anywhere. To land the clean CSV in your own bucket, pull it from your backend and pipe it straight into object storage. The body streams, so you never have to buffer the whole file:
# Amazon S3
curl -s "https://app.vern.so/api/v1/companies/c0a8012e-4f1b-4d3a-9b2c-7e6f5a4b3c2d/export.csv?sheet_id=7a1c2b3d-4e5f-4061-8a9b-0c1d2e3f4a5b" \
  -H "x-api-key: $VERN_API_KEY" \
  | aws s3 cp - s3://your-bucket/acme/contacts.csv

# Google Cloud Storage
curl -s "https://app.vern.so/api/v1/companies/c0a8012e-4f1b-4d3a-9b2c-7e6f5a4b3c2d/export.csv?sheet_id=7a1c2b3d-4e5f-4061-8a9b-0c1d2e3f4a5b" \
  -H "x-api-key: $VERN_API_KEY" \
  | gcloud storage cp - gs://your-bucket/acme/contacts.csv
Any S3-compatible store (R2, MinIO, Spaces) works the same way. Keep your x-api-key server-side — run this from your backend, never the browser. Vern never receives your storage credentials; your backend relays the bytes.
Prefer Vern to deliver directly into a bucket you own — via a presigned URL or stored bucket credentials — instead of relaying it yourself? That’s not available today. Tell us at vish@vern.so if you’d use it.

Next