Using webhooks

With webhooks, the Toast platform pushes updates (also known as webhook events) to integration partners, dramatically reducing or eliminating the need to poll Toast APIs. The following sections provide information about using Toast platform webhooks. It includes:

For reference information on specific webhook event categories, see Webhooks reference. Currently, the Toast platform supports the following webhook event categories:

Webhook basics

This section uses the following webhook terms and concepts:

Term Definition

Webhook

A Web-based callback that allows the Toast platform to push updates (also known as webhook events) to webhook consumers, reducing or eliminating the need to poll a Toast API.

Webhook endpoint

The URL of a webhook consumer service that is capable of receiving webhook events from the Toast platform.

Event category

A Toast-defined classification for the type of events a webhook sends. For example, the partners event category sends webhook events related to the addition or removal of partner integrations to a restaurant location.

Event type

A Toast-defined name for a specific type of webhook event, for example, a partner_added or partner_removed event.

Webhook subscription

Maintained by Toast support, a webhook subscription associates a webhook endpoint with an event category. This defines the type of webhook events that will be sent to the webhook endpoint. A webhook endpoint may be associated with multiple event categories.

Webhook secret

A secret passphrase generated when a webhook subscription is created. The passphrase is used to sign the contents of a message posted to the endpoint associated with the webhook subscription. See Message signing.

The secret key is unique for each webhook subscription within an environment. For example, a stock webhook subscription has a different secret key than a partner webhook subscription for the same integration partner and within the same environment. For more information about webhook subscriptions, see Webhook basics. For more information about Toast API environments, see Environments.

Endpoint requirements

The Toast platform publishes updates to a webhook endpoint as they happen. It is possible, but not required, to use the same webhook endpoint for multiple event categories. The specifics of the data posted to the endpoint allow you to determine which event category generated the update.

To work correctly with the Toast platform, a webhook endpoint:

  • MUST support the HTTP/1.1 protocol.

  • MUST support HTTPS and use a valid TLS1.2 (or better) certificate.

  • MUST support the POST method. Updates are published as a POST request.

  • SHOULD ensure idempotency of update processing. When retry support is implemented, it will be possible for updates to be sent to your endpoint more than once and the endpoint must account for these redundant updates. Toast Integrations will provide more information on how to manage this situation at a future date.

  • SHOULD return a 2xx response code for a successful POST as soon as possible and perform any internal processing asynchronously. Timeouts are imposed on POST requests to prevent unnecessary delays.

  • MUST NOT return a 3xx response code. Redirects are not followed.

  • SHOULD NOT return a 4xx response code, unless the endpoint receives data from the Toast platform that does not match the documented format, making the return of a 400 Bad Response code appropriate. In general, the Toast platform will not resend updates after receiving a 4xx response code. The two exceptions will be for the 400 Bad Response code already been mentioned and the 404 Page Not Found error. A 404 Page Not Found code can be returned by the proxies, gateways, or load balancers that manage a request on its way to a webhook endpoint. If the Toast platform receives a 404 response code, it will assume that the webhook payload was not delivered to the endpoint and it will try to resend the update. See Retry support for more information.

  • MUST be publicly accessible and should not require authentication. See Message signing for information on verifying messages.

Subscriptions

After you have created a webhook endpoint, you work with the Toast Integrations team to have your webhook subscription created. The subscription registers a webhook endpoint in the Toast platform and creates an association between the partner that owns the webhook endpoint and the event categories that will be sent to the endpoint. The subscription also defines the webhook secret that is used for verifying the authenticity of a message and its contents.

After the subscription has been created, your endpoint will receive updates as they happen in the Toast platform. To unsubscribe from the webhook, you must contact the Toast Integrations team.

Message data schema

Webhook messages are always sent as JSON payloads in the body of POST requests. The message is sent with Content-Type: application/json.

Regardless of the event category, the data in the message that is published to your endpoint follows the same schema:

{
    "timestamp": “<ISO formatted timestamp in UTC>”,
    "eventCategory": "<eventCategory>",
    "eventType": "<eventType>",
    "guid": "<eventGuid>",
    "details": {
        <eventType specific payload>
  }
}

For reference information on the payload returned for specific event categories, see Webhooks reference.

HTTP headers

Webhook updates include a set of HTTP headers, some of which are standard HTTP headers and some of which are Toast-specific. This section provides more details on both types.

Toast-specific HTTP headers

The following table describes the Toast-specific HTTP headers included with webhook events.

Header Description

Toast-Signature

As a security measure, all webhook messages contain a signature in the Toast-Signature HTTP header. A webhook endpoint uses the Toast-Signature header to confirm that a webhook update message is coming from a known, secure source. See Message signing for more details.

Toast-Event-Type

The type of event that has occurred, for example, a partner_added event for the partners webhook or a low_quantity event for the stock webhook.

Toast-Restaurant-External-ID

