webhooks documentation


Webhooks are event notifications we send you through HTTP/HTTPS requests. The webhooks requests are composed of three important parts:

  • URL
  • Signature
  • Payload


The URL is the HTTP/HTTPS address where we send you the request. You indicate the URL when you create a new webhook through our App, see Webhook Creation section.


Each webhook request is signed using a secret or key, the payload and the timestamp. The webhook request headers contain the signature and the timestamp in a custom header called Mono-Signature.
The header Mono-Signature is like the following example:

Mono-Signature: t=1672328528,v1=662255ca79c4b21914894d32da10189a1482cd0fee56b2765a8b472662ce55ac

t is the timestamp, You can use it to validate if the request is not in your desired time range, see more at replay attacks.

The v1 is the signature version, and its value is the signature. You can use it to validate if the webhook request was sent from our system. You can see more information in the verifying signatures manually section.

Note: currently, we only use the signature version v1


The webhook request payload is JSON data containing the event's information. The main schema is like the following example:

    "event": {
        "data": {...},
        "type": "event_type_or_name"
    "timestamp": "2022-12-29T15:42:08.325158Z"

For more information about the specific data by each event see webhook events section.


When a webhook request fails, the system retries this request. Each attempt is executed X seconds after the previous attempt,
if the last attempt is executed and it fails the webhook request will not be sent anymore.

The following table describes how the request will be retried:

230 seconds
31.5 minutes
43.5 minutes
57.5 minutes
615.5 minutes
731.5 minutes
81.06 hours
92.13 hours
104.26 hours

These times are an approximation. The system executes a maximum of ten attempts in 8.4 hours.

Webhook events

When a webhook is created or registered the following events will be associated to it:


Bank transfers

Card transactions

Collection intents

Webhooks creation

Webhook creation is done through the user interface. Below you will find a detailed step by step.

  • Go to settings.
  • Click on Personal.
  • Click on API.
  • Click new webhook.
  • Insert the HTTPS/HTTP URL that you had configured to listen the events.
  • Click on save.

If everything is working as expected, there will be an alert indicating that we were successfully created your webhook, and you should be able to see the URL listed on the page.


Webhook urls are unique, meaning that you can only create one webhook for the same url. If for some reason you want to create a new webhook for an existing URL in your account, you should delete the previous one and create the new one pointing to the previously deleted URL, a new secret for that url will be generated.

Always verify that you are receiving information from the webhook in your systems.

URL restrictions:

  • It can not be blank / Do not leave it blank
  • The url should start with and http or https prefix.
  • The host can not be or localhost.
  • Must be a valid HTTP/HTTPS URL.

Detail view of the webhook

To access this view click on the arrow at the end of the column where your URL is displayed.
The detailed webhook view of the webhook contains the secret that is visually hidden. Click on the show/hide eyeball to see the whole secret.

Once revealed you should be able to use it, to verify that we are the ones that send you the payload. BE CAREFUL secret sharing is discouraged.

Verifying signatures manually

Step 1 Extract the timestamp and signatures from the headers

Split the header using the , character as the separator, to get a list of elements


Step 2 prepare the signed_payload string

the string should be as follow

Step 3 check the expected signature

Compute an HMAC with the SHA256 hash function. Use the endpoint’s signing secret as the key, and use the signed_payload string as the message.

an example in ruby

require 'openssl'

timestamp = 1672774221
raw_payload = '{"respose_body": "example"}'

signed_payload = "#{timestamp}.#{raw_payload}"

secret="whsec_example" #grab this secret from the page

hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secret, signed_payload)



the last number should be the one that you check against the one that came in the payload.

Step 4 Checking signatures

Compare the signature in the header to the expected signature. Compute the difference between the current timestamp and the received timestamp, then decide if the difference is within your time tolerance range.
To protect against timing attacks, use a constant-time string comparison to compare the expected signature to the received signatures.

Money fields

Fields that specify money values are defined in two key value pairs, one for the currency, and other for the amount. In these fields the money is represented in the minimum unit, which is cents.
For example:

240000 = 2400,00

160 = 1,60

Money fields that come with decimal units represent the original value. This is the case of the fx_rates field, where
"2400,32" = 2400,32