Uploads
Get a presigned S3 URL to upload an avatar image (for a workspace, persona, or user) directly from the browser, without proxying the file through the API.
This group is for avatars only. For post media (images/videos attached to posts),
see Media — /v1/media/upload and related endpoints. /v1/uploads
has no scope of its own; it shares the media:read / media:write scopes with /v1/media.
Base URL
https://api.voxburst.io/v1/uploadsAuthentication: Requires a Bearer token with the media:write scope (or wildcard).
Get a Presigned Avatar Upload URL
POST /v1/uploads/avatar-url
Returns a presigned S3 PUT URL and the resulting public CDN URL. The caller uploads the
file directly to uploadUrl, then persists publicUrl by PATCHing the relevant entity.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Entity type: workspace, persona, or user |
entityId | string | Yes | ID of the entity the avatar belongs to. Must belong to the requesting workspace (or be the caller’s own user for type: "user") |
contentType | string | Yes | One of image/jpeg, image/png, image/webp |
curl -X POST https://api.voxburst.io/v1/uploads/avatar-url \
-H "Authorization: Bearer vb_live_xxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"type": "workspace",
"entityId": "wsp_example123",
"contentType": "image/png"
}'Response (201)
{
"uploadUrl": "https://voxburst-media-bucket.s3.amazonaws.com/avatars/workspace/wsp_example123/6c1f...png?X-Amz-...",
"publicUrl": "https://cdn.voxburst.io/avatars/workspace/wsp_example123/6c1f...png"
}Upload Flow
POST /v1/uploads/avatar-urlwithtype,entityId, andcontentType.PUTthe raw file bytes touploadUrl, setting theContent-Typeheader to match thecontentTypeyou requested. The presigned URL expires 15 minutes after issuance.- On a successful
200from the S3PUT, persist the avatar by calling the entity’s own update endpoint withavatarUrl: publicUrl:type: "workspace"→PATCH /v1/workspaces/:idwith{ "logo": publicUrl }type: "persona"→PATCH /v1/personas/:id(see Personas)type: "user"→PATCH /v1/users/mewith{ "avatarUrl": publicUrl }
curl -X PUT "https://voxburst-media-bucket.s3.amazonaws.com/avatars/workspace/wsp_example123/6c1f...png?X-Amz-..." \
-H "Content-Type: image/png" \
--data-binary @logo.pngOwnership Validation
The API validates that the caller may issue a presigned URL for the given entityId
before returning one:
type | Requirement |
|---|---|
workspace | entityId must equal the caller’s own workspace ID (from the token/workspace context) |
persona | entityId must be a persona that belongs to the caller’s workspace |
user | entityId must equal the caller’s own user ID (DB primary key or Cognito sub) |
Error Codes
| Status | Cause |
|---|---|
400 | Request body failed validation (invalid type, missing entityId, or unsupported contentType) |
403 | entityId does not belong to the caller’s workspace/user, or type: "workspace"/"persona" was requested with no workspace context |