If the triggering event has occurred at a restaurant, the GUID of that restaurant is included in the Toast-Restaurant-External-ID HTTP header, for example, if the webhook update is for a low_quantity event, this header identifies the restaurant where the inventory quantity is low. This header is omitted if the triggering event has not occurred at a restaurant, for example, the header is omitted for the Partners webhook event types because those events are triggered by changes to a partner's status, not changes to a restaurant's status.

Toast-Event-Category

The event category, for example, partners or stock.

Standard HTTP headers

In addition to the Toast-specific HTTP headers, webhook events include the standard HTTP headers shown in the table below. For more detailed information on these headers, see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers:

Header Value

Accept-Encoding

gzip,deflate

Connection

close

Content-Length

The size of the message body, in bytes.

Content-Type

application/json

Host

The domain name and port of the server that is listening for webhook events. Generated from the partner URI that is specified when a webhook subscription is created.

User-Agent

Apache-HttpClient/4.5.10 (Java/1.8.0_212)

Timeouts

In order to keep the Toast platform's webhook support operating with optimum performance, timeouts are enforced on requests sent to webhook endpoints. This protects the webhook system from endpoints that may be experiencing issues or are poorly implemented. Currently, these timeouts are:

  • Connection timeout: If the Toast platform experiences a timeout greater than 2 seconds while trying to connect to the webhook endpoint, it will abandon the update request.

    Important

    Toast API clients must return a 2xx response within the 2-second window to acknowledge the event, before processing any additional business logic.

  • Socket timeout: If the Toast platform experiences a timeout longer than 2 seconds while sending an update request or while waiting for a webhook endpoint to acknowledge receipt of a request, it will abandon the request.

Retry support

The Toast platform attempts to resend updates to a webhook endpoint in the following circumstances:

  • There is a timeout when connecting to, sending to, or receiving from the webhook endpoint. See Timeouts for more information.

  • The endpoint returns an HTTP 404 (not found) response code.

  • The endpoint returns an HTTP 429 (too many requests) response code.

  • The endpoint returns an HTTP 5xx response code.

For the conditions above, the Toast platform will wait five minutes and then resend the update. If the resent update also results in one of the conditions above, then the Toast platform will wait 10 minutes and resend the update a second time. If the second resend attempt fails, the Toast platform does not send the update again.

The Toast platform does not attempt to resend an update if:

  • The endpoint returns an HTTP 4xx response code other than 404 (not found) or 429 (too many requests).

  • The endpoint returns an HTTP 3xx response code.

Back-off support

In order to protect the Toast platform from outages, breakage, or delays with webhook endpoints, the Toast platform includes back-off functionality that temporarily disables a webhook subscription based on pre-defined error rates. The back-off support follows these rules:

  • If a webhook endpoint returns fifty or more errors during a five-minute interval, the subscription is paused for one minute.

  • If a webhook endpoint is paused nine times during a ten-minute interval, then the subscription is stopped and you must contact Toast support to restart it.

If a webhook endpoint is paused or stopped, messages are not sent to that endpoint and an email is sent to notify you of the paused or stopped endpoint. An additional email notification is sent when a stopped endpoint has been restarted (no email notification is sent when the Toast platform resumes sending messages to a paused endpoint).

Message signing

The Toast platform implements message signing that allows you to validate the source of data sent to your webhook endpoint.

Note

Using message signing to validate a webhook message is not required, however, it is highly recommended.

Using the secret key that is generated when your webhook subscription is created, and the body and timestamp of the message, a signature for each message is computed and published in the Toast-Signature HTTP header on the POST request to your endpoint.

Note

The secret key is unique for each webhook subscription within an environment. For example, a stock webhook subscription has a different secret key than a partner webhook subscription for the same integration partner and within the same environment. For more information about webhook subscriptions, see Webhook basics. For more information about Toast API environments, see Environments.

To validate the message, you compute the signature on your side, using the same process that the Toast platform uses to compute the signature. If the signatures match, then the message is valid and trustworthy.

The signature is derived by concatenating the body and timestamp of the webhook message into a string. This string is hashed and then signed using the HMAC-SHA256 algorithm and the secret key. The following is a code sample for computing the signature:

import javax.crypto.spec.SecretKeySpec;
import javax.crypto.Mac;
import javax.xml.bind.DatatypeConverter;
import java.nio.charset.StandardCharsets;

String HMAC = "HmacSHA256";

String getSignature(String secret, String body, String timestamp) {
  SecretKeySpec signingKey = new SecretKeySpec(secret.getBytes(), HMAC);
  try {
      String signature = body + timestamp;
      Mac mac = Mac.getInstance(HMAC);
      mac.init(signingKey);
      byte[] rawHmac = mac.doFinal(signature.getBytes(StandardCharsets.UTF_8));
      return DatatypeConverter.printBase64Binary(rawHmac);
  } catch (Exception e) {
      logger.warn("Failed to generate Webhook Signature", e);
      return null;
  }
}