# upload_asset

> Upload a file to use as a reference

`POST /api/v2/uploads`

Two ways in. Pass `source_url` (a public link) and we copy it. Or pass `content_type` + `size_bytes` for a local file: you get an `upload_url` to PUT the bytes to, then use `file_url` in a tool. Needs the `uploads` scope.

- Auth: API key (Authorization: Bearer)
- Key scope needed: `uploads`
- Raw spec: https://app.diffusr.ai/api/v2/openapi.json

## Request body (JSON)

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `source_url` | string | no | A public http(s) URL to copy in. Use this OR the three fields below. |
| `content_type` | string | no | For a LOCAL file: its MIME type, e.g. "video/mp4", "image/jpeg". |
| `size_bytes` | integer | no | For a LOCAL file: its exact size in bytes. |

## Example

**cURL**

```bash
curl -X POST "https://app.diffusr.ai/api/v2/uploads" \
  -H "Authorization: Bearer $DIFFUSR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "content_type": "video/mp4",
  "size_bytes": 12345678
}'
```

**TypeScript**

```ts
import { Diffusr } from "diffusr";

const d = new Diffusr(); // reads DIFFUSR_KEY
// Copies a public link in. For a local file use d.uploadFile("./clip.mp4").
const up = await d.uploadFromUrl("https://example.com/clip.mp4");
console.log(up.file_url);
```

**Python**

```python
from diffusr import Diffusr

d = Diffusr()  # reads DIFFUSR_KEY
# Copies a public link in. For a local file use d.upload_file("./clip.mp4").
up = d.upload_from_url("https://example.com/clip.mp4")
print(up["file_url"])
```

## Response

### 201 ApiUpload

A file_url (URL copied in), or an upload_url to PUT the bytes to.

## Errors

Every error body is `{ error, code, request_id, ... }`. See https://diffusr.ai/docs/errors.

- 401: Missing, wrong, revoked or expired API key (code UNAUTHORIZED, KEY_REVOKED, KEY_EXPIRED).
- 403: The key may not do this (SCOPE_DENIED, MODEL_NOT_ALLOWED, TEST_MODE_UNSUPPORTED, ACCOUNT_BLOCKED, allowance_exceeded).
- 422: The request is not valid (VALIDATION_FAILED, INVALID_JSON, PREFLIGHT_FAILED, CALLBACK_URL_INVALID, REFERENCE_*). `issues` lists each problem. Nothing was charged.
- 429: Too many requests or jobs (RATE_LIMITED, CONCURRENCY_LIMIT, UPLOAD_QUOTA, …). Wait Retry-After seconds, then retry.
- 500: Our fault (INTERNAL_ERROR). Quote request_id to support.
- 503: Paused or busy (API_PAUSED, MODEL_PAUSED, PROVIDER_PAUSED, PROVIDER_BUSY, UNAVAILABLE). Wait Retry-After seconds, then retry.

## Charges

Free. No credits are spent.
