Why webhooks?

Webhooks allow you to listen to events happening in your Dynamic environment and integrate applications to automatically receive information about those events.

To enable webhook events, you need to register webhook endpoints. After you register them, Dynamic can push real-time event data to your application’s webhook endpoint when events happen within your Dynamic environment. Dynamic sends webhook events to your app as a JSON payload that includes an Event object.

Events

Events are our way of letting you know when something happens in your Dynamic environment. When an event occurs, we create a new Event object. For example, when a user links a wallet, we create a wallet.linked event. Certain API requests might create multiple events. For example, when a user first signs in to your environment, we create a user.created event, and when a user successfully authenticates, we create a user.session.created event.

Event object

eventId
The unique id of the event that triggered the webhook message. A single event in a project can trigger one or more webhook messages if there is more than one webhook configured.

messageId
The unique id of the message sent. This key should be used as the idempotency key inorder to handle redeliveries.

webhookId
The unique id of the configured webhook that sent the message.

eventName
The name of the event that triggered the message. Events always conform to the following convention {resourceType}.{action}. For example with the event name of user.created, user is the resource type and created is the action performed on the resouce. The full list of event names can be retrieved by using the /eventTypes endpoint in the API here.

environmentId
The unique id of the environment from which the event originated.

environmentName
The name of the environment from which the event originated. This can be used to have the same systems handle both live and sandbox events.

timestamp
Timestamp when the event occurred.

redelivery
If the message is a redelivery, this will be set to true.

Example Event Object

Below is an example of a user.created event

{
  "eventId": "2a92c161-3167-44ad-8fce-4c6cdaed8129",
  "messageId": "5a2a5360-bb7e-4ea6-9bd3-0146bf2f734f",
  "webhookId": "a86acea4-e050-4846-8e4f-0ae039f6e37c",
  "eventName": "user.created",
  "environmentId": "123e4567-e89b-12d3-a456-426614174000",
  "environmentName": "sandbox",
  "timestamp": "2023-10-26T14:30:59.210Z",
  "data": {
    "chain": "EVM",
    "origin": null,
    "ipAddress": "::1",
    "verifiedCredentialId": "b13f337d-a8dc-41a7-96f5-5e5d76ad864a",
    "userId": "a5914498-7a8b-4c58-b04c-9624fef2897c",
    "expiresAt": null,
    "walletPublicKey": "0x3FcE1F4F28DbA209344072867134A3a7F547C7f1",
    "createdAt": "2023-10-26T14:30:02.909Z",
    "projectEnvironmentId": "7181a853-fb76-4dc2-9af8-6aeb6d2b818b",
    "provider": "browserExtension",
    "walletName": "metamask",
    "id": "484e49ba-3026-4e2c-9bf0-ed98ae224833",
    "revokedAt": "2023-10-26T14:30:59.204Z",
    "verifiedCredentialType": "wallet"
  }
}

What generates events?

SourceTrigger
Developer DashboardWhen you call an API by modifying Dynamic resources in the Developer Dashboard.
SDKWhen a user action in your app or website integrating the SDK results in an API call.
APIWhen you call an API directly.

Setting up Webhooks

1

Events

Identify what events you would like to monitor here.

2

Endpoint

Develop a webhook endpoint to receive event data POST requests, making sure it uses HTTPS.

3

Enable

Register your endpoint with Dynamic using the Webhooks Developer Dashboard or the API.

Signature validation

Dynamic follows general best practice when it comes to signature validation. As such, each payload includes a x-dynamic-signature-256 header which has a hash signature value, generated from your secret token.

To do the validation, there are plenty of template examples out there to help. We recommend the Github guide as it follows exactly the same format of signature as we do.

Event delivery behavior

Test payload

When you register a webhook, Dynamic sends a test payload to the webhook’s configured URL to verify that the endpoint exists and can receive payloads. The test payload is a ping event.

Retry behavior

Webhook messages have built-in retry logic. All non-200 response codes will result in a retry.

Events are delivered at least once, but can be retried up to 5 times for live environments, make sure to handle idempotency using the messageId attribute.

Below are the request retry intervals for live environments

  • 15 seconds
  • 1 minute
  • 10 minutes
  • 1 hour
  • 1 day

Event ordering

Dynamic makes no guarantee of message ordering. Events can be sent in an order not congruent with the order in which they happened.

Best Practices for implementing webhooks

Idempotency

Configured endpoints may receive the same event multiple times. This can happen for a number of reasons, including network timeouts, duplicate events, or as a result of retry logic. As such, it is important to design your endpoint to be idempotent so that it can safely handle duplicate events. Using the messageId attribute in the event object is a good way to handle this.

Events

Only select the events you are interested in. If you are only interested in user events, only select those event types. This will reduce the number of messages you receive and the number of messages you need to handle.

Verify messages

Make sure to validate the x-dynamic-signature-256 header to ensure the message is coming from Dynamic. This is a hash signature value, generated from your secret token.

Security

Make sure your endpoint is using HTTPS. Dynamic will not send messages to endpoints that use HTTP.

Limits

Webhooks

10 per environment

Webhook messages

After repeated failed delivery of messages to a configured endpoint that responds with a non 2XX HTTP status code the webhook will be automatically disabled.

Messages in live environments will be available for 90 days and 30 days for sandbox environments.

Endpoint response time

Configured payload urls must respond promptly, if the endpoint does not respond within 15 seconds, the message timeout and will be retried.