Skip to main content

Get Avatar Upload URL

Generate a signed upload URL for user avatar.
const res = await client.storage.getAvatarUploadUrl.$post({
  fileName: "avatar.jpg",
  contentType: "image/jpeg",
  fileSize: 512000
})
const { uploadUrl, publicUrl, key } = await res.json()

// Upload file using the signed URL
await fetch(uploadUrl, {
  method: 'PUT',
  body: file,
  headers: { 'Content-Type': 'image/jpeg' }
})
Type: Private Procedure
fileName
string
required
Original file name (sanitized for storage)
contentType
string
required
MIME type (e.g., “image/jpeg”, “image/png”)
fileSize
number
required
File size in bytes
uploadUrl
string
Signed URL for uploading the file (valid for limited time)
publicUrl
string
Public URL to access the uploaded file
key
string
Storage key/path for the uploaded file
Upload Policy:
  • Max file size: 5 MB
  • Allowed types: image/jpeg, image/jpg, image/png, image/gif, image/webp
  • Storage path: users/{userId}/avatar/{uuid}-{fileName}
  • Rate limit: Prevents abuse with per-user limits
After uploading to the signed URL, use the publicUrl to reference the avatar in user settings.

Get Workspace Upload URL

Generate signed upload URL for workspace assets (logos, images).
const res = await client.storage.getUploadUrl.$post({
  slug: "acme",
  folder: "logo",
  fileName: "company-logo.png",
  contentType: "image/png",
  fileSize: 256000
})
const { uploadUrl, publicUrl, key } = await res.json()
Type: Private Procedure (requires workspace upload permission)
slug
string
required
Workspace slug
folder
string
required
Upload folder: “logo”, “images”, or other allowed folder
fileName
string
required
File name
contentType
string
required
MIME type
fileSize
number
required
File size in bytes
Upload Policies by Folder: Permissions:
  • User must be workspace owner or admin
  • Rate limited per user to prevent abuse
Storage path format: workspaces/{slug}/{folder}/{uuid}-{fileName}

Get Post Image Upload URL

Generate signed upload URL for post images (public boards).
const res = await client.storage.getPublicPostImageUploadUrl.$post({
  workspaceSlug: "acme",
  boardSlug: "features",
  fileName: "screenshot.png",
  contentType: "image/png",
  fileSize: 1024000
})
const { uploadUrl, publicUrl, key } = await res.json()
Type: Public Procedure (with restrictions)
workspaceSlug
string
required
Workspace slug
boardSlug
string
required
Board slug
fileName
string
required
Image file name
contentType
string
required
Image MIME type
fileSize
number
required
File size in bytes
Upload Policy:
  • Max size: 10 MB
  • Allowed types: image/jpeg, image/png, image/gif, image/webp
  • Storage path: workspaces/{slug}/posts/{uuid}-{fileName}
Access Requirements:
  • Board must exist and be public
  • If board doesn’t allow anonymous posts, user must be authenticated
  • Rate limited per user (or by IP for anonymous)
This endpoint only works for public boards. Private boards require workspace member access.

Get Comment Image Upload URL

Generate signed upload URL for comment images.
const res = await client.storage.getCommentImageUploadUrl.$post({
  postId: "post-123",
  fileName: "reply-image.jpg",
  contentType: "image/jpeg",
  fileSize: 512000
})
const { uploadUrl, publicUrl, key } = await res.json()
Type: Private Procedure
postId
string
required
ID of the post where comment will be added
fileName
string
required
Image file name
contentType
string
required
Image MIME type
fileSize
number
required
File size in bytes
Upload Policy:
  • Max size: 5 MB
  • Allowed types: image/jpeg, image/png, image/gif, image/webp
  • Storage path: workspaces/{slug}/comments/{uuid}-{fileName}
Validation:
  • Post must exist and not be locked
  • Board must allow comments
  • For private boards, user must have workspace access
  • Rate limited per user

Upload Flow

1

Request signed URL

Call the appropriate upload URL endpoint with file metadata.
2

Upload file

Use the returned uploadUrl to upload your file via HTTP PUT:
await fetch(uploadUrl, {
  method: 'PUT',
  body: fileBlob,
  headers: {
    'Content-Type': contentType
  }
})
3

Use public URL

Reference the publicUrl in your API calls (e.g., when creating a post or updating settings).
Security Notes:
  • All signed URLs have time-limited validity
  • File names are sanitized to prevent path traversal
  • Content types are validated and normalized
  • File sizes are enforced server-side
  • Rate limiting prevents abuse
Supported Image Types:
  • JPEG/JPG (image/jpeg)
  • PNG (image/png)
  • GIF (image/gif)
  • WebP (image/webp)
  • SVG (image/svg+xml) - logo uploads only
Store the publicUrl in your database when creating posts or updating settings. The key can be used for deletion operations if needed.

Build docs developers (and LLMs) love