---
title: "Start a database export"
method: POST
path: "/clusters/{cluster_id}/exports"
tags: ["Exports"]
---

# Start a database export

`POST /clusters/{cluster_id}/exports`

## Request

- Base URL: `http://localhost:8000`
- URL: `http://localhost:8000/clusters/{cluster_id}/exports`
- Auth: API key in header `API-Key`

Queues a new database export for the cluster. The export is generated asynchronously;
poll `GET /clusters/{cluster_id}/exports/{export_id}` until `status` is `completed`,
then download the archive from `download_url` before `expires_at`.

When `include_credentials` is `true`, an `encryption_password` must be provided and the
resulting archive will be AES-256-CBC encrypted.

Returns `409` with code `export_already_running` if an export is already pending or
processing for this cluster. Exports older than the two-hour stale threshold do not
block new requests; age is measured from start time, or creation time if not started.

Required scope: `clusters:exports:write`

## Path parameters

- `cluster_id` string, uuid, required

## Headers

- `API-Version` '2026-06-01.beta', required

## Request body

- CreateExportRequest
  - `format` 'sql' | 'pgdump', required
  - `include_credentials` boolean: Include the Keycloak `credential` and related tables. Requires `encryption_password` to be set.
  - `encryption_password` string: Password used to encrypt the archive (AES-256-CBC, PBKDF2). Required when `include_credentials` is `true`. Never stored; only a hash is retained for verification.

## Response `202`

Returned when an export has been accepted for processing. Poll the `Location` URL until `status` is `completed` or `failed`.

- Export
  - `id` string, uuid, required
  - `cluster_id` string, uuid, required
  - `format` 'sql' | 'pgdump', required
  - `status` 'pending' | 'processing' | 'completed' | 'failed', required
  - `expires_at` string, date-time, nullable, required: When the archive will be deleted from storage.
  - `created_at` string, date-time, required
  - `started_at` string, date-time, nullable, required
  - `completed_at` string, date-time, nullable, required
  - `progress` integer, required: Completion percentage of the export job, from 0 to 100.
  - `include_credentials` boolean, required: Whether the dump includes the `credential` and related Keycloak tables.
  - `is_encrypted` boolean, required: Whether the archive is AES-256-CBC encrypted with the password provided at creation time.
  - `file_size_bytes` integer, nullable, required: Size of the produced ZIP archive in bytes. Only set once `status` is `completed`.
  - `sha256_checksum` string, nullable, required: SHA-256 checksum of the produced ZIP archive (hex). Only set once `status` is `completed`.
  - `download_url` string, uri, nullable, required: Time-limited presigned URL to download the archive. Only set when `status` is `completed` and `expires_at` is in the future. Returned URLs are valid for at least one hour.
  - `error_message` string, nullable, required: Failure description. Only set when `status` is `failed`.

## Other responses

- `400`: The server could not understand the request due to invalid syntax.
- `401`: Access is unauthorized.
- `402`: Client error
- `403`: Access is forbidden.
- `404`: The server cannot find the requested resource.
- `409`: The request conflicts with the current state of the server.
- `422`: Client error
- `429`: Client error
- `500`: Server error
- `501`: Server error

---

[API](https://skmtc.dev/skycloak/apis/skycloak-public-api.md) · [All operations](https://skmtc.dev/skycloak/apis/skycloak-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/skycloak/apis/skycloak-public-api/revisions/33a69e2ce35f?raw)
