Appearance
Base path: /api/v1/appearance. Per-user dashboard visual preferences (theme, color scheme, typography, motion, member banners). Read needs appearance: read. Write (PATCH, reset) needs appearance: read_write.
See Scopes for the appearance key and Errors for shared JSON error shape.
Get appearance
GET/api/v1/appearance
Response
200
JSON document: _id, userId, themeMode (light | dark | system), optional darkVariant (default | storm | night | moon), colorScheme, optional customColorSchemeId, fontFamily, optional customFontId, fontSize (small | medium | large), optional fontScale / fontSizePx, optional amoledBase, reduceMotion, memberBannerGradientsEnabled, updatedAt (Unix ms). _creationTime mirrors the row update time used for sync.
{
"_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"_creationTime": 1714237200000,
"userId": "a0a0a0a0-a0a0-a0a0-a0a0-a0a0a0a0a0a0",
"themeMode": "system",
"darkVariant": "default",
"colorScheme": "florality",
"fontFamily": "default",
"fontSize": "medium",
"fontScale": 1,
"fontSizePx": 16,
"amoledBase": false,
"reduceMotion": false,
"memberBannerGradientsEnabled": true,
"updatedAt": 1714237200000
}Examples
cURL
curl -sS \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/appearance"JavaScript (fetch)
const res = await fetch("https://api.floralitys.com/api/v1/appearance", {
headers: { Authorization: "Bearer YOUR_TOKEN" },
});
if (!res.ok) throw new Error(await res.text());
const appearance = await res.json();Status codes
- 200: JSON object
- 404: no row yet (body includes hint to reset or PATCH)
- 401 / 403: auth / scope
Example 404 body:
{
"code": "NOT_FOUND",
"message": "No appearance settings yet. Use POST /api/v1/appearance/reset or PATCH /api/v1/appearance to create them."
}Update appearance
PATCH/api/v1/appearance
Strict JSON: any subset of themeMode, darkVariant, colorScheme, colourScheme, customColorSchemeId, fontFamily, customFontId, fontSize, fontScale, fontSizePx, amoledBase, reduceMotion, memberBannerGradientsEnabled. At least one field required. customColorSchemeId / customFontId may be null to clear. Server enforces plan limits (e.g. custom fonts on Pro).
Examples
cURL
curl -sS -X PATCH \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"themeMode":"dark","fontSize":"large"}' \
"https://api.floralitys.com/api/v1/appearance"JavaScript (fetch)
const res = await fetch("https://api.floralitys.com/api/v1/appearance", {
method: "PATCH",
headers: {
Authorization: "Bearer YOUR_TOKEN",
"Content-Type": "application/json",
},
body: JSON.stringify({ themeMode: "dark", fontSize: "large" }),
});
if (!res.ok) throw new Error(await res.text());
const appearance = await res.json();Status codes
- 200: updated JSON document (same shape as GET)
- 400: invalid JSON, unknown keys, empty body, or validation message
- 403: entitlement (e.g. custom fonts)
- 404: custom color scheme or custom font id not found / not yours
- 401 / 403: missing key / missing write scope
- 500: rare persistence failure (INTERNAL)
Example 403 body:
{
"code": "FORBIDDEN",
"message": "Custom fonts require a Pro plan or higher. Upgrade to continue."
}Reset appearance
POST/api/v1/appearance/reset
Resets all appearance fields to product defaults. Creates a row if none exists (unlike GET, which returns 404 until settings exist).
Examples
cURL
curl -sS -X POST \
-H "Authorization: Bearer YOUR_TOKEN" \
"https://api.floralitys.com/api/v1/appearance/reset"JavaScript (fetch)
const res = await fetch("https://api.floralitys.com/api/v1/appearance/reset", {
method: "POST",
headers: { Authorization: "Bearer YOUR_TOKEN" },
});
if (!res.ok) throw new Error(await res.text());
const appearance = await res.json();Status codes
- 200: JSON document after reset
- 401 / 403: auth / scope
