Webhooks

Intro

With our webhook system we allow you to receive events in real-time (or almost) without the need to poll our API on a regular basis (which might be an issue with regards to your rate-limits as well).

💡

Make sure to read our guide about Webhooks first 📖

Overview

Supported Entities

See https://docs.partner-api.monta.com/docs/webhooks#supported-event-types

Configuration

To be able to receive events via a webhook you need to provide an HTTPS endpoint as well as a secret.

Make use of the PUT /webhooks/config(docs) endpoint to provide both:

  • webhookUrl: A HTTPS URL to send the webhook payload to when an event occurs.
  • webhookSecret: A cryptoghrapic secret used to sign the webhook payload.

Format of incoming events

Webhook Request Model

Any call to your webhook endpoint follows this structure (request payload):

POST {webhookUrl}

{
	"entries": [],
	"pending": 42,
	"timestamp": 1690550358254
}
  • entries: List of entries (Webhook Entry Model, see next paragraph) delivered in this batch
  • pending: Number of pending events left for delivery
  • timestamp: Timestamp of the request (milliseconds from the epoch of 1970-01-01T00:00:00Z). Check this to avoid replay attacks.

Webhook Entry Model

{
	"entityType": "charge",
	"entityId": "21",
	"eventType": "created",
	"payload": {}
}
  • entityType: Type of the entity
  • entityId: ID of the entity
  • eventType: Type of event, ie. created, deleted, updated
  • payload: Payload of this entity, e.g. a full Charge object

Validating incoming events

To allow you to validate incoming events, we are signing every request with a signature as part of the header field X-Monta-Signature.

The signature has the following format: sha1={signature}

It is generated using this algorithm: HMAC-SHA1 with your webhookSecret as key (Bytes) and the request body as input.

To validate that the requests was indeed coming from Monta, re-generate the signature using your secret and the payload and compare.

💡

To detect/prevent replay attack you can parse the timestamp field of the request body.

Responding to our webhook calls

When we call your webhook endpoint we expect you to do 2 things:

  1. Reply immediately
  2. Reply with 200 status code

Any processing, parsing and what not that could lead to long response times should be done asynchronously.

Failed deliveries

When a delivery failed - regardless if it was on our or your end (ie. when you provided anything other than 200 status code) - we mark the event and their entries as failed and they will be picked up in our retry schedule (currently every 60 seconds).

🚧

Please note that we delete any events older than 24 hours.

Debugging

To make everyone's live easier, we provide you with an endpoint to debug any webhook events relevant for your consumer in the past 24 hours.

Use the endpoint GET /webhooks/entries (docs) to retrieve all entries. You can also filter by status to only check for pending or failed entries.

In case of a failed entry, inspect the error field to learn more about the potential cause.