---
title: "Atomically create versions for multiple tables"
method: POST
path: "/v1/table/version/batch-create"
tags: ["Table", "Metadata"]
---

# Atomically create versions for multiple tables

`POST /v1/table/version/batch-create`

Atomically create new version entries for multiple tables.

This operation is atomic: either all table versions are created successfully,
or none are created. If any version creation fails (e.g., due to conflict),
the entire batch operation fails.

Each entry in the request specifies the table identifier and version details.
This supports `put_if_not_exists` semantics for each version entry.

## Request body

- BatchCreateTableVersionsRequest — Request to atomically create new version entries for multiple tables. The operation is atomic: all versions are created or none are.
  - `identity` Identity — Identity information of a request.
    - `api_key` string — API key for authentication. REST NAMESPACE ONLY This is passed via the `x-api-key` header.
    - `auth_token` string — Bearer token for authentication. REST NAMESPACE ONLY This is passed via the `Authorization` header with the Bearer scheme (e.g., `Bearer <token>`).
  - `context` Context — Arbitrary context as key-value pairs. How to use the context is custom to the specific implementation. On a request, it carries caller-provided context to the implementation. On a response, it carries implementation-provided context back to the caller. REST NAMESPACE ONLY Context entries are mapped to and from HTTP headers using the `header.` prefix: - On a request, any entry whose key starts with `header.` is sent as an HTTP request header with the prefix stripped. For example, the entry `{"header.Authorization": "Bearer abc"}` is sent as the request header `Authorization: Bearer abc`. - On a response, every HTTP response header is returned as an entry whose key is the header name prefixed with `header.`. For example, the response header `x-request-id: abc123` is returned as the entry `{"header.x-request-id": "abc123"}`.
  - `entries` CreateTableVersionEntry[], required — List of table version entries to create atomically
    - `id` string[], required — The table identifier
    - `version` integer, required — Version number to create
    - `branch` string — Branch to target. When not specified, the main branch is used.
    - `manifest_path` string, required — Path to the manifest file for this version
    - `manifest_size` integer — Size of the manifest file in bytes
    - `e_tag` string — Optional ETag for the manifest file
    - `metadata` object — Optional metadata for the version
    - `naming_scheme` string — The naming scheme used for manifest files in the `_versions/` directory. Known values: - `V1`: `_versions/{version}.manifest` - Simple version-based naming - `V2`: `_versions/{inverted_version}.manifest` - Zero-padded, reversed version number (uses `u64::MAX - version`) for O(1) lookup of latest version on object stores V2 is preferred for new tables as it enables efficient latest-version discovery without needing to list all versions.

## Response `200`

Result of atomically creating table versions

- BatchCreateTableVersionsResponse — Response for batch creating table versions. Contains the created versions for each table in the same order as the request.
  - `context` Context — Arbitrary context as key-value pairs. How to use the context is custom to the specific implementation. On a request, it carries caller-provided context to the implementation. On a response, it carries implementation-provided context back to the caller. REST NAMESPACE ONLY Context entries are mapped to and from HTTP headers using the `header.` prefix: - On a request, any entry whose key starts with `header.` is sent as an HTTP request header with the prefix stripped. For example, the entry `{"header.Authorization": "Bearer abc"}` is sent as the request header `Authorization: Bearer abc`. - On a response, every HTTP response header is returned as an entry whose key is the header name prefixed with `header.`. For example, the response header `x-request-id: abc123` is returned as the entry `{"header.x-request-id": "abc123"}`.
  - `transaction_id` string — Optional transaction identifier
  - `versions` TableVersion[], required — List of created table versions in the same order as the request entries
    - `version` integer, required — Version number
    - `manifest_path` string, required — Path to the manifest file for this version.
    - `manifest_size` integer — Size of the manifest file in bytes
    - `e_tag` string — Optional ETag for optimistic concurrency control. Useful for S3 and similar object stores.
    - `timestamp_millis` integer — Timestamp when the version was created, in milliseconds since epoch (Unix time)
    - `metadata` object — Optional key-value pairs of metadata

## Other responses

- `400` — Indicates a bad request error. It could be caused by an unexpected request body format or other forms of request validation failure, such as invalid json. Usually serves application/json content, although in some cases simple text/plain content might be returned by the server's middleware.
- `401` — Unauthorized. The request lacks valid authentication credentials for the operation.
- `403` — Forbidden. Authenticated user does not have the necessary permissions.
- `404` — A server-side problem that means can not find the specified resource.
- `409` — The request conflicts with the current state of the target resource.
- `503` — The service is not ready to handle the request. The client should wait and retry. The service may additionally send a Retry-After header to indicate when to retry.
- `5XX` — A server-side problem that might not be addressable from the client side. Used for server 5xx errors without more specific documentation in individual routes.

---

[API](https://skmtc.net/lancedb/apis/lance-namespace-specification.md) · [All operations](https://skmtc.net/lancedb/apis/lance-namespace-specification/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/lancedb/lance-namespace-specification/versions/d5b7c114f475/schema)
