We’ve migrated our documentation to a new site, which means some URLs have changed.
Subscriptions

How Do I Configure Piano ESP Callbacks and Webhooks?

What an ESP callback delivers

When a user is added to or removed from a mailing list, ESP can call a registered HTTPS endpoint with a JSON body:

{
  "email": "<reader_email>",
  "sqid": <mailing_list_id>,
  "action": "user_added" | "user_removed"
}

  • user_added fires when a user is subscribed to a mailing list.

  • user_removed fires when a user is unsubscribed — whether through the in-email unsubscribe link or through the API.

  • sqid is the mailing list ID (historically "squad ID").

For Double Opt-In mailing lists, the user_added event fires only after the user clicks the confirmation link, not at the moment of initial signup.

The HTTP method used for callbacks is configurable per endpoint at registration time (typically POST).

Endpoint requirements

Your callback endpoint must:

  • Be reachable over HTTPS.

  • Accept Content-Type: application/json (or the form-encoded variant if you elect that contract).

  • Return a status code in the 2xx range within a few seconds.

A failing endpoint is automatically suspended. After suspension, contact Piano Support to re-enable it.

Per-Site, ESP supports one callback endpoint. If you need to fan out events to multiple downstream systems, route through your own API gateway, proxy, or distribution service — the multi-endpoint case is not natively supported by ESP. The same endpoint typically handles both user_added and user_removed, distinguished by the action field in the payload. If you prefer separate endpoints for subscription and unsubscription events (for example, /sub/ and /unsub/), you can register two routes and have Piano direct each action type to the matching URL.

Requesting endpoint setup

Callback configuration is performed by Piano's technical team — it is not self-service. To register an endpoint, contact your Account Manager or Piano Support and supply:

Item

Notes

Endpoint URL

Full HTTPS URL. If you need different routes per action, supply both.

Action scope

user_added, user_removed, or both.

ESP Site ID

Each Site has one endpoint. Provide one set of details per Site.

Environment

Sandbox, US production, EU production, or Asia-Pacific production. Sandbox and production are configured separately.

HTTP method and content type

Defaults to POST with JSON; specify if different.

Optional security details

Custom headers, URL-embedded auth token, IP whitelist requirements, non-standard ports.

Piano configures the registration and confirms when callbacks are live. Test in sandbox first, then ask Piano to promote the configuration to production once you have verified end-to-end delivery.

Verifying registration

After registration, generate a subscribe or unsubscribe event in the relevant environment and confirm the endpoint received the payload. If callbacks do not arrive consistently, ask Piano Support to check the request log on their side for outbound delivery attempts and response codes — this is often the fastest way to identify a network or response-code problem on the receiving side.

Changing or updating an endpoint

Any change to the host, path, port, scheme, or event scope of a registered endpoint requires a re-registration request to Piano Support. Common reasons to update:

  • The site URL or domain changed (for example, moving from s.example.com to [www.example.com](https://www.example.com), or restructuring the path prefix).

  • A different downstream service is taking over event consumption.

  • You want to add or remove an event type from the registration.

Supply the old endpoint URL plus the new endpoint URL, the affected Site ID, and the environment. After the change is made, historical events are not replayed — only events from the moment of re-registration onward are delivered to the new endpoint.

Disabling a callback

To disable a registered callback, contact Piano Support. Supply the callback URL to disable, the ESP Site ID, and the environment (sandbox or production). Disabling is internal-only — there is no self-service path. Once disabled, the endpoint receives no further user_added or user_removed events.

Securing the endpoint

ESP callbacks do not carry a built-in authentication token to identify the source of the call. Two practices are recommended to harden the integration:

IP whitelisting (recommended)

Restrict inbound requests to your endpoint to Piano's published ESP webhook IP ranges. Sandbox and production environments use different IP ranges, and the ranges may change over time — Piano will notify you in advance of any change. Ask Piano Support for the current list for your region (US, EU, AP).

URL-embedded authentication token

Register the endpoint with an auth token in the URL, for example:

https://your-endpoint-url.com/esp-dispatcher?auth=<your_token>

Your endpoint verifies the token on every request and rejects unauthorized calls. Use this in addition to — not instead of — IP whitelisting where possible. If you operate multiple environments (production, pre-production), use a distinct token per environment.

Cross-system consistency

When ESP callbacks drive downstream state in another Piano product (most commonly Identity Management / SSO) or in your own user-state system, drift between the two surfaces causes hard-to-debug problems:

  • If a user_removed event is dropped or returns a non-2xx response, the downstream system can retain a stale "subscribed" state and inadvertently re-subscribe the user via an automated process.

  • Conversely, if a user_added event is missed, the downstream system can flag the user as unsubscribed when they are not.

Mitigate drift with logging and monitoring on the receiving side: log every payload and the response your endpoint returned, and reconcile periodically (for example, a nightly job comparing ESP list membership against downstream state). The reconciliation also catches the seven-consecutive-failure suspension before it surfaces as an alarm.

Sandbox testing tips

  • Configure sandbox and production endpoints separately — neither inherits configuration from the other.

  • For Double Opt-In lists, you must complete the confirmation step in the sandbox flow before user_added fires; do not stop the test at the initial signup screen.

  • Whitelist the sandbox IP range on your firewall before testing. Production IP ranges differ.

  • If your endpoint returns 405 Method Not Allowed, verify that it accepts the registered HTTP method (typically POST).

Webhook limitations summary

Limitation

Behaviour

Endpoints per Site

One

Multiple downstream systems

Use your own API gateway, proxy, or fan-out service

Replay after re-registration

Not supported — historical events are not redelivered

Failure tolerance

Seven consecutive non-2xx responses suspends the webhook

Built-in source authentication

None — secure via IP whitelist and/or URL token

Self-service configuration

Not available — contact Piano Support for any change

Sandbox vs. production

Configured independently

Double Opt-In

user_added fires only after confirmation

Last updated: