# Webhooks

### Webhooks events

Rialto webhooks will allow you to be notified when a new action happened on the Rialto platform.&#x20;

A webhook request will always be a `POST`request on your specified endpoint. The body of the message will contain the webhook event encoded as a JSON and following the same structure.

```json
{
    // Type of event
    type: "TRANSACTION_CREATED",
    // Timestamp of the event, formatted as ISO 8601 date-time
    timestamp: "2024-12-01T09:07:54.940Z",
    // Data payload, see couples (event type, event payload) below
    payload: {
        clientId: "e7c1d1db-b8ca-4586-af30-8fcc213b5353",
        transactionId: "ef497614-ba4d-422d-b226-7662b17566b7"
    }
}
```

#### Event definitions

Rialto webhooks cover several types of events. Below is a list of event types and their associated payload structure:

* **Transactions events**

  The payload is defined as&#x20;

  ```typescript
  {
      // ID of the client account to which the transaction belongs
      clientId: string;
      // ID of the transaction
      transactionId: string;
  }
  ```

  The following types are available:

  * **TRANSACTION\_CREATED:** triggered when a new transaction is created,
  * **TRANSACTION\_INITIATED:** triggered when a transaction has been initiated i.e. when Rialto has received the funds for the transaction. Rialto is now processing the transaction,
  * **TRANSACTION\_COMPLETED**: triggered when the funds have been received by the user, completing the transaction,
  * **TRANSACTION\_CANCELLED**: triggered when the user has cancelled a transaction,
  * **TRANSACTION\_DISMISSED**: triggered when Rialto has dismissed a transaction of a client account.
* **Bank account management events**

  The payload is defined as

  ```typescript
  {
      // ID of the client account owner of the bank account
      clientId: string;
      // ID of the bank account
      bankAccountId: string;
  }
  ```

  The following types are available:

  * **BANK\_ACCOUNT\_REQUESTED:** triggered when the user has requested a new bank account,
  * **BANK\_ACCOUNT\_REJECTED:** triggered when the Rialto team has rejected a pending bank account request,
  * **BANK\_ACCOUNT\_APPROVED:** triggered when the Rialto team has approved a pending bank account request,
  * **BANK\_ACCOUNT\_DELETED:** triggered when the user or the Rialto team has deleted an approved bank account.
* **Blockchain wallet management events**

  The payload is defined as

  ```typescript
  {
      // ID of the client account owner of the bank account
      clientId: string;
      // ID of the blockchain wallet
      blockchainWalletId: string;
  }
  ```

  The following types are available:

  * **BLOCKCHAIN\_WALLET\_REQUESTED:** triggered when the user has requested a new blockchain wallet,
  * **BLOCKCHAIN\_WALLET\_REJECTED:** triggered when the Rialto team has rejected a pending blockchain wallet request,
  * **BLOCKCHAIN\_WALLET\_APPROVED:** triggered when the Rialto team has approved a pending blockchain wallet request,
  * **BLOCKCHAIN\_WALLET\_DELETED:** triggered when the user or the Rialto team has deleted an approved blockchain wallet.
* **Onboarding and account events** - *only for Client Account Managers*

  The payload is defined as

  ```typescript
  { clientId: string }
  ```

  The following types are available:

  * **ONBOARDING\_UNDER\_REVIEW:** the client account onboarding has been filled and the Rialto team is reviewing the submitted informations,
  * **ONBOARDING\_RESUBMISSION\_REQUIRED:** The Rialto team has decided that additional information or modifications are required to the client account onboarding,
  * **ONBOARDING\_APPROVED:** The onboarding informations are approved, the client account will need to sign the terms and conditions as a last step before being able to start transactions,
  * **CLIENT\_VERIFIED:** The terms and conditions document has been signed by the client account. The client account is now ready for transactions,
  * **TERMS\_AND\_CONDITIONS\_VOIDED:** The client account has not yet signed the terms and conditions document and there was an issue with the existing document, the later is voided and the signature process is restarted,
  * **CLIENT\_DELETED:**  The client account has been deleted by the Client Account Manager or the Rialto team.

#### Expected response and retries

A webhook request will be considered successful if the response has a success status code (200-299).

In case of error, webhook requests will be retried three times and following an exponential backoff strategy.

### Webhooks management

A webhook can be created from your target URL and starts as active. A **webhook secret** will be shared at creation time in order to enable you to properly verify the messages.

Once a webhook is no longer needed, it can be deleted.

Management of the webhooks can be made:

* either via the API using the `/webhooks` routes,
* either via the application, in your API Settings page and its dedicated Webhooks section.

Please note the following:

* Webhook secrets are only shown once at creation time.
* Webhook secrets allow to any user that has access to them to create webhook messages with an exact signature. Webhook secrets should **never be shared to an unintended audience**. Please keep your webhook secret secure. If a secret is lost or publicly revealed, it is recommended to delete the webhook and re-create it.
* You can have 3 active webhooks at the same time. If you reached the limit, you need to delete one webhook before creating a new one.

### Security

It is strongly recommended to protect your webhook endpoints against unwanted requests.

Each request can be verified using the webhook secret, the message content and the signature header.

If additional security is needed, the list of IPs addresses of the request sender are available for restrictions.

#### Verifying the signature

To each webhook is associated a secret, only visible at the webhook creation.

Using this secret, a HMAC (SHA-256) of the request body is computed, it is then `base64 encoded`, the value `sha256=<base64 encoded HMAC>`is finally added to the `Rialto-Signature`header of the webhook request.

Here is a NodeJS snippet in order to illustrate the verification of a message.

```typescript
import crypto from "crypto";

const WEBHOOK_SECRET = "<Fill your secret>";

async function requestHandler(request: Request): Promise<unknown> {
  const body = await request.text();
  const signatureHeader = request.headers.get("Rialto-Signature");

  if (!signatureHeader) {
    return new Response("Unauthorized", { status: 401 });
  }

  const hmac = crypto.createHmac("sha256", WEBHOOK_SECRET);
  hmac.update(body);
  const signature = hmac.digest("base64");

  if (signatureHeader !== `sha256=${signature}`) {
    return new Response("Unauthorized", { status: 401 });
  }

  return new Response("OK", { status: 200 });
}
```

#### IPs restrictions

Webhook requests are sent from a fixed list of IPs. Additional security can be brought by restricting your endpoints to be requested from these IPs.

```json
[
    "3.125.136.186/32",
    "18.198.95.233/32",
    "3.69.157.89/32",
    "3.69.220.58/32",
    "52.58.170.183/32",
    "3.74.98.166/32"
]
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.rialtobridge.xyz/concepts/webhooks.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
