Koo Docs
View as Markdown

Uploads

Presign a media upload

POST/accounts/{accountId}/uploads/presign
Rolesreadereditoradminowner

Validate scope/type/size + target ownership and return a short-lived presigned PUT URL plus the eventual CDN URL. The `accountAvatar` and `accountBanner` scopes additionally require the admin role.

Parameters
accountIdstringpathrequired
Request body
scope"accountAvatar" | "accountBanner" | "appImage"required

Which media slot is being uploaded; resolves to a server-owned key prefix.

contentTypestringrequired

The exact Content-Type the client will PUT (signed into the URL).

sizeBytesintegerrequired

Byte size of the file; checked against the scope cap.

sha256stringrequired
targetIdstring

The owning entity id (publishedAppId for appImage).

Returns
200 · PresignUploadResultDto
uploadUrlstring <uri>read-only

Presigned PUT URL — the client uploads the bytes directly here.

keystringread-only

Server-issued object key; pass it back verbatim to commit.

finalUrlstring <uri>read-only

The CDN URL the object will be delivered from after commit.

expiresAtstring <date-time>read-only

When the presigned upload URL expires.

cURL
POST /accounts/{accountId}/uploads/presign
bash
curl https://api.koo.io/accounts/:accountId/uploads/presign \  -X POST \  -H "Authorization: Bearer kc_your_api_token" \  -H "Content-Type: application/json" \  -d '{      "scope": "accountAvatar",      "contentType": "example",      "sizeBytes": 0,      "sha256": "example"    }'
Response
json
{  "uploadUrl": "https://example.com",  "key": "example",  "finalUrl": "https://example.com",  "expiresAt": "2026-01-01T00:00:00.000Z"}

Commit a media upload

POST/accounts/{accountId}/uploads/commit
Rolesreadereditoradminowner

HEAD-verify the uploaded object and write its CDN URL onto the target entity. Rejects any key outside the requester’s scope. The `accountAvatar` and `accountBanner` scopes additionally require the admin role.

Parameters
accountIdstringpathrequired
Request body
keystringrequired

The key returned by presign.

scope"accountAvatar" | "accountBanner" | "appImage"required

Which media slot is being uploaded; resolves to a server-owned key prefix.

Returns
200 · CommitUploadResultDto
finalUrlstring <uri>read-only

The committed CDN URL written to the entity.

cURL
POST /accounts/{accountId}/uploads/commit
bash
curl https://api.koo.io/accounts/:accountId/uploads/commit \  -X POST \  -H "Authorization: Bearer kc_your_api_token" \  -H "Content-Type: application/json" \  -d '{      "key": "example",      "scope": "accountAvatar"    }'
Response
json
{  "finalUrl": "https://example.com"}