Code Buckets
Upload a chunk
Send one 16 MiB part of the file.
Stores one chunk, encrypted. Chunk index covers bytes index × chunk_size up to the next chunk; every chunk is exactly chunk_size bytes except the last. Send chunks in any order and in parallel (up to 4 at a time works well). Sending a chunk again replaces it, so retries are safe. Chunk requests don't count toward the key's per-minute limit.
Request body: The raw chunk bytes (Content-Type: application/octet-stream). Optional header X-Content-SHA256: the chunk's SHA-256 in hex; a mismatch answers 400 checksum_mismatch.
Split a file with split -b 16777216 -d -a 5 storefront.zip part- and send part-00000, part-00001, … as chunks 0, 1, …. The Uploads guide has a full script in each language.
Authorizations
AuthorizationstringrequiredYour API key as a bearer token: Bearer clsk_.... Create keys in the Console with the Code Buckets permissions you need.
X-Clatter-AccountstringrequiredThe 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
upload_idstringrequiredThe upload id (cbo_…) from Start an upload.
indexintegerrequired0 to chunk_count - 1.
Response
200 · application/json
objectstringupload.chunk.
upload_idstringThe upload.
indexintegerThe chunk index.
sizeintegerBytes stored.
sha256stringSHA-256 of the chunk (hex).
duplicatebooleantrue when the same chunk was already stored.
Errors
| Status | Code | When |
|---|---|---|
400 | bad_chunk / bad_chunk_size / checksum_mismatch | Wrong index, wrong length, or the checksum didn't match. |
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 upload with that id on your account. |
409 | upload_closed | The upload is already complete. |
502 | storage_error | Retry the chunk. |
curl -X PUT "https://api.codebuckets.clatterlabs.xyz/v1/uploads/cbo_m2n8b4v6c1x9z3l7k5j0/chunks/0" \
-H "Authorization: Bearer $CLATTER_API_KEY" \
-H "X-Clatter-Account: $CLATTER_ACCOUNT_ID" \
-H "Content-Type: application/octet-stream" \
--data-binary @part-00000import os, requests
BASE = "https://api.codebuckets.clatterlabs.xyz"
headers = {"Authorization": f"Bearer {os.environ['CLATTER_API_KEY']}", "X-Clatter-Account": os.environ["CLATTER_ACCOUNT_ID"]}
r = requests.put(f"{BASE}/v1/uploads/cbo_m2n8b4v6c1x9z3l7k5j0/chunks/0", headers=headers, data=open("part-00000", "rb").read())
r.raise_for_status()
print(r.json())const BASE = "https://api.codebuckets.clatterlabs.xyz";
const headers = {
Authorization: `Bearer ${process.env.CLATTER_API_KEY}`,
"X-Clatter-Account": process.env.CLATTER_ACCOUNT_ID,
};
const res = await fetch(`${BASE}/v1/uploads/cbo_m2n8b4v6c1x9z3l7k5j0/chunks/0`, { method: "PUT", headers, body: await (await import("node:fs/promises")).readFile("part-00000") });
const data = await res.json();
if (!res.ok) throw new Error(data.error.message);
console.log(data);{
"object": "upload.chunk",
"upload_id": "cbo_m2n8b4v6c1x9z3l7k5j0",
"index": 0,
"size": 16777216,
"sha256": "4d9b0f3c…"
}