Settings registry
A typed, hierarchical configuration system. Modules register their settings as code; tenants override at any of three scope levels; the resolver walks specific → general.
Resolution order
channel scope → most specific (e.g. POS terminal #5)
market scope → one regional surface (CZ vs DE)
account scope → whole e-shop default
registered default → baked into the module
A GET .../settings/resolve.json?key=...&market_id=... returns
{value, source_scope, source_id, definition} so the caller knows
where the value came from.
Built-in commerce settings
26 keys ship out of the box across these categories:
| Category | Examples |
|---|---|
| order | number_format, number_prefix, starting_number, auto_archive_after_days |
| tax | calculation_mode, b2b_reverse_charge, vies_cache_days |
| checkout | guest_allowed, captcha_provider, session_ttl_minutes, reserve_at |
| inventory | reservation_ttl_minutes, allow_overselling, low_stock_threshold |
| shipping | allow_pickup_points, free_shipping_threshold_cents |
transactional_from_address, transactional_from_name, support_email, locale_default, api_key | |
| brand | primary_color, logo_url, favicon_url |
| customer | welcome_email_enabled, abandoned_cart_email_enabled, abandoned_cart_delay_minutes |
Inspect the registry
curl "$API/settings/registry.json?category=tax" \
-H "Authorization: Bearer $NEVIOS_KEY"
{
"settings_registry": [
{
"key": "commerce.tax.calculation_mode",
"type": "string",
"default": "vat_inclusive",
"description": "...",
"category": "tax",
"scopes": ["account","market"],
"allowed_values": ["vat_inclusive","vat_exclusive"],
"min_value": null,
"max_value": null,
"sensitive": false
},
...
]
}
The dashboard renders settings pages dynamically by reading this.
Set a value
# Account-wide override
curl -X PUT "$API/settings/commerce.tax.calculation_mode.json" \
-H "Authorization: Bearer $NEVIOS_KEY" -H "Content-Type: application/json" \
-d '{"scope_type":"account","value":"vat_exclusive"}'
# Per-market override (more specific)
curl -X PUT "$API/settings/commerce.tax.calculation_mode.json" \
-H "Authorization: Bearer $NEVIOS_KEY" -H "Content-Type: application/json" \
-d '{"scope_type":"market","scope_id":308...,"value":"vat_inclusive"}'
The service validates against the registry — wrong type, out-of-range,
or invalid enum value returns 422 with details.
Resolve
# Account-only
curl "$API/settings/resolve.json?key=commerce.tax.calculation_mode" \
-H "Authorization: Bearer $NEVIOS_KEY"
# With market context (most specific wins)
curl "$API/settings/resolve.json?key=commerce.tax.calculation_mode&market_id=308..." \
-H "Authorization: Bearer $NEVIOS_KEY"
# Bulk
curl "$API/settings/resolve.json?category=email" \
-H "Authorization: Bearer $NEVIOS_KEY"
Delete an override
Reverts to the next-up scope (or default).
curl -X DELETE "$API/settings/commerce.tax.calculation_mode.json" \
-H "Authorization: Bearer $NEVIOS_KEY" \
-d 'scope_type=account'
Type system
The registry supports 7 canonical types: string | int | bool | float | json | list. Each definition can add:
allowed_values— enum constraintmin_value/max_value— numeric boundsschema— Pydantic model forjsontypessensitive— never log values;<sensitive>in registry response
commerce.email.api_key is sensitive — list/registry responses show
"default": "<sensitive>", event payloads redact the value, the
dashboard masks it in the UI.
Endpoints
GET /admin/2026-01/settings/registry.json
GET /admin/2026-01/{handle}/settings.json
GET /admin/2026-01/{handle}/settings/resolve.json
PUT /admin/2026-01/{handle}/settings/{key}.json
DELETE /admin/2026-01/{handle}/settings/{key}.json
Next: Themes.