Site Settings
Global site configuration endpoints. Settings are key-value pairs organized into groups
and used to control the behaviour and appearance of the frontend. Each setting has a fixed
key that is referenced by the frontend — only value and description can be modified
through the API.
Base path: /api/v1/settings
Get Public Settings
Returns all settings marked as is_public. No authentication required.
Intended to be called by the frontend on initial load.
Response 200 OK
[
{
"key": "site_name",
"value": "My CMS Site",
"type": "string",
"group": "general"
},
{
"key": "contact_email",
"value": "hello@site.com",
"type": "string",
"group": "contact"
}
]
Get All Settings
Returns all settings including non-public ones. Admin only.
Required permission: settings:read
Response 200 OK — list of SiteSettingResponse objects.
[
{
"id": "uuid",
"key": "site_name",
"value": "My CMS Site",
"type": "string",
"group": "general",
"label": "Site Name",
"description": "The name of the website",
"is_public": true,
"is_readonly": false,
"created_at": "2026-01-01T00:00:00Z",
"updated_at": null
}
]
Get Settings Grouped
Returns all settings organized by group. Useful for rendering admin settings UI where each group maps to a separate form section.
Required permission: settings:read
Response 200 OK
[
{
"group": "general",
"settings": [
{
"id": "uuid",
"key": "site_name",
"value": "My CMS Site",
"type": "string",
"group": "general",
"label": "Site Name",
"description": "The name of the website",
"is_public": true,
"is_readonly": false,
"created_at": "2026-01-01T00:00:00Z",
"updated_at": null
}
]
},
{
"group": "seo",
"settings": []
}
]
Get Settings by Group
Returns all settings belonging to a specific group.
Required permission: settings:read
Path parameters
| Parameter | Type | Description |
|---|---|---|
group |
string | One of: general, seo, social, contact, appearance |
Response 200 OK — list of SiteSettingResponse objects.
Get Setting by Key
Returns a single setting by its unique key.
Required permission: settings:read
Path parameters
| Parameter | Type | Description |
|---|---|---|
key |
string | Unique setting key (e.g. site_name) |
Response 200 OK — SiteSettingResponse object.
Errors
| Status | Description |
|---|---|
404 |
Setting not found |
Update Setting
Updates the value and/or description of a single setting.
Readonly settings cannot be modified.
Required permission: settings:update
Path parameters
| Parameter | Type | Description |
|---|---|---|
key |
string | Unique setting key |
Request body — all fields optional
| Field | Type | Required | Description |
|---|---|---|---|
value |
string | ❌ | New value for the setting |
description |
string | ❌ | Updated description shown in admin |
Response 200 OK — updated SiteSettingResponse object.
Errors
| Status | Description |
|---|---|
400 |
Setting is readonly |
404 |
Setting not found |
Bulk Update Settings
Updates multiple settings in a single request. If any key is not found or is readonly, the entire request fails — no partial updates.
Required permission: settings:update
Request body
{
"settings": [
{ "key": "site_name", "value": "My CMS Site" },
{ "key": "contact_email", "value": "hello@site.com" },
{ "key": "primary_color", "value": "#3b82f6" }
]
}
| Field | Type | Required | Description |
|---|---|---|---|
settings |
array | ✅ | Minimum 1 item |
settings[].key |
string | ✅ | Must match an existing key |
settings[].value |
string | ❌ | New value (null clears value) |
Response 200 OK — list of updated SiteSettingResponse objects.
Atomic operation
If any setting key is not found or has is_readonly: true, the entire request is rejected.
No settings will be modified.
Errors
| Status | Description |
|---|---|
400 |
One or more settings are readonly |
404 |
One or more setting keys not found |
Setting Groups
| Group | Description |
|---|---|
general |
Site name, tagline, logo, favicon, maintenance |
seo |
Default meta title/description, OG image, GA ID |
social |
Social network URLs |
contact |
Email, phone, address, Google Maps |
appearance |
Brand colors, footer text, custom CSS |
Setting Types
The type field indicates how the value should be interpreted and rendered in the admin UI.
| Type | Description | UI Component |
|---|---|---|
string |
Short text, URLs, hex colors | Text input |
text |
Long text, HTML, CSS | Textarea |
boolean |
"true" or "false" as string |
Toggle |
number |
Numeric value stored as string | Number input |
json |
JSON object or array stored as text | Code editor |
Boolean values
Boolean settings store their value as the string "true" or "false".
The frontend is responsible for parsing this appropriately.
Available Setting Keys
general
| Key | Type | Public | Description |
|---|---|---|---|
site_name |
string |
✅ | The name of the website |
site_tagline |
string |
✅ | Short description shown in header |
site_logo_id |
string |
✅ | UUID of the logo media item |
site_favicon_id |
string |
✅ | UUID of the favicon media item |
maintenance_mode |
boolean |
❌ | Put the site into maintenance mode |
seo
| Key | Type | Public | Description |
|---|---|---|---|
seo_title |
string |
✅ | Fallback meta title for pages |
seo_description |
text |
✅ | Fallback meta description |
seo_og_image_id |
string |
✅ | Default Open Graph image UUID |
google_analytics |
string |
❌ | GA4 Measurement ID (G-XXXXXXXXXX) |
robots_txt |
text |
❌ | Custom robots.txt content |
social
| Key | Type | Public | Description |
|---|---|---|---|
social_facebook |
string |
✅ | Full URL to Facebook page |
social_instagram |
string |
✅ | Full URL to Instagram profile |
social_twitter |
string |
✅ | Full URL to Twitter/X profile |
social_linkedin |
string |
✅ | Full URL to LinkedIn page |
social_youtube |
string |
✅ | Full URL to YouTube channel |
contact
| Key | Type | Public | Description |
|---|---|---|---|
contact_email |
string |
✅ | Primary contact email address |
contact_phone |
string |
✅ | Primary contact phone number |
contact_address |
text |
✅ | Physical address of the business |
contact_map_url |
string |
✅ | Embed URL for Google Maps |
appearance
| Key | Type | Public | Description |
|---|---|---|---|
primary_color |
string |
✅ | Main brand color (hex) |
secondary_color |
string |
✅ | Secondary brand color (hex) |
footer_text |
text |
✅ | Copyright or footer content |
custom_css |
text |
❌ | Additional CSS injected into the frontend |