OneTablet API Documentation

setAllWebhookSettings

POST/management/settings/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 (send newUrlEvents with it). Explicit null: cleared. To stop delivery without throwing the registration away, send newUrlEnabled: false instead.
  • 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):

  1. If newUrl is sent as a url, newUrlEvents must be sent with it and contain at least one event — registering a destination with no stated subscriptions would be a silent no-op.
  2. legacyUrl in the body is a 400.
  3. Every entry in newUrlEvents must be one of the published event types.
  4. newUrl must be https:// 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.
  5. Any field in the body outside newUrl / newUrlEvents / newUrlEnabled / legacyUrlEnabled is a 400.
  6. A call that would leave the organization with NO webhook destination — clearing newUrl with null when no legacyUrl is on file, or a first-ever call that registers no destination at all — is a 400.

Returns the full updated settings, including the untouched legacyUrl, so you can confirm the write without a second call.

Request

application/json
required
  • newUrlstring

    The new signed destination to register.

    Omitted -> the stored newUrl is left alone. A url -> registered, and at least one entry in newUrlEvents must accompany it in the SAME call. Explicit null -> the destination is cleared, which is refused with 400 when it would leave the organization with no webhook destination at all (no legacyUrl on file). Prefer newUrlEnabled: false to stop delivery: pausing keeps the registration, clearing throws it away.

  • newUrlEventsstring[]

    Which events newUrl receives.

    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 whenever newUrl is 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 newUrl only. Omitted -> left at its stored value.

  • legacyUrlEnabledboolean

    Pause switch for legacyUrl only (ONE-2877). Unlike legacyUrl itself — which has no field on this request at all and is rejected with 400 if sent — this one IS settable: it is the only way a partner can turn the legacy feed off themselves. false stops legacy delivery immediately; setting it back to true resumes it.

    OMITTING IT LEAVES LEGACY DELIVERY EXACTLY AS IT IS (ONE-2903). It used to be read as false, which meant registering a newUrl without naming this field switched a partner's live legacy order feed off, with a 200 and no warning. That is fixed; you never need to restate this field to keep legacy running.

Responses

200 — OK
  • 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) by legacyUrlEnabled below.

  • legacyUrlEnabledboolean

    A pause switch for legacyUrl ONLY (ONE-2877) — the sibling of newUrlEnabled for the legacy destination. Unlike legacyUrl itself, this IS settable through setAllWebhookSettings: it is how a partner finishes migrating off the legacy feed without OneTablet clearing legacyUrl as a support action. false silences legacyUrl alone; it has no effect on newUrl. It defaults true, so a destination nobody has ever switched off keeps delivering — including across a setAllWebhookSettings call 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. Governs newUrl ONLY — the legacy feed has no per-event list and is always orders-only. Absent/empty when newUrl is 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 newUrl ONLY. false silences the new feed; it has no effect on legacyUrl, 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.