---
title: "Mint a Vercel Blob client token for a direct image upload"
method: POST
path: "/api/v1/uploads/sign"
tags: ["Uploads"]
---

# Mint a Vercel Blob client token for a direct image upload

`POST /api/v1/uploads/sign`

## Request

- Base URL: `http://localhost:3002`
- URL: `http://localhost:3002/api/v1/uploads/sign`
- Auth: HTTP bearer

Returns a short-lived token (1h) the iOS client uses with @vercel/blob to upload a single image. Bypasses Vercel's 4.5MB function body limit. The completion webhook fires at /api/v1/uploads/complete and persists the URL to the appropriate Prisma model based on `kind`.

## Headers

- `idempotency-key` string, uuid

## Request body

- SignUpload
  - `contentType` string, required
  - `sizeBytes` integer, required
  - `kind` 'boat-photo' | 'profile' | 'gallery' | 'booking-attachment', required
  - `refId` string, nullable

## Response `201`

Client token minted

- object
  - `data` SignUploadResponse, required
    - `token` string, required
    - `blobUrl` string, uri, required
    - `pathname` string, required

## Other responses

- `400`: Request body or query parameters failed validation.
- `401`: Authentication required, or the bearer token is missing or invalid.
- `403`: Authenticated but not permitted to access this resource.
- `404`: The requested resource does not exist (existence is not leaked).
- `409`: Idempotency-Key was reused with a different request body

---

[API](https://skmtc.dev/chartercaptain/apis/charter-captain-api.md) · [All operations](https://skmtc.dev/chartercaptain/apis/charter-captain-api/llms.txt) · [OpenAPI document](https://skmtc.dev/chartercaptain/apis/charter-captain-api/revisions/1ffea1113adb?raw)
