---
title: "Create a storage destination"
method: POST
path: "/v1/storage-destinations"
tags: ["Storage"]
---

# Create a storage destination

`POST /v1/storage-destinations`

## Request

- Base URL: `https://api-eu.dynamicdocumentapi.com`
- URL: `https://api-eu.dynamicdocumentapi.com/v1/storage-destinations`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-API-Key`

`credentials` are encrypted at rest and never returned; reads answer `{"configured": true}`. Reference the destination from `delivery.storage[]` on a render. On Amazon S3, `config.storage_class` sets the class of every uploaded object and of the connection test's probe: `STANDARD`, `STANDARD_IA`, `ONEZONE_IA`, `INTELLIGENT_TIERING` or `GLACIER_IR`; leave it out for the bucket's default. Archive classes (`GLACIER`, `DEEP_ARCHIVE`) and classes on other providers answer `400`. `config.force_path_style` (S3 and S3-compatible) puts the bucket in the path (`true`, `<endpoint>/<bucket>/<key>`) or in the host name (`false`, `<bucket>.<endpoint host>`); left out, it is `false` for Amazon S3 and `true` for S3-compatible services. Bucket names with dots, underscores or capitals and IP-address endpoints always use the path. Uploaded objects get the file's content type.

## Headers

- `Idempotency-Key` string

## Request body

- StorageDestinationWrite
  - `config` object, required
  - `credentials` object: Never returned again; send it only when it changes.
  - `is_default` boolean
  - `keep_hosted_copy` boolean
  - `name` string, required
  - `path_template` string
  - `provider` 's3' | 's3_compatible' | 'azure_blob' | 'gcs' | 'sftp', required: * `s3` - Amazon S3 * `s3_compatible` - S3-compatible * `azure_blob` - Azure Blob Storage * `gcs` - Google Cloud Storage * `sftp` - SFTP

## Response `201`

- StorageDestination
  - `config` object, required: Provider settings: bucket, region, endpoint, prefix, …; for SFTP host, port, username, prefix and host_key.
  - `created_at` string, date-time, required
  - `credentials` object, required: Write-only: reads return `{"configured": true|false}`.
  - `id` string, required: `dst_…`
  - `is_default` boolean, required
  - `keep_hosted_copy` boolean, required
  - `last_test` StorageLastTest, required
    - `at` string, date-time, nullable, required
    - `error` string, nullable, required
    - `status` 'succeeded' | 'failed' | 'null', nullable, required: * `succeeded` - succeeded * `failed` - failed
  - `name` string, required
  - `object` string
  - `path_template` string, required: Jinja path for uploaded files.
  - `provider` 's3' | 's3_compatible' | 'azure_blob' | 'gcs' | 'sftp', required: * `s3` - Amazon S3 * `s3_compatible` - S3-compatible * `azure_blob` - Azure Blob Storage * `gcs` - Google Cloud Storage * `sftp` - SFTP
  - `updated_at` string, date-time, required

## Other responses

- `400`: Invalid request body (`errors[]` with JSON pointers).
- `401`: Missing, invalid, expired or revoked credentials.
- `403`: Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `429`: Rate limited (`Retry-After`).
- `503`: The control plane is unreachable (`Retry-After`).

---

[API](https://skmtc.dev/dynamicdocumentapi/apis/dynamic-document-api.md) · [All operations](https://skmtc.dev/dynamicdocumentapi/apis/dynamic-document-api/llms.txt) · [OpenAPI document](https://skmtc.dev/dynamicdocumentapi/apis/dynamic-document-api/revisions/0f14bc0000f4?raw)
