# Exports

An export is not a SQL dump. It is a bundle that **boots**: the database
archive, storage objects, auth users, and policies, rendered as a Docker
Compose project or Kustomize manifests, with a manifest of SHA-256 digests over
every artifact and an optional HMAC-SHA256 signature — so you can verify the bundle before
you trust it.

---

## POST /v1/organizations/{org}/projects/{project}/environments/{env}/exports

Queues a bundle for the environment. The export worker dumps, packs and
boot-checks it in the background; poll
`GET /v1/organizations/{org}/exports/{export_id}` until `state` is `available`.

| Field | Type | Notes |
|---|---|---|
| `format` | `"compose"` or `"kustomize"` | Render target for the bundle (default `compose`) |
| `include_data` | boolean | Include table data in the database archive (default `true`) |
| `include_storage` | boolean | Include storage objects (default `true`) |

```sh
curl -X POST "$SCRIBASE_API_URL/v1/organizations/acme/projects/store/environments/production/exports" \
  -H "Authorization: Bearer $SCRIBASE_ACCESS_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{"format": "compose"}'
```

**Response:** the export record, in state `requested`:

```json
{
  "export_id": "ex-3f9a1c2b7d4e5f60",
  "project": { "organization_id": "acme", "project_id": "store" },
  "source_environment_id": "production",
  "state": "requested",
  "format": "compose",
  "include_data": true,
  "include_storage": true,
  "created_at_epoch_seconds": 1790125000,
  "total_size_bytes": 0,
  "sha256": "",
  "postgres_major": 0,
  "artifacts": [],
  "boots_elsewhere": false,
  "storage_object_count": 0
}
```

`state` moves through `requested`, `packing` and `verifying` to `available`
(or `failed`, with an `error`). An available export also carries
`expires_at_epoch_seconds` and a signed `download_url`.

## POST /v1/organizations/{org}/projects/{project}/export

The project-scoped form. Name the source environment in the body:

```json
{ "source_environment_id": "production", "format": "kustomize" }
```

`format` defaults to `compose`.

## GET /v1/organizations/{org}/projects/{project}/exports

The project's persisted export manifests as `{"items": [...]}`.

## GET /v1/organizations/{org}/exports

Every export in the organization, newest first, as `{"items": [...]}`.

## GET /v1/organizations/{org}/exports/{export_id}

One export record. Once `state` is `available` it includes `download_url`, a
short-lived signed link.

## GET /v1/organizations/{org}/exports/{export_id}/download?expires=...&signature=...

Streams the gzip bundle. The link carries its own authorization (an HMAC over
the organization, export and expiry), so it needs no bearer header; request a
fresh one with the route above when it expires.

---

## CLI

```sh
scribase export create acme store production --format compose --wait --out store.tar.gz
scribase export list acme store
scribase export download acme ex-3f9a1c2b7d4e5f60 --out store.tar.gz
```

See [`scribase export`](https://docs.scribase.com/docs/cli/export.md).

## SDK

```ts
const { manifest } = await scribase.export.create(
  { organizationId: 'acme', projectId: 'store', environmentId: 'production' },
  { format: 'compose' },
);
```
