The Webhooks resource: registering callback URLs, and parsing/validating inbound event deliveries.
Summary
Functions
Returns {:error, %Monzo.Error.WebhookVerificationError{}} if the
event's transaction account_id is not present in
expected_account_ids, :ok otherwise.
Deletes a registered webhook. Monzo will stop sending notifications to it.
Lists the webhooks registered for an account.
Parses and minimally validates a raw incoming webhook request body into
a Webhook.Event.
Registers a URL to receive real-time events for an account. Monzo will POST to this URL on matching events, retrying up to 5 times with exponential backoff if your endpoint fails to respond successfully.
Functions
@spec assert_expected_account(Monzo.Webhook.Event.t(), [String.t()]) :: :ok | {:error, Monzo.Error.WebhookVerificationError.t()}
Returns {:error, %Monzo.Error.WebhookVerificationError{}} if the
event's transaction account_id is not present in
expected_account_ids, :ok otherwise.
@spec delete(Monzo.Client.t(), String.t()) :: :ok | {:error, Exception.t()}
Deletes a registered webhook. Monzo will stop sending notifications to it.
@spec list(Monzo.Client.t(), String.t()) :: {:ok, [Monzo.Webhook.t()]} | {:error, Exception.t()}
Lists the webhooks registered for an account.
@spec parse_event(String.t()) :: {:ok, Monzo.Webhook.Event.t()} | {:error, Monzo.Error.WebhookVerificationError.t()}
Parses and minimally validates a raw incoming webhook request body into
a Webhook.Event.
Webhook security
As of this writing, Monzo does not document a cryptographic signature (e.g. HMAC) on webhook deliveries, so this function cannot and does not perform signature verification. To defend your endpoint:
- Serve it over HTTPS only.
- Treat the registered URL as a secret (use an unguessable path segment).
- Validate the event's
account_idagainst the accounts you expect usingassert_expected_account/2before trusting the payload. - Re-fetch the transaction via
Monzo.Transactions.retrieve/2before acting on financially sensitive data, rather than trusting the webhook body alone.
@spec register(Monzo.Client.t(), String.t(), String.t()) :: {:ok, Monzo.Webhook.t()} | {:error, Exception.t()}
Registers a URL to receive real-time events for an account. Monzo will POST to this URL on matching events, retrying up to 5 times with exponential backoff if your endpoint fails to respond successfully.