---
title: "A pre-signed URL to upload an image or sound clip."
method: POST
path: "/v1/uploads"
tags: ["drafts"]
---

# A pre-signed URL to upload an image or sound clip.

`POST /v1/uploads`

## Request

- Base URL: `https://api.50heads.com`
- URL: `https://api.50heads.com/v1/uploads`
- Auth: one of:
  - HTTP bearer
  - OAuth 2 (authorization code, authorization URL `https://auth.50heads.com/authorize`, token URL `https://auth.50heads.com/token`; client credentials, token URL `https://auth.50heads.com/token`, scopes: `questions:write`)

PUT the file to `uploadUrl` with the returned headers (the URL is the credential, for 15 minutes), then use `publicUrl` in the question. Images are checked and their metadata stripped before heads see them.

## Request body

- UploadsRequest
  - `kind` 'image' | 'audio', required
  - `contentType` string, required
  - `bytes` integer, required

## Response `201`

OK

- UploadsResponse
  - `uploadUrl` string, required
  - `publicUrl` string, required
  - `headers` object, required

## Other responses

- `400`: The request is not valid; `error.details.validation` lists the fixes.
- `401`: No key or token, or it expired or was revoked.
- `403`: The key or token lacks the scope (`insufficient_scope`), or the action is not allowed.
- `429`: Too many requests; wait for Retry-After.

---

[API](https://skmtc.dev/50heads/apis/50heads-api.md) · [All operations](https://skmtc.dev/50heads/apis/50heads-api/llms.txt) · [OpenAPI document](https://skmtc.dev/50heads/apis/50heads-api/revisions/20175e8b00e3?raw)
