Management API
A JSON over HTTPS API for everything outside the object data path. Base URL: https://api.tcnstorage.store/v1.
Overview
- Authenticate with
Authorization: Bearer <token>. - List endpoints are paginated with
limit(max 200) and an opaquecursor. - Mutating requests accept an
Idempotency-Keyheader, remembered for 24 hours. - Rate limits are returned in
RateLimit-Limit,RateLimit-RemainingandRateLimit-Reset. See limits.
| Method | Path | Description |
|---|---|---|
| GET | /v1/buckets | List buckets in the workspace |
| POST | /v1/buckets | Create a bucket |
| GET | /v1/buckets/{name} | Get bucket settings |
| PATCH | /v1/buckets/{name} | Update versioning, edge or lifecycle |
| DELETE | /v1/buckets/{name} | Delete an empty bucket |
| GET | /v1/keys | List access keys |
| POST | /v1/keys | Create a scoped access key |
| DELETE | /v1/keys/{id} | Revoke an access key |
| POST | /v1/edge/purge | Purge cached objects |
| POST | /v1/buckets/{name}/notifications | Subscribe a webhook |
| GET | /v1/usage | Usage for a billing period |
Create a bucket
POST /v1/buckets HTTP/1.1
Host: api.tcnstorage.store
Authorization: Bearer tcn_live_4f9c2e7a1b8d
Content-Type: application/json
Idempotency-Key: 7d1f0c9e-2b4a-4e61-9a55-3c8e1f6b2d40
{"name":"media-assets","region":"fra1","versioning":true}{
"name": "media-assets",
"region": "fra1",
"versioning": "enabled",
"object_lock": false,
"edge": { "enabled": false, "hostname": "media-assets.cdn.tcnstorage.store" },
"created_at": "2026-09-14T10:22:31Z"
}Create a scoped access key
{
"name": "ci-uploader",
"scopes": [
{ "bucket": "build-artifacts", "prefix": "releases/", "actions": ["put", "list"] }
],
"expires_at": "2026-12-31T23:59:59Z"
}{
"id": "key_01J8ZQ4N2V7R",
"access_key_id": "TCNK3H8W5P1LEXAMPLE",
"secret_access_key": "shown only in this response",
"expires_at": "2026-12-31T23:59:59Z"
}Purge edge cache
Purge by exact URLs (up to 1 000 per request), by prefixes (up to 50) or by cache tags (up to 100). Purges complete across all PoPs in under two seconds.
Request
{
"bucket": "media-assets",
"urls": ["https://media-assets.cdn.tcnstorage.store/2026/poster.jpg"],
"tags": ["campaign-autumn"]
}Event notifications
Webhooks receive a POST for each matching event. Verify the TCN-Signature header, an HMAC-SHA256 of the raw body with your endpoint secret. Failed deliveries are retried for 24 hours with exponential backoff.
Delivery payload
{
"id": "evt_01J8ZR9D3K6M",
"type": "object.created",
"bucket": "media-assets",
"region": "fra1",
"object": { "key": "2026/poster.jpg", "size": 482113, "etag": "\"9b2cf535f27731c974343645a3985328\"" },
"occurred_at": "2026-09-14T10:24:08Z"
}Errors
Management API errors use a single JSON shape and a stable code. Include request_id when contacting support.
429 Too Many Requests
{
"error": {
"code": "rate_limited",
"message": "Rate limit of 1200 requests per minute exceeded.",
"request_id": "req_7Hq2Zt9LbX4p",
"retry_after": 12
}
}| HTTP | code | Meaning |
|---|---|---|
| 400 | invalid_request | Malformed JSON or a failed validation rule. |
| 401 | unauthenticated | Missing, expired or revoked token. |
| 403 | forbidden | The token scope does not allow this action. |
| 404 | not_found | The resource does not exist in this workspace. |
| 409 | conflict | Name taken or state conflict, e.g. deleting a non-empty bucket. |
| 422 | quota_exceeded | A workspace quota would be exceeded. |
| 429 | rate_limited | Too many requests. Wait for retry_after seconds. |
| 500 | internal | Unexpected error. Safe to retry idempotent requests. |
S3 API error codes are listed on the limits and errors page.