---
title: "Upload Image Bytes"
method: PUT
path: "/image-uploads/{token}"
tags: ["Image uploads"]
---

# Upload Image Bytes

`PUT /image-uploads/{token}`

## Request

- Base URL: `https://api.purplegrain.com/api/v1`
- URL: `https://api.purplegrain.com/api/v1/image-uploads/{token}`
- Auth: none required

The one-time PUT from `createImageUpload`. The token in the path is the
credential (this user, this upload, this byte size); send no bearer
token. The body is the raw file and must be exactly `byte_size` bytes,
at most 20 MB, and its magic bytes must match the declared content type.
A second PUT, or a PUT after `expires_at`, is refused. Not an MCP tool:
the agent runs `curl_example` from the shell.

## Path parameters

- `token` string, required

## Response `200`

The file is stored. `content_type` is the stored type (HEIC and HEIF become image/jpeg).

- ImageUploadPutResponse
  - `upload_id` string, required: The same signed id to pass as `image_upload_ids`.
  - `status` 'uploaded', required
  - `content_type` string, required: The stored type. HEIC and HEIF are stored as image/jpeg.
  - `byte_size` integer, required: Size of the stored image, after conversion, orientation and resizing.

## Other responses

- `422`: Expired, already used, the wrong size, a checksum mismatch, or magic bytes that do not match content_type.

---

[API](https://skmtc.dev/purplegrain/apis/purple-grain-api.md) · [All operations](https://skmtc.dev/purplegrain/apis/purple-grain-api/llms.txt) · [OpenAPI document](https://skmtc.dev/purplegrain/apis/purple-grain-api/revisions/4bedbc1c784c?raw)
