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

# Upload a theme background image

> Store an image and use it as the background of a theme.

A theme background image takes two steps. First store the image and get a `signed_id`. Then pass the `signed_id` as `background_image` when you [create](https://apidocs.neetoform.com/api/themes/create.md) or [update](https://apidocs.neetoform.com/api/themes/update.md) a theme.

The image must be a PNG, JPEG, GIF or SVG of 1 MB or smaller. A `signed_id` works only in the workspace that created it, and only after the image bytes are uploaded.

## Option 1: The image is on the web

**1. Store the image**

Send the public `https` address to [Upload an image from a URL](https://apidocs.neetoform.com/api/images/upload-from-url.md). The address must be reachable without credentials and point to a public host. At most 2 redirects are followed.

```bash theme={"system"}
curl -X POST "https://YOUR_SUBDOMAIN.neetoform.com/api/external/v2/images" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://example.com/files/banner.png" }'
```

The response has the `signed_id`.

**2. Use it on a theme**

```bash theme={"system"}
curl -X PATCH "https://YOUR_SUBDOMAIN.neetoform.com/api/external/v2/themes/THEME_ID" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "theme": { "background_image": "SIGNED_ID", "properties": { "background": -30, "background_image_position": "top center" } } }'
```

## Option 2: The image is on your machine

**1. Reserve the upload**

Send the file name, its size in bytes and its checksum to [Reserve an image upload](https://apidocs.neetoform.com/api/images/reserve-upload.md). The `checksum` is the base64-encoded MD5 digest of the file, not the hex digest.

```bash theme={"system"}
CHECKSUM=$(openssl md5 -binary banner.png | base64)
SIZE=$(wc -c < banner.png | tr -d ' ')

curl -X POST "https://YOUR_SUBDOMAIN.neetoform.com/api/external/v2/image_uploads" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d "{ \"filename\": \"banner.png\", \"byte_size\": $SIZE, \"checksum\": \"$CHECKSUM\" }"
```

The response has the `signed_id`, the `upload_url` and the `upload_headers`.

**2. Send the bytes**

Send the file with an HTTP `PUT` to `upload_url`. Send every header in `upload_headers` unchanged. The `upload_url` is a short-lived credential, so do not share or log it.

```bash theme={"system"}
curl -X PUT "UPLOAD_URL" \
  -H "Content-Type: image/png" \
  --data-binary @banner.png
```

Use the headers from the response. Do not add an `X-Api-Key` header to this request.

**3. Use it on a theme**

Pass the `signed_id` as `background_image`, as in option 1. A `signed_id` used before its bytes arrive returns a 422 error.

## Related theme properties

These properties go in `theme.properties`:

| Property | Values |
| - | - |
| `background_image_position` | `center`, `top left`, `top center`, `top right`, `center left`, `center right`, `bottom left`, `bottom right`, `bottom center` |
| `background` | Whole number from -100 to 100. Below 0 darkens the image, above 0 lightens it. |
| `is_content_background_enabled` | `true` shows the questions on a card. |
| `content_background_color` | Hex color for the card. An alpha channel is allowed, such as `#ffffffcc`. |
| `is_dominant_background_color_enabled` | `true` makes `background_color` follow `dominant_color`. |
| `dominant_color` | Hex color of the main color in the image. |

Send an empty string or `null` as `background_image` to remove the image. Theme responses return `background_image_url`, the CDN address of the image, or `null` when there is none.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.