Server image uploads
POST /server-assets/upload replaces or clears the server’s icon or banner image. Admin tools use it to change the server’s branding. The server name and other settings change through server_update instead.
Request
Section titled “Request”Send multipart/form-data:
const form = new FormData();form.append("asset", "icon");form.append("file", imageFile);form.append("validator_key", handshake.validator_key);form.append("validator", validator);
const response = await fetch(new URL("/server-assets/upload", serverUrl), { method: "POST", body: form,});| Field | Required | Description |
|---|---|---|
asset |
Yes | icon or banner. |
file |
Unless clearing | The new image. 1 byte to 10 MB, at most 8192 pixels on each side and 25 million pixels in total. |
clear |
No | Send 1 to remove the image instead of replacing it. file is then ignored. |
validator_key, validator |
For Rotur accounts | The connection’s validator_key and a fresh Rotur validator for it. |
local_upload_token |
For server accounts | The local_upload_token from ready. When present, the validator fields are ignored. |
Authentication works the same way as attachment uploads.
The server decodes the image and saves it as PNG under a new random file name. Animation is lost. If saving the setting fails, the server deletes the new file.
Response
Section titled “Response”Success returns HTTP 200 with the current image URLs:
{ "icon": "https://chat.example.com/server-assets/7f1c2d3e-4b5a-6978-8a9b-0c1d2e3f4a5b.png", "banner": ""}An empty string means that image is cleared.
Every signed-in connection, including yours, then receives a server_update event:
{ "cmd": "server_update", "name": "Example Chat", "icon": "https://chat.example.com/server-assets/7f1c2d3e-4b5a-6978-8a9b-0c1d2e3f4a5b.png", "banner": ""}The server also writes a server_update entry to the audit log.
Permissions
Section titled “Permissions”The account must be a current member with manage_server. The owner and administrators have it.
Uploads count against the same per-minute limit as attachment uploads. An account in timeout can’t upload.
Errors
Section titled “Errors”Failures return an HTTP status and {"error": "..."}.
| Status | error |
When |
|---|---|---|
400 |
Asset must be icon or banner |
asset is missing or has another value. |
400 |
An image file is required |
No file and no clear=1. |
400 |
Choose a valid image no larger than 8192 pixels per side |
The image size can’t be read, a side is over 8192 pixels, or it has more than 25 million pixels. |
400 |
Unsupported image format |
The image can’t be decoded. |
401 |
validator_key and validator are required for authentication |
No proof was sent. |
401 |
Invalid credentials |
Rotur rejected the validator, or the account doesn’t exist on this server. |
401 |
Invalid local upload token |
The server account token is wrong or expired. |
403 |
Access denied |
The account is banned. |
403 |
Manage server permission required |
The account isn’t a member or lacks manage_server. |
413 |
Server images must be between 1 byte and 10 MB |
The file is empty or too big. |
415 |
Content-Type must be multipart/form-data |
The body isn’t multipart. |
429 |
Upload rate limit exceeded |
Too many uploads this minute, or the account is in timeout. |
500 |
Unable to save server image |
The file couldn’t be written. |
502 |
Failed to validate credentials, Invalid authentication response |
The server couldn’t check the validator with Rotur. |
A failure while saving the new setting returns HTTP 400 with the configuration error text.
Serving images
Section titled “Serving images”GET /server-assets/{name} returns a stored image. The handshake’s server.icon and server.banner link here. A missing file, or a name containing a path, returns 404 with Server asset not found.
See also
Section titled “See also”server_update: change the server name and other details.- HTTP routes: every HTTP endpoint.
