setAllWebhookSettings
Set any of newUrl, newUrlEvents, newUrlEnabled and legacyUrlEnabled in one call.
AN OMITTED FIELD IS LEFT UNCHANGED; A FIELD YOU SEND IS SET (ONE-2903). Send only what you are actually changing — you never have to restate a setting to keep it. In particular, registering a newUrl without mentioning legacyUrlEnabled no longer switches your legacy order feed off, which is what this operation used to do.
Field by field:
newUrl— omitted: unchanged. A url: registered (sendnewUrlEventswith it). Explicitnull: cleared. To stop delivery without throwing the registration away, sendnewUrlEnabled: falseinstead.newUrlEvents— omitted: unchanged. Present: REPLACES the whole list, so[]means "no events". It is never an append; a list you could only add to would be useless.newUrlEnabled— omitted: unchanged. Present: set.legacyUrlEnabled— omitted: unchanged. Present: set.
On an organization that has never had any webhook settings, "unchanged" means the stored default: newUrl absent, newUrlEvents empty, and both enabled switches on.
legacyUrl MUST NOT appear in the request body at all — it is rejected with 400, not silently ignored, so you are never left believing you changed something you did not. WE control WHERE legacy delivers; legacyUrlEnabled is how YOU control WHETHER (ONE-2877).
WHY IT IS STILL CALLED setAllWebhookSettings. The name is kept deliberately, and it does not mean "resets everything you leave out". It means this ONE operation covers ALL of the settable webhook fields — there is no per-field endpoint to hunt for. Renaming a published operation is itself a breaking change for anyone already compiled against it, and it would buy nothing this paragraph does not: the semantics are stated here, on the operation, where a reader meets them.
VALIDATION (each enforced, each with its own test):
- If
newUrlis sent as a url,newUrlEventsmust be sent with it and contain at least one event — registering a destination with no stated subscriptions would be a silent no-op. legacyUrlin the body is a400.- Every entry in
newUrlEventsmust be one of the published event types. newUrlmust behttps://and must not resolve to a private (RFC1918), link-local, or cloud-metadata address — this value is later POSTed to by a service on a VPC connector, so this is a real SSRF control, not a formality.- Any field in the body outside
newUrl/newUrlEvents/newUrlEnabled/legacyUrlEnabledis a400. - A call that would leave the organization with NO webhook destination — clearing
newUrlwithnullwhen nolegacyUrlis on file, or a first-ever call that registers no destination at all — is a400.
Returns the full updated settings, including the untouched legacyUrl, so you can confirm the write without a second call.
Request
- newUrlstring
The new signed destination to register.
Omitted -> the stored
newUrlis left alone. A url -> registered, and at least one entry innewUrlEventsmust accompany it in the SAME call. Explicitnull-> the destination is cleared, which is refused with400when it would leave the organization with no webhook destination at all (nolegacyUrlon file). PrefernewUrlEnabled: falseto stop delivery: pausing keeps the registration, clearing throws it away. - newUrlEventsstring[]
Which events
newUrlreceives.Omitted -> the stored subscription list is left alone. PRESENT -> it REPLACES the stored list wholesale, so
[]genuinely means "no events" and this is not an append. Must contain at least one entry whenevernewUrlis sent as a url.Possible values: [order.created, order.status.updated, order.rejected, order.cancelled, order.delivery.updated, store.status.changed, report.completed, menu.publication.completed] - newUrlEnabledboolean
Pause switch for
newUrlonly. Omitted -> left at its stored value. - legacyUrlEnabledboolean
Pause switch for
legacyUrlonly (ONE-2877). UnlikelegacyUrlitself — which has no field on this request at all and is rejected with400if sent — this one IS settable: it is the only way a partner can turn the legacy feed off themselves.falsestops legacy delivery immediately; setting it back totrueresumes it.OMITTING IT LEAVES LEGACY DELIVERY EXACTLY AS IT IS (ONE-2903). It used to be read as
false, which meant registering anewUrlwithout naming this field switched a partner's live legacy order feed off, with a200and no warning. That is fixed; you never need to restate this field to keep legacy running.
{
"newUrl": "<newUrl>",
"newUrlEvents": [
"order.created"
],
"newUrlEnabled": true,
"legacyUrlEnabled": true
}Responses
- legacyUrlstring
The legacy orders-only feed's registered url. READ-ONLY through this API — absent when nothing is configured. Gated by
Organization.webhookOrderNotificationsEnabled, unchanged by anything on this contract, and (ONE-2877) bylegacyUrlEnabledbelow. - legacyUrlEnabledboolean
A pause switch for
legacyUrlONLY (ONE-2877) — the sibling ofnewUrlEnabledfor the legacy destination. UnlikelegacyUrlitself, this IS settable throughsetAllWebhookSettings: it is how a partner finishes migrating off the legacy feed without OneTablet clearinglegacyUrlas a support action.falsesilenceslegacyUrlalone; it has no effect onnewUrl. It defaultstrue, so a destination nobody has ever switched off keeps delivering — including across asetAllWebhookSettingscall that does not mention this field at all (ONE-2903). - newUrlstring
The new signed (
v2=ES256) destination. Absent when nothing is registered. - newUrlEventsstring[]
Which events are delivered to
newUrl. GovernsnewUrlONLY — the legacy feed has no per-event list and is always orders-only. Absent/empty whennewUrlis absent.Possible values: [order.created, order.status.updated, order.rejected, order.cancelled, order.delivery.updated, store.status.changed, report.completed, menu.publication.completed] - newUrlEnabledboolean
A pause switch for
newUrlONLY.falsesilences the new feed; it has no effect onlegacyUrl, which has its own gate (Organization.webhookOrderNotificationsEnabled).
About Settings
Read and set where OneTablet delivers your webhooks (ONE-2721).
organizationId is NEVER a field on any request or response here — it is resolved from the authenticated api key, exactly as every other Management API domain resolves it. A partner able to pass an organizationId could redirect another partner's order feed to their own server; the only way that cannot happen is for there to be no parameter that accepts one.
TWO DESTINATIONS, ONE ROW. legacyUrl is the pre-existing orders-only feed — the URL itself is READ-ONLY here (WE control WHERE legacy delivers; cleared only by OneTablet as a support action), gated by the org-wide Organization.webhookOrderNotificationsEnabled flag exactly as it is today, AND (ONE-2877) by legacyUrlEnabled — the self-serve switch that finally lets a partner turn legacy delivery off without asking OneTablet to clear legacyUrl. newUrl is the new signed (v2=, ES256) destination this endpoint lets a partner register for themselves, together with newUrlEvents (which events it receives) and newUrlEnabled (its own pause switch). Any combination of legacyUrlEnabled / newUrlEnabled is valid at once — legacy-only (today's state for Sizl and Profit Cookers), dual-run while migrating, or new-only once a partner is done — and registering/pausing one destination never touches the other.
THE NAMING CARRIES THE SEMANTICS. newUrlEvents and newUrlEnabled govern newUrl ONLY; legacyUrlEnabled governs legacyUrl ONLY — the legacy feed has no per-event subscription list and is always orders-only. Do not read newUrlEnabled: false as "webhooks are off" — it silences newUrl alone, exactly as legacyUrlEnabled: false silences only legacyUrl.
STORAGE: one row per organization, upserted ON CONFLICT ("organizationId") DO UPDATE — see SettingsRepository. No producer reads newUrl/newUrlEvents yet (that is ONE-2697); this contract is registration only.