---
title: "Upload an image"
description: "Add an image to the library from a public https url (fetched once, no redirects, no private addresses) or base64 data with its content_type: PNG, JPEG, GIF or WebP up to 5 MB and 16,384 px a side (50 megapixels at most), counted against the plan's image storage (403 limit_reached). `POST /api/v1/library-images`"
url: https://www.unitpost.com/docs/platform/post-library-images
section: "Platform API reference"
updated: 2026-10-13
---
# Upload an image

`POST /api/v1/library-images`

Add an image to the library from a public https `url` (fetched once, no redirects, no private addresses) or base64 `data` with its `content_type`: PNG, JPEG, GIF or WebP up to 5 MB and 16,384 px a side (50 megapixels at most), counted against the plan's image storage (`403 limit_reached`). Send an `Idempotency-Key` so a retried upload stores one image. Requires the `templates:write` capability.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `Idempotency-Key` | header | string | no | Any unique string (1–256 characters, e.g. a UUID). Retrying with the same key and the same body within 24 hours returns the first result instead of sending again; the same key with a different body is `409 invalid_idempotent_request`, and one still in flight is `409 concurrent_idempotent_requests`. |

## Request body

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `url` | string | no | A public https image to fetch (no redirects, no private addresses). PNG, JPEG, GIF or WebP, up to 5 MB and 16,384 px a side (50 megapixels at most); anything else is a 422 naming `url`. |
| `data` | string | no | The image bytes, base64 (no `data:` prefix). Base64 adds a third, and a request over ~6 MB is refused before it arrives, so this fits about 4 MB of image; send larger images (up to 5 MB) by `url`. At most 16,384 px a side and 50 megapixels; anything else is a 422 naming `data`. |
| `content_type` | enum | no | Required with `data`; refused with `url` (the server sends the type). One of: `image/png`, `image/jpeg`, `image/gif`, `image/webp`. |
| `filename` | string | no | Shown in the library. Defaults to the URL's file name, or `image`. |
| `alt` | string \| null | no | Alt text suggested when the image is inserted. |

## Response fields (201)

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `object` | string | yes | — |
| `id` | string | yes | — |
| `path` | string | yes | Put this in a template or design: `<Image src="/img/…">` or `<img src="/img/…">`. Template and design sends resolve it to the image host; a raw `html` send doesn't, so use `url` there. |
| `url` | string | yes | The image's public address on our asset CDN: use it in raw `html` sends and anywhere outside Unitpost. |
| `filename` | string | yes | — |
| `content_type` | string | yes | — |
| `size` | integer | yes | Bytes. |
| `width` | integer \| null | yes | — |
| `height` | integer \| null | yes | — |
| `alt` | string \| null | yes | The alt text suggested when the image is inserted. |
| `created_at` | string | yes | — |
| `updated_at` | string | yes | — |

## Responses

| Status | Description |
| --- | --- |
| 201 | The image. |
| 400 | The body isn't JSON, or the `Idempotency-Key` is malformed. |
| 401 | Missing or invalid API key. |
| 403 | Insufficient scope, or the plan's image storage is full (`limit_reached`). |
| 409 | The `Idempotency-Key` is in use by a request still running, or with another body. |
| 422 | Neither or both of `url` and `data`, an image that couldn't be fetched or read, the wrong type, over 5 MB, over 16,384 px a side or 50 megapixels, or an unknown key. |
| 429 | Too many uploads; retry after the wait. |
| 502 | Storing the image failed; nothing was stored. Retry. |
| 503 | `engine_unavailable`: image hosting isn't configured on this deployment; nothing was stored. |

## Example request

```bash
curl -X POST 'https://www.unitpost.com/api/v1/library-images' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'User-Agent: my-app/1.0' \
  -H 'Content-Type: application/json' \
  -d '{ }'
```

## Example response (201)

```json
{
  "object": "library_image",
  "id": "id_123",
  "path": "string",
  "url": "https://example.com",
  "filename": "string",
  "content_type": "string",
  "size": 1,
  "width": 0,
  "height": 0,
  "alt": "string",
  "created_at": "2026-01-01T00:00:00.000Z",
  "updated_at": "2026-01-01T00:00:00.000Z"
}
```

## Links

- HTML reference (with Node.js, Python, Ruby, PHP, Laravel, Go, Java, Rust, .NET and CLI examples): https://www.unitpost.com/docs/platform/post-library-images
- OpenAPI 3.1 (full schemas): https://www.unitpost.com/api/v1/openapi.json
