---
title: "Create an upload"
description: "Direct mode returns a one-use write target: POST the exact bytes to put_url with put_headers, then poll GET /v1/uploads/{id} until status is ready. Import mode gives a public https source_url instead; the worker fetches, checks, and stores the object and returns it ready."
url: https://docs.roasos.com/api-reference/uploads/createUpload
---

# Create an upload

Direct mode returns a one-use write target: POST the exact bytes to put_url with put_headers, then poll GET /v1/uploads/{id} until status is ready. Import mode gives a public https source_url instead; the worker fetches, checks, and stores the object and returns it ready.

## `POST /v1/uploads`

Endpoint: `POST https://api.roasos.com/v1/uploads`

Create an upload

Direct mode returns a one-use write target: POST the exact bytes to put_url with put_headers, then poll GET /v1/uploads/{id} until status is ready. Import mode gives a public https source_url instead; the worker fetches, checks, and stores the object and returns it ready.

### Request body

Content type: `application/json`

### Responses

- `201`: Upload authorized (direct) or stored (import)
- `400`: Invalid request, unsupported content type, oversized object, or an unsafe source_url
- `409`: The upload identity conflicts with an existing authorization, or the workspace is unavailable for uploads
- `429`: Write rate limit exceeded
- `503`: Upload authorization or storage is temporarily unavailable

Read the full reference at https://docs.roasos.com/api-reference/uploads/createUpload.
