---
title: "Create Vena Table Export"
method: POST
path: "/exports"
tags: ["Vena tables [Beta]"]
---

# Create Vena Table Export

`POST /exports`

## Request

- Base URL: `https://us1.vena.io/api/public/v1`
- URL: `https://us1.vena.io/api/public/v1/exports`
- Auth: HTTP basic
- TypeScript: <https://skmtc.dev/venasolutions/apis/vena-api/docs/exports/post.ts> (a function with typed inputs; its response is checked against the schema)

**Beta.** Submits an asynchronous Vena Table snapshot export job and returns immediately with status `SUBMITTED`. Poll `GET /exports/{exportId}/status` until `COMPLETED` before calling `GET /exports/{exportId}/data`.

The create response uses `id` (not `exportId`) and returns a **flat** export resource rebuilt from the persisted job/step (`exportType`, `modelId`, `tableId`, `whereClause`, `columnNames`, timestamps). It does **not** echo a nested `request` object. `errorReason` is omitted on create (`status` is always `SUBMITTED`).

**Row cap:** A single export job can contain at most **20,000,000** rows. Create runs a pre-flight COUNT; if the result would exceed the cap, the API returns `400 EXPORT_ROW_LIMIT_EXCEEDED` and does **not** enqueue a job. Use `whereClause` to narrow the result set. A **zero-row** result is allowed — the job is enqueued and `/data` returns an empty page after `COMPLETED`.

**TTL:** `expiresTime` is `createdTime` + 24 hours.

**Not-found on create** uses HTTP **400** (`INVALID_PARAMETER` on `modelId` / `tableId`), not 404. True HTTP 404 (`NOT_FOUND` / `EXPORT_EXPIRED`) applies to status and data endpoints.

**exportType** must be the exact token `VENA_TABLE` (case-sensitive, no surrounding whitespace). Blank, unknown, lowercase, or padded values return `400 INVALID_PARAMETER`.

Unknown JSON properties on the request body are **ignored** (forwards-compatible).

## Request body

- CreateVenaTableExportRequest
  - `exportType` 'VENA_TABLE', required: Export pipeline selector. v1 accepts the exact token `VENA_TABLE` only (case-sensitive, no surrounding whitespace). Blank, unknown, lowercase (`vena_table`), or padded (` VENA_TABLE `) values deserialize as missing and return `400 INVALID_PARAMETER` (`exportType must be VENA_TABLE.`).
  - `modelId` string, required: Model ID (JSON string Id)
  - `tableId` string, required: Vena Table ID on the given model (JSON string Id)
  - `whereClause` string, required: Required VenaQL WHERE filter to scope the export and stay within the **20,000,000-row** snapshot cap. - Missing / null → `400 INVALID_PARAMETER` - Empty string (`""`) → export all permitted rows (small tables only) - Non-empty → must be valid VenaQL (validated at create time) **NULL checks — use `IS NULL` / `IS NOT NULL`:** Comparisons with `=` / `!=` against `NULL` evaluate to UNKNOWN and can silently return 0 rows even when syntax validation passes. | Avoid | Use instead | |---|---| | `Field = null` | `Field IS NULL` | | `Field != null` | `Field IS NOT NULL` | | `Field NOT IN ('a', null)` | `Field NOT IN ('a', 'b') AND Field IS NOT NULL` | | `Field BETWEEN null AND 100` | `Field <= 100` | **Always quote string literals** (`Field = 'yes'`, not `Field = yes`). Vena Table cells are stored as strings — prefer `Field = '123'` over `Field = 123`. **LIKE:** escape literal `%` / `_` when needed (`Field LIKE '10\_000' ESCAPE '\\'`).
  - `columnNames` string[], nullable: Optional column subset. Omitted or empty = all columns on the table. Each name must exist on the table.

## Response `200`

Export job accepted and enqueued. Body is a flat export resource: `id`, `status=SUBMITTED`, `exportType`, `modelId`, `tableId`, `whereClause`, `columnNames`, and timestamps. Poll status before fetching data.

- CreateVenaTableExportResponse: Public export resource rebuilt from the persisted job/step (not a nested echo of the create body). Same shape is intended for a future GET /exports/{exportId}. `errorReason` is present only when status is ERROR (create always returns SUBMITTED, so it is omitted).
  - `id` string, required: Export job ID. Use this in GET /exports/{exportId}/status and /data.
  - `status` 'SUBMITTED', required: Initial job status on create — always SUBMITTED
  - `exportType` 'VENA_TABLE', required: Export pipeline type
  - `modelId` string, required: Model id for this export
  - `tableId` string, required: Vena Table source id
  - `whereClause` string: Filter applied when building the snapshot (may be empty)
  - `columnNames` string[]: Resolved columns included in the snapshot
  - `createdTime` string, date-time, required
  - `expiresTime` string, date-time, required: Absolute expiration instant. Equals createdTime + snapshot TTL (typically 24 hours).
  - `errorReason` string: Present only when status is ERROR — user-facing summary from the ETL job short message

## Other responses

- `400`: Validation or domain reject. Missing model/table are HTTP **400** `INVALID_PARAMETER` (with `param.path` of `modelId` or `tableId`), not 404. Also covers invalid `exportType`, `whereClause`, `columnNames`, and `EXPORT_ROW_LIMIT_EXCEEDED`. Zero-row filters are **not** rejected (no EXPORT_NO_DATA).
- `401`: Invalid authentication credentials
- `403`: Authenticated user does not have access to the model/table. Variants: forbiddenModel.
- `422`: The Public Export API feature is not enabled for this customer.
- `429`: Too many requests, please try again later

## Changes

- **2026-11-03** `587671c855dd`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/venasolutions/apis/vena-api/changes/exports/post.md)

---

[API](https://skmtc.dev/venasolutions/apis/vena-api.md) - [All operations](https://skmtc.dev/venasolutions/apis/vena-api/llms.txt) - [OpenAPI document](https://skmtc.dev/venasolutions/apis/vena-api/revisions/587671c855dd?raw)
