Receive Frame events in your webhook endpoint

Why use webhooks

When building Frame integrations, you may want your applications to receive real-time events from your Frame accounts to allow your backend systems to execute corresponding actions.

To enable webhook events, you must register webhook endpoints. Once registered, Frame can push real-time event data to your application's webhook endpoint whenever events occur in your Frame account. Frame sends these webhook events via HTTPS as a JSON payload containing an Event object.

Receiving webhook events is especially useful for tracking asynchronous events such as a customer's bank confirming a payment, a customer disputing a charge, a recurring payment succeeding, or the collection of subscription payments.

Frame uses Svix to send our webhooks.

Event overview

Frame generates event data to inform you of activities within your account.

When an event occurs, Frame creates a new Event object. A single API request may trigger the creation of multiple events. For instance, if you create a new subscription for a customer, you will receive both customer.subscription.created and payment_intent.succeeded events.

By registering webhook endpoints in your Frame account, you enable Frame to automatically send Event objects via POST requests to the registered webhook endpoint hosted by your application. Once your webhook endpoint receives an Event, your app can perform backend actions. For example, you might call your shipping provider's API to schedule a shipment after receiving a payment_intent.succeeded event.

Event object

The Event object we send to your webhook endpoint provides a snapshot of the object that changed. They might include a previous_attributes property that indicates the change, when applicable.

Example event payload

The following event shows a customer updated.

{
  "id": "4bbdf2cd-8ca2-4e00-a75b-a9ac0609ca6b",
  "object": "event",
  "type": "customer.updated",
  "created": 1715061591,
  "data": {
    "object": {
      "billing_address": null,
      "created": 1715060068,
      "description": null,
      "email": "john@website.com",
      "id": "5d8047ae-082e-4b1f-b082-056b80310e7e",
      "livemode": false,
      "metadata": [],
      "name": "John Doe",
      "object": "customer",
      "phone": null,
      "shipping_address": null,
      "updated": 1715060165
    }
  }
}

Event object structure

Review the event object structure to better understand events and the underlying information they provide.

Event type

You receive events for all of the event types your webhook endpoint is listening for in your configuration. Use the received event type to determine what processing your application needs to perform. The data.object correspoding to each event type varies.

Live and test mode

You might receive both live and test mode event delivery requests to your endpoints. This can happen if you use a single endpoint for both live and test mode. Use the livemode attribute to check whether the object exists in live or test mode, and determine the correct handling for the event.

Why event objects get generated

This table describes different scenarios that trigger generating Event objects.

SOURCETRIGGER
DashboardWhen you call an API by modifying your Frame resources in the Frame Dashboard.
APIWhen a user action in your app or website results in an API call.

Get started

To start receiving webhook events in your application, follow these steps to create and register a webhook endpoint:

  1. Create a webhook endpoint handler to receive event data POST requests.
  2. Register your endpoint within Frame using the Dashboard or the API.
  3. Secure your webhook endpoint.

You can use a single endpoint to handle multiple event types or set up individual endpoints for specific events.

Create handler

Set up an HTTP or HTTPS endpoint function capable of accepting webhook requests via the POST method. During development on your local machine, you may use HTTP. However, once the endpoint is publicly accessible, it must use HTTPS.

Set up your endpoint function so that it:

  1. Handles POST requests with a JSON payload consisting of an event object.
  2. Quickly returns a successful status code (2xx) prior to any complex logic that could cause a timeout. For example, you must return a 200 response before updating a customer's invoice as paid in your accounting system.

Example endpoint

This code snippet is a webhook function configured to check that the event type was received, to handle the event, and return a 200 response.

require "json"

# Using Sinatra
post "/webhook" do
  status 200
end

Test your handler

Before you go-live with your webhook endpoint function, we recommend that you test your application integration.

Register your endpoint in Frame

After testing your webhook endpoint function, register the webhook endpoint's accessible URL using the Webhooks section in the Developer Dashboard or the API so Frame knows where to deliver events. You can register up to 16 webhook endpoints with Frame. Registered webhook endpoints must be publicly accessible HTTPS URLs.

Webhook URL format

The URL format to register a webhook endpoint is:

https://<your-website>/<your-webhook-endpoint>

For example, if your domain is https://mycompanysite.com and the route to your webhook endpoint is @app.route('/frame_webhooks', methods=['POST']), specify https://mycompanysite.com/frame_webhooks as the Endpoint URL.

Add a webhook endpoint

Use the following steps to register a webhook endpoint in the Developers Dashboard. You can register up to 16 webhook endpoints on each Frame account.

  1. Navigate to the Webhooks page.
  2. Click New endpoint.
  3. Add your webhook endpoint's HTTPS URL in Endpoint URL.
  4. Select the event types you're currently receiving in your local webhook endpoint in Select events.
  5. Click Add endpoint.

Protect your webhooks from abuse

To ensure that the API route receiving the webhook can only be hit by your app, there are a few protections you can put in place:

Retries

Svix will use a set schedule and retry any webhooks that fail. To see the up-to-date schedule, check out the Svix Retry Schedule.

If Svix is attempting and failing to send a webhook, and that endpoint is removed or disabled from the Webhooks page of the Frame Dashboard, then the attempts will also be disabled.

Troubleshooting Tips

There are some common reasons why your webhook endpoint is failing:

Not using the raw payload body

This is the most common issue. When generating the signed content, we use the raw string body of the message payload.

If you convert JSON payloads into strings using methods like stringify, different implementations may produce different string representations of the JSON object, which can lead to discrepancies when verifying the signature. It's crucial to verify the payload exactly as it was sent, byte-for-byte or string-for-string, to ensure accurate verification.

Missing the secret key

From time to time we see people simple using the wrong secret key. Remember that keys are unique to endpoints.

Sending the wrong response codes

When we receive a response with a 2xx status code, we interpret that as a successful delivery even if you indicate a failure in the response payload. Make sure to use the right response status codes so we know when message are supposed to succeed vs fail.