> ## Documentation Index
> Fetch the complete documentation index at: https://docs.crazyrouter.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Image Upload Guidance

> Upload images and get temporary public URLs for APIs that accept image input

> Дата обновления: 2026-06-21

Crazyrouter provides temporary public image upload endpoints for converting local or remote images into model-readable public URLs. Use them for vision, image editing, image-to-video, and workflow integrations.

<Note>
  Temporary images are kept for 48 hours by default and then cleaned up automatically. Storage during that period is not billed separately; per-user upload quota and rate limits apply.
</Note>

## Endpoint Overview

| Scenario                   | Endpoint                         |
| -------------------------- | -------------------------------- |
| Local file upload          | `POST /v1/files/uploads`         |
| Base64 image upload        | `POST /v1/files/uploads/base64`  |
| Remote image rehosting     | `POST /v1/files/uploads/url`     |
| Presigned direct R2 upload | `POST /v1/files/uploads/presign` |

Common limits:

| Item               | Current rule                                                  |
| ------------------ | ------------------------------------------------------------- |
| Auth               | `Authorization: Bearer YOUR_API_KEY`                          |
| Supported formats  | `image/png`, `image/jpeg`, `image/webp`, `image/gif`          |
| Single file size   | 20MB                                                          |
| User upload quota  | 200MB / rolling 24-hour window                                |
| Default expiration | 48 hours                                                      |
| Returned URL       | `https://media.crazyrouter.com/task-artifacts/tmp-inputs/...` |

## Presigned Direct R2 Upload

For high-upload-volume workflows, request a presigned upload URL first, then upload the image directly from your client to the storage endpoint with `PUT`. The image bytes do not pass through the Crazyrouter application server.

```bash cURL theme={null}
curl -X POST https://api.crazyrouter.com/v1/files/uploads/presign \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "filename": "reference.jpg",
    "content_type": "image/jpeg",
    "size": 12345,
    "purpose": "model_input"
  }'
```

Example response:

```json theme={null}
{
  "id": "file_e5bbce820b5941409682a9c5e9ba79f1",
  "upload_url": "https://...r2.cloudflarestorage.com/...?...",
  "url": "https://media.crazyrouter.com/task-artifacts/tmp-inputs/2026/06/21/user-1/file_e5bbce820b5941409682a9c5e9ba79f1.jpg",
  "method": "PUT",
  "headers": {
    "Content-Type": "image/jpeg",
    "Content-Length": "12345"
  },
  "mime_type": "image/jpeg",
  "size": 12345,
  "expires_at": "2026-06-22T04:41:35Z",
  "upload_expires_at": "2026-06-21T04:56:35Z"
}
```

Then upload directly:

```bash cURL theme={null}
curl -X PUT "$UPLOAD_URL" \
  -H "Content-Type: image/jpeg" \
  -H "Content-Length: 12345" \
  --data-binary @./reference.jpg
```

After the upload succeeds, use the returned `url` as the image URL in the model request.

<Warning>
  The `upload_url` is a short-lived write URL, valid for about 15 minutes by default. `Content-Type` and `Content-Length` must match the presign request. Do not pass `upload_url` to the model; use the returned `url` instead.
</Warning>
