Skip to Content

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/uploads

Authentication: 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

FieldTypeRequiredDescription
typestringYesEntity type: workspace, persona, or user
entityIdstringYesID of the entity the avatar belongs to. Must belong to the requesting workspace (or be the caller’s own user for type: "user")
contentTypestringYesOne 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

  1. POST /v1/uploads/avatar-url with type, entityId, and contentType.
  2. PUT the raw file bytes to uploadUrl, setting the Content-Type header to match the contentType you requested. The presigned URL expires 15 minutes after issuance.
  3. On a successful 200 from the S3 PUT, persist the avatar by calling the entity’s own update endpoint with avatarUrl: publicUrl:
    • type: "workspace"PATCH /v1/workspaces/:id with { "logo": publicUrl }
    • type: "persona"PATCH /v1/personas/:id (see Personas)
    • type: "user"PATCH /v1/users/me with { "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.png

Ownership Validation

The API validates that the caller may issue a presigned URL for the given entityId before returning one:

typeRequirement
workspaceentityId must equal the caller’s own workspace ID (from the token/workspace context)
personaentityId must be a persona that belongs to the caller’s workspace
userentityId must equal the caller’s own user ID (DB primary key or Cognito sub)

Error Codes

StatusCause
400Request body failed validation (invalid type, missing entityId, or unsupported contentType)
403entityId does not belong to the caller’s workspace/user, or type: "workspace"/"persona" was requested with no workspace context
Last updated on