---
title: "Export dataset rows"
method: POST
path: "/v1/projects/{projectSlug}/datasets/{datasetSlug}/rows/export"
tags: ["Datasets"]
---

# Export dataset rows

`POST /v1/projects/{projectSlug}/datasets/{datasetSlug}/rows/export`

Exports the selected rows as CSV. Returns one of three outcomes, discriminated by `status`:

- `"ready"` — the export fit in the synchronous path. Body carries a short-lived signed `downloadUrl` the caller follows with a plain HTTP GET.
- `"queued"` — the export was too large for the synchronous path AND a `recipient` was supplied. The CSV will be emailed to that address. The recipient must be a member of the requesting organization.
- `"too_large"` — the export was too large for the synchronous path AND no `recipient` was supplied. Body includes a `recommendedAction` describing how to recover (typically: ask the user for an email and retry with `recipient` set).

## Path parameters

- `projectSlug` string, required — Project slug (human-readable identifier)
- `datasetSlug` string, required — Dataset slug (human-readable identifier within the project).

## Request body

- ExportDatasetRowsBody
  - `selection` union — Rows to export. Defaults to `{ mode: "all" }` when omitted.
    - object
      - `mode` 'selected', required
      - `rowIds` string[], required
    - object
      - `mode` 'all', required
    - object
      - `mode` 'allExcept', required
      - `rowIds` string[], required
  - `recipient` string, email — Email address to send the download link to when the export is too large for the synchronous path. Must belong to a member of the requesting organization. Ignored when the export fits the synchronous path; required for the async email flow.

## Response `200`

CSV ready at the signed URL

- ExportDatasetRowsReadyResponse
  - `status` 'ready', required — Always `"ready"`. The CSV is available at `downloadUrl`.
  - `downloadUrl` string, required — Short-lived signed URL pointing to the CSV in object storage. Follow it with a plain HTTP GET.
  - `filename` string, required — Suggested filename for the downloaded CSV.
  - `expiresAt` string, required — ISO-8601 timestamp at which `downloadUrl` stops working.
  - `rowCount` integer, required — Number of rows included in the export.

## Other responses

- `202` — Export queued; download link will be emailed
- `400` — Validation error
- `401` — Unauthorized
- `404` — Not found
- `413` — Export exceeds the synchronous threshold and no `recipient` was provided
- `429` — Export rate limit exceeded

## Changes

- **2026-07-24** `b1124fb6b4f2` — 1 info
  - added the non-success response with the status `429`
- **2026-06-02** `4e09c5b2704f` — 5 info
  - the request property `recipient` became optional
  - added the non-success response with the status `413`
  - added the required property `recipient` to the response with the `202` status
  - added the required property `rowCount` to the response with the `202` status
  - …1 more
- **2026-05-19** `f42a1fb46380` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/latitude-dev/apis/latitude/changes/v1/projects/:projectSlug/datasets/:datasetSlug/rows/export/post.md)

---

[API](https://skmtc.dev/latitude-dev/apis/latitude.md) · [All operations](https://skmtc.dev/latitude-dev/apis/latitude/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/latitude-dev/latitude/revisions/a0bf72a85607/schema)
