Media¶
Each site has its own media library for images.
Accepted images¶
| Type | Content-Type | File extension |
|---|---|---|
| PNG | image/png |
.png |
| JPEG | image/jpeg |
.jpg |
| WebP | image/webp |
.webp |
| GIF | image/gif |
.gif |
| AVIF | image/avif |
.avif |
The first bytes of the file must match the declared type.
SVG and other types are refused with 415.
The maximum size is 16 MiB.
Upload¶
Send the raw bytes with the image Content-Type:
curl -X POST https://blog.example.com/api/sites/blog.example.com/media \
-H "Authorization: Bearer $CUHLUMN_TOKEN" \
-H "Content-Type: image/png" \
--data-binary @logo.png
{
"name": "ba7816bf8f01cfea414140de5dae2223.png",
"url": "https://blog.example.com/media/ba7816bf8f01cfea414140de5dae2223.png"
}
Names¶
The file name is the first 32 hexadecimal characters of the SHA-256 hash of the content, with the extension. The same image therefore always gets the same name. A repeated upload of the same image returns the same name and does not write the file again.
Use an image¶
Use the root-relative path /media/{name} or the absolute url in these places:
- Markdown, for example
 - The post
coverandog_image - The site
logo,favicon, andog_image
A root-relative path works behind any proxy and on any port.
Public address¶
/media/{name} on the site domain serves the file with these headers:
Cache-Control: public, max-age=31536000, immutableX-Content-Type-Options: nosniff
An alias domain redirects to the canonical domain.
A missing file returns 404.
Delete¶
DELETE /api/sites/{host}/media/{name} removes the record and the file.
The server does not check whether a post still uses the image.