Skip to content
FiveCord Docs

Themes

A theme is a custom CSS stylesheet stored under a short code, and anyone holding the code can fetch it. The HTTP API exposes one operation, which stores a theme. The Media Proxy serves the stored stylesheet back through Get theme CSS.

The route is user-only. A bot token and an OAuth2 bearer credential are both rejected with 403 ACCESS_DENIED.

A theme identifier is 16 lowercase hexadecimal characters matching ^[a-f0-9]{16}$. Submitting identical CSS twice creates two independent themes.

{
"id": "3f0a91c7d2b84e65"
}

The UTF-8 encoding of a submitted document cannot exceed 8388608 bytes, and the document is at least one character long. Both bounds are fixed constants of the instance.

BoundValue
Encoded CSS1 28388608 bytes
Submitted CSS3at least 1 character

1 The 8 MiB ceiling is inclusive, so a document whose UTF-8 encoding is exactly 8388608 bytes is stored and one byte more is rejected with 400 FILE_SIZE_TOO_LARGE

2 Measured over the UTF-8 encoding, so a document of multi-byte characters can be shorter than 8388608 characters and still be rejected

3 Measured in characters of the submitted string

An account holds no theme quota. The theme:share:create rate limit bucket is the only bound on how many themes an account creates, and no route here checks an instance limit key.

The instance-wide content filter screens the submitted document before the route runs. It checks a css value of at least 3 characters against the instance phrase blocklist and the instance URL blocklist. A match on either returns 403 CONTENT_BLOCKED. A shorter value is never screened.

FiveCord scans a body under every content type except multipart/form-data and application/x-www-form-urlencoded. The filter also skips a body that does not parse as JSON. The route parses the body from the raw request text and reads no content type, so a JSON document sent under either form content type is stored without passing the blocklists.

The screen precedes the rate limit bucket, the credential check, and the request schema, so a blocked document returns CONTENT_BLOCKED even when the request has no credential.

Nothing else inspects the document. FiveCord stores the CSS verbatim and never parses, validates, minifies, or rewrites it.

POST/v1/users/@me/themes

Stores a custom CSS document and returns 201 with the created theme identifier. User-only, and no permission is required.

FieldTypeDescription
css1 2stringThe CSS text to store and share (at least 1 character)

1 Stored verbatim, bounded by the 8388608-byte UTF-8 ceiling described in Document bounds

2 An empty string is rejected with the validation code INVALID_FORMAT

A body that parses as JSON but is not an object, such as a string, a number, an array, or null, returns the same code at the path root.

FieldTypeDescription
idstringThe theme identifier

The object has the identifier and nothing else.

StatusBodyCondition
201response bodyDocument was stored
400error responseThe encoded document exceeds the size ceiling and the request returns FILE_SIZE_TOO_LARGE
403error responseCaller is a bot or presents a bearer credential and the request returns ACCESS_DENIED
403error responseThe account has an outstanding required action and the request returns ACCOUNT_SUSPICIOUS_ACTIVITY
403error responseThe document is blocked by content moderation and the request returns CONTENT_BLOCKED

FiveCord stores the UTF-8 encoding of the submitted document with the content type text/css; charset=utf-8. FiveCord finishes storing the document before it returns the identifier.

The Media Proxy serves the document from /themes/{id}.css.

20 requests per minute for each authenticated user, on the theme:share:create bucket.