Site settings
| Method | Path | Scope |
|---|---|---|
GET |
/v1/sites/me/settings |
site:read |
PATCH |
/v1/sites/me/settings |
site:write |
- Base URL:
https://api.canverly.com - Auth: Bearer API key — the site is the key’s site; there is no id to pass
- Rate limit: 60 req/min per key
GET /v1/sites/me/settings
Section titled “GET /v1/sites/me/settings”curl -s https://api.canverly.com/v1/sites/me/settings \ -H "Authorization: Bearer ck_live_xxx"{ "id": "01KVPWYKT6AJDGG2EJN7DW4VT5", "slug": "example-blog", "primary_domain": "blog.example.com", "aliases": ["www.blog.example.com"], "theme_id": "aurora", "default_language": "pt-BR", "enabled_languages": ["pt-BR", "en"], "multi_lang_enabled": true, "prefer_www": false, "force_redirect": true, "child_redirect_mode": "redirect", "redirect_status_code": 301, "settings": { "social": { "instagram": "https://instagram.com/exampleblog" }, "search": { "enabled": true }, "subscriptions_enabled": true }}The response is a projection: only known fields are returned, so a new
internal field added upstream never leaks here. id, slug, primary_domain
and aliases are read-only — they come back on GET but cannot be written.
settings is the presentation/content blob. GET returns it whole, including
keys this API cannot write (see the allowlist below).
PATCH /v1/sites/me/settings
Section titled “PATCH /v1/sites/me/settings”Two kinds of field, both optional, both allowlisted.
Top-level fields
Section titled “Top-level fields”| Field | Type | Notes |
|---|---|---|
theme_id |
string | Active theme. |
default_language |
string | BCP-47 tag. |
enabled_languages |
string[] | BCP-47 tags. |
multi_lang_enabled |
boolean | |
prefer_www |
boolean | Canonical host prefers www.. |
force_redirect |
boolean | Force non-canonical hosts to the primary domain. |
child_redirect_mode |
string | How alias/child domains behave. |
redirect_status_code |
integer | 301 or 302. |
These are replaced with the value you send.
settings keys
Section titled “settings keys”Inside the settings object, only these top-level keys are writable, and they
are merged over what is stored — omitted keys keep their current value:
social · footer_columns · legal_links · search · customization ·
advanced · subscriptions_enabled · language_url_mode
Brand and identity — title · tagline · description · logo ·
logo_media_id · logo_svg · logo_url · favicon_svg · favicon_png_url ·
favicon_png_media_id · favicon_ico_url · favicon_ico_media_id
The legacy variants are all writable because the site reads them in a cascade
(logo → logo_svg → logo_url); allowing only the modern one would let you
write a field the site never reads. Upload the file with
POST /v1/media first and store the returned
id — a full site can be branded without opening the panel.
A body with no writable field at all is a 400 whose message lists everything
that is accepted.
Example
Section titled “Example”curl -X PATCH https://api.canverly.com/v1/sites/me/settings \ -H "Authorization: Bearer ck_live_xxx" \ -H "Content-Type: application/json" \ -d '{ "default_language": "pt-BR", "enabled_languages": ["pt-BR", "en"], "multi_lang_enabled": true, "settings": { "social": { "instagram": "https://instagram.com/exampleblog" }, "subscriptions_enabled": true } }'200 OK returns the same projection as GET, reflecting the new state — so a
single call is enough to write and confirm.
Errors
Section titled “Errors”| Status | error.code |
When |
|---|---|---|
400 |
bad_request |
No writable field in the body (no updatable settings provided (allowed: …)). |
401 |
unauthorized |
Missing/invalid/revoked key. |
403 |
forbidden |
Key lacks site:read / site:write. |
429 |
rate_limited |
Over 60 req/min — honour Retry-After. |
502 |
upstream |
Transient upstream error; retry with backoff. |