Settings
GET /v1/settings
PATCH /v1/settingsOne curated resource for the venue's configuration. GET returns the
current values; PATCH is a partial update — send only the fields you
want to change. Available on every plan with an active subscription.
Publish to go live
Like menu content, settings changes affect the public menu after the
next publication snapshot — finish your
changes, then call POST /v1/publish.
Fields#
All fields are optional in PATCH. Unknown fields are rejected with a
400 validation error naming the property — secrets and internal fields
(payment/delivery-provider credentials, cached data, ids) are not part
of this resource in either direction.
| Group | Fields |
|---|---|
| Venue core | name, address, phone, googleMapsUrl, wifiPassword, additionalInfo, country (ISO 3166-1 alpha-2), defaultCurrency (ISO 4217, see Reference), timezone (IANA) |
| SEO | seoTitle (≤60), seoDescription (≤160), cuisineType, googlePlaceId |
| Working hours | schedule, orderSchedule — arrays of { day, isOpen, openTime?, closeTime? } (HH:MM) |
| Social / reviews | instagramUrl, telegramUrl, tiktokUrl, twitterUrl, tripAdvisorUrl, googleReviewsUrl |
| Design | theme (LIGHT|DARK), brandColor (hex), menuFontFamily, menuCardStyle (see Reference) |
| Languages | defaultLanguage, enabledLanguages[] (allowed values in Reference) |
| Order config* | deliveryEnabled, pickupEnabled, dineInOrderingEnabled, minimumOrderAmount, deliveryFee, freeDeliveryThreshold, pickupDiscount (0–100), estimatedDeliveryTime, estimatedPickupTime, deliveryEmail |
| Notifications | notifyWaiterEnabled, notifyHookahEnabled, notifyBillEnabled, notifyBookingEnabled, notifyOrderEnabled, telegramChatId, orderTelegramChatId |
GET additionally returns read-only agent context:
logoUrl— set it via the logo ingest;publicMenuUrl— the venue's live menu link (https://<slug>.duck-hub.com/menu) to report back when the build is done;lastPublishedAt— timestamp of the latestPOST /v1/publish(null= never published), so you can tell whether draft changes have gone live.
* Order config requires the delivery feature
The whole order-config group is gated by your plan's delivery feature.
On plans without it, PATCHing any of those fields fails with
403 and code DELIVERY_NOT_AVAILABLE; all other
fields still work. Check planLimits.features.hasDelivery in
GET /v1/reference first.
Money fields (minimumOrderAmount, deliveryFee, freeDeliveryThreshold)
are integers in minor currency units. defaultLanguage is always kept
inside enabledLanguages automatically. Notification chat changes are
audit-logged server-side.
Example#
curl -X PATCH https://api.duck-hub.com/v1/settings \
-H "Authorization: Bearer dk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Trattoria Roma",
"cuisineType": "Italian",
"defaultCurrency": "EUR",
"timezone": "Europe/Rome",
"enabledLanguages": ["en", "it", "de"],
"schedule": [
{ "day": "monday", "isOpen": true, "openTime": "10:00", "closeTime": "22:00" },
{ "day": "sunday", "isOpen": false }
]
}'const response = await fetch('https://api.duck-hub.com/v1/settings', {
method: 'PATCH',
headers: {
Authorization: 'Bearer dk_live_your_api_key',
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Trattoria Roma',
cuisineType: 'Italian',
defaultCurrency: 'EUR',
timezone: 'Europe/Rome',
enabledLanguages: ['en', 'it', 'de'],
}),
})
const settings = await response.json() // the updated curated viewPATCH responds 200 with the same curated view GET returns.
Concurrency (ETag / If-Match)#
Settings can also be edited in the DuckHub app — to avoid silently overwriting a concurrent change, use optimistic concurrency:
GET /v1/settingsreturns anETagresponse header.- Send it back on
PATCHasIf-Match. If the settings changed since your read (e.g. the owner edited them in the app), the PATCH fails with412and codeSTALE_RESOURCE— re-read, re-apply your change, retry. - Omitting
If-Matchkeeps the old unconditional behavior.
ETAG=$(curl -si https://api.duck-hub.com/v1/settings \
-H "Authorization: Bearer dk_live_your_api_key" \
| grep -i '^etag:' | cut -d' ' -f2 | tr -d '\r')
curl -X PATCH https://api.duck-hub.com/v1/settings \
-H "Authorization: Bearer dk_live_your_api_key" \
-H "Content-Type: application/json" \
-H "If-Match: $ETAG" \
-d '{"name": "Trattoria Roma"}'Every PATCH response also carries the fresh ETag, so chained
conditional updates don't need an extra GET. (The same pattern will
apply to other single-resource endpoints as they gain conditional
writes; bulk sync has no single version to match and stays
unconditional.)
Errors#
400 Validation failed— invalid value (unsupported currency/locale, bad timezone, malformed schedule) or an unknown/secret field403DELIVERY_NOT_AVAILABLE— order-config field on a plan without the delivery feature412STALE_RESOURCE— yourIf-Matchno longer matches (settings changed since you read them)401/403 SUBSCRIPTION_INACTIVE— see Errors