---
title: "Upload an image to the site's image library"
method: POST
path: "/v1/sites/{site_id}/images"
tags: ["Images"]
---

# Upload an image to the site's image library

`POST /v1/sites/{site_id}/images`

## Request

- Base URL: `https://api.getsitecontrol.com`
- URL: `https://api.getsitecontrol.com/v1/sites/{site_id}/images`
- Auth: HTTP bearer

Adds a file to the site's image library and returns it with its public `url`,
which the widget and email image tools take. Give the file by `url`, a public
http or https address it is downloaded from, or by `data`, base64-encoded with
its `name`, for small content up to about 20 KB such as an icon or a logo.

A file is at most 3 MB; images of any common format are accepted. The file
appears in the editors' Upload tab as well.

## Path parameters

- `site_id` integer, required

## Headers

- `Idempotency-Key` string: Makes a retry of a POST safe: a repeat with the same key, body and GSC-Version returns the stored response with `Idempotency-Replayed: true` instead of running again. The key protects against repeated execution while the key store works. Saving the change and storing the response under the key are not atomic: if the process or the key store fails between them, the change is kept, the key is released after 15 minutes and a retry runs the request again. After a timeout or a 5xx, read the resource to check the result before retrying. 5xx and 429 responses and responses over 256 KB are not stored, so a repeat runs the request again. A key is kept for 24 hours. The same key with another body or version is 422; a repeat while the first request runs is 409.

## Request body

- ImageUpload
  - `url` string, nullable: Public http or https address of the file to download, e.g. a photo or a generated image. Give it or `data`, not both
  - `data` string, nullable: The file itself, base64-encoded, for small content up to about 20 KB such as an icon or a logo. Give it or `url`, not both
  - `name` string, nullable: File name with its extension, e.g. `logo.png`. Required with `data`; with `url` it defaults to the last part of the address

## Response `201`

Successful Response

- Image
  - `id` integer, required
  - `name` string, nullable: File name with its extension, as it was uploaded; `image.<ext>` for a file sent to an upload link
  - `url` string, required: Public address of the image. The widget and email image tools take this URL, e.g. as the hero image or an image block's source
  - `width` integer, nullable: Pixels; null when the file's header does not say, as for SVG
  - `height` integer, nullable: Pixels; null when the file's header does not say, as for SVG
  - `updated_at` string, date-time, required

## Other responses

- `400`: Unsupported GSC-Version
- `401`: Missing or invalid API key or access token
- `403`: Access denied
- `404`: Not found
- `409`: Conflict
- `413`: `image_too_large`: the file is over 3 MB; `payload_too_large`: the request body is over 5 MB
- `422`: `image_type_not_allowed`: a file a browser would run, such as HTML; `image_unsafe_svg`: an SVG with scripts or external links; `image_url_unreachable`: the URL is not a public domain or did not answer with the file; `image_source_required`: not exactly one of `url` and `data`, or `data` without `name`
- `429`: Rate limited
- `503`: Temporarily unavailable; retry later

---

[API](https://skmtc.dev/getsitecontrol/apis/getsitecontrol-public-api.md) - [All operations](https://skmtc.dev/getsitecontrol/apis/getsitecontrol-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getsitecontrol/apis/getsitecontrol-public-api/revisions/084fcad80e75?raw)
