---
title: "Pre-signed slots for image bytes"
method: POST
path: "/api/v1/uploads"
tags: ["Items"]
---

# Pre-signed slots for image bytes

`POST /api/v1/uploads`

## Request

- Base URL: `https://api.roma.app`
- URL: `https://api.roma.app/api/v1/uploads`
- Auth: HTTP bearer

Get pre-signed URLs to upload images DIRECTLY into Roma storage — the reliable alternative to passing third-party links in imageUrls (those must stay fetchable until the server downloads them; short-lived signed links often expire first). For each slot: HTTP PUT the raw image bytes to uploadUrl with the matching Content-Type header (valid ~2 hours), then pass its bucketPath as an imageUrls entry in create_items / update_items. Keep images at or under 10 MB (maxBytes). Up to 10 slots per call.

## Request body

- object
  - `mimeType` 'image/png' | 'image/jpeg' | 'image/heic' | 'image/webp', required: The image type you will upload (all slots in one call share it).
  - `count` integer: How many upload slots (default 1).

## Response `201`

Created; the body is the new item.

- object
  - `uploads` object[], required
    - `uploadUrl` string, required
    - `bucketPath` string, required
  - `maxBytes` number, required
  - `validForSeconds` number, required

## Other responses

- `400`: The request was understood and refused; the error says what to change.
- `401`: No usable bearer token.
- `404`: No such item for this account.
- `405`: The path exists but not with this method; Allow lists the ones that work.
- `429`: Over the rate limit; wait for Retry-After.

---

[API](https://skmtc.dev/roma/apis/roma-api.md) - [All operations](https://skmtc.dev/roma/apis/roma-api/llms.txt) - [OpenAPI document](https://skmtc.dev/roma/apis/roma-api/revisions/3dd91459b0fb?raw)
