# Start an upload

> Open a resumable upload for a zip or an asset.

`POST https://api.codebuckets.clatterlabs.xyz/v1/buckets/{bucket_id}/uploads` (key permission: `buckets:write`)

Reserves space in the bucket and returns the upload with its chunk layout. Send the file as `chunk_count` chunks of `chunk_size` bytes (the last one is shorter) with [Upload a chunk](/api-reference/code-buckets/uploads/chunk), then [complete the upload](/api-reference/code-buckets/uploads/complete).

## Authorizations

- `Authorization` (string, required): Your API key as a bearer token: `Bearer clsk_...`. Create keys in the [Console](https://console.clatterlabs.com/api-keys) with the Code Buckets permissions you need.
- `X-Clatter-Account` (string, required): The Account ID that owns the key, like `CL-7K2M9QXA`. Find it in Console › Settings. A missing value answers `401 missing_account_id`; someone else's answers `401 account_mismatch`.

## Path parameters

- `bucket_id` (string, required): The bucket id (`cbk_…`).

## Body

- `name` (string, required): The file name, like `storefront.zip` (no slashes, up to 255 characters).
- `size` (integer, required): The exact file size in bytes.
- `kind` (string): `archive` or `asset`. Defaults to `archive` for `.zip` names, `asset` otherwise.
- `target_path` (string): Archives only: unpack into this folder (like `packages/api`) and keep the rest of the tree. Omit to replace the whole tree.
- `content_type` (string): MIME type returned on download.
- `visibility` (string): `inherit` (default: follow the bucket), `private` or `public`. Pass `public` to get a public link as soon as the upload completes.

## Response

- `object` (string): `upload` while it's being uploaded, then `object`.
- `id` (string): The upload id, which is also the stored object's id (`cbo_…`).
- `bucket_id` (string): The bucket it belongs to.
- `kind` (string): `archive` (a zip of code) or `asset` (any other file).
- `name` (string): The file name.
- `target_path` (string): Archives only: the folder the zip is unpacked into (`""` = the whole tree).
- `size` (integer): Size in bytes.
- `chunk_size` (integer): Bytes per chunk: 16,777,216 (16 MiB).
- `chunk_count` (integer): How many chunks the file has.
- `status` (string): `uploading`, `processing` (building the preview), `ready` or `failed`.
- `received_chunks` (integer[]): While `uploading`: the chunk indexes already stored. Upload only the missing ones to resume.
- `preview` (object): Archives only: `{ status, files, skipped, skipped_examples, stripped_folder, ms }`. `status` is `pending`, `extracting`, `ready`, `partial`, `failed` or `off`; `ms` is how long building the preview took, in milliseconds.
- `visibility` (string): The file's own setting: `inherit` (default: follow the bucket), `private` or `public`.
- `effective_visibility` (string): What applies now: `private` or `public` (the file's setting, or the bucket's when it's `inherit`).
- `public_url` (string | null): The file's public link while it's public and stored, `null` otherwise. Images (`image/*`) get `https://img.cdn.clatterlabs.xyz/<id>`; everything else `https://files.cdn-buckets.clatterlabs.xyz/<object_id>/<name>`. See [Public files](/code-buckets/public-files).
- `served_as` (string): `image` (public link on img.cdn.clatterlabs.xyz, cached for a year) or `file` (files.cdn-buckets.clatterlabs.xyz).
- `encrypted` (boolean): Always `true`.
- `created_at / completed_at` (string): ISO 8601 timestamps.

## Example request

```bash
curl -X POST "https://api.codebuckets.clatterlabs.xyz/v1/buckets/BUCKET_ID/uploads" \
  -H "Authorization: Bearer $CLATTER_API_KEY" \
  -H "X-Clatter-Account: $CLATTER_ACCOUNT_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "storefront.zip",
    "size": 131204115
  }'
```

## Errors

| Status | Code | When |
| --- | --- | --- |
| `400` | `bad_request` | A field is missing or invalid. |
| `401` | `invalid_api_key / missing_account_id / account_mismatch` | The key or Account ID is wrong. |
| `402` | `quota_exceeded` | This month's free tokens are used up. |
| `403` | `insufficient_scope` | The key lacks the permission. |
| `404` | `not_found` | No bucket with that id on your account. |
| `413` | `bucket_full` | The upload would take the bucket past 10 GB (counting unfinished uploads). |
| `503` | `storage_unavailable` | Try again. |

## Example response

```json
{
  "object": "upload",
  "id": "cbo_m2n8b4v6c1x9z3l7k5j0",
  "bucket_id": "cbk_q7c1r9t2y6u0i3o8p5a4",
  "kind": "archive",
  "name": "storefront.zip",
  "target_path": "",
  "content_type": "application/zip",
  "size": 131204115,
  "chunk_size": 16777216,
  "chunk_count": 8,
  "status": "uploading",
  "received_chunks": [],
  "preview": {
    "status": "pending"
  },
  "visibility": "inherit",
  "effective_visibility": "private",
  "public_url": null,
  "served_as": "file",
  "encrypted": true,
  "created_at": "2026-10-28T14:05:11.482Z",
  "completed_at": null
}
```


