> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hashrails.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

Webhooks allow you to receive real-time notifications about transfer request events. When a status changes, Hashrails sends a `POST` request to your configured webhook URL with the event details.

### Configuration

Configure your webhook URL in the [Hashrails Dashboard](https://dashboard.railsfromthecrypt.com/api-management/webhooks) to start receiving notifications.

### Headers

Every webhook request includes the following headers:

| Header                | Example                      | Description                     |
| --------------------- | ---------------------------- | ------------------------------- |
| `Content-Type`        | `application/json`           | Payload content type            |
| `x-webhook-event`     | `transfer_request.completed` | The event type                  |
| `x-webhook-timestamp` | `1761132905`                 | Unix timestamp of the delivery  |
| `x-webhook-signature` | `ac810d6feefc67c2eb09...`    | HMAC signature for verification |
| `user-agent`          | `Hashrails-Webhook/1.0`      | Webhook client identifier       |

### Signature Validation

Always validate the webhook signature to ensure the request is from Hashrails and hasn't been tampered with.

```javascript theme={null}
const crypto = require('crypto');

const SECRET = 'your-webhook-secret'; // From the dashboard
const PAYLOAD = '{"event":"transfer_request.completed",...}'; // Raw JSON body

const hash = crypto
  .createHmac('SHA256', SECRET)
  .update(PAYLOAD)
  .digest('hex')
  .toUpperCase();

// Compare with the x-webhook-signature header
```

***

## Transfer Request Events

The following events are sent throughout the lifecycle of a transfer request. Each event payload includes the full transfer request object.

### Event Reference

* `transfer_request.rate.fetching` - Hashrails has started sourcing the best exchange rate for the transfer. The rate and destination amount will be `0` at this stage.
* `transfer_request.rate.received` - A rate has been determined and is ready for review. The `rate.value`, `rate.expires_at`, and `destination.amount` fields are now populated.
* `transfer_request.rate.expired` - The rate expired before it was confirmed. Call the [Refresh Quote](/api-reference/transfer-request/refresh-quote) endpoint to request a new rate.
* `transfer_request.payment.awaiting` - The rate has been confirmed and the transfer is awaiting payment. The `payment_instructions` field is now populated with the details needed to complete payment.
* `transfer_request.payment.received` - A payment has been received for this transfer. For split payments, the `payments` array will contain the received amount.
* `transfer_request.payment.completed` - Full payment has been confirmed and the transfer is being processed for settlement.
* `transfer_request.completed` - The transfer has been fully settled and funds have been delivered to the recipient. The `transaction_hash` field is included for crypto settlements.
* `transfer_request.cancelled` - The transfer request has been cancelled. No further action will be taken.

### Event Payloads

Click on each event below to see the full payload structure.

<Tabs>
  <Tab title="transfer_request.rate.fetching">
    Sent when Hashrails begins fetching a rate for the transfer request.

    ```json theme={null}
    {
      "event": "transfer_request.rate.fetching",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "fetching_rates",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 0,
        "currency": "USDC"
      },
      "rate": {
        "value": 0,
        "expires_at": null
      },
      "payment_instructions": {},
      "events": [
        {
          "status": "pending",
          "timestamp": "2025-12-18T08:27:15.056854Z"
        },
        {
          "status": "fetching_rates",
          "timestamp": "2025-12-18T08:27:15.056869Z"
        }
      ],
      "payments": [],
      "timestamp": 1763559035,
      "webhook_id": "e33ab75e-b319-4422-a640-e1a0263316fd"
    }
    ```
  </Tab>

  <Tab title="transfer_request.rate.received">
    Sent when the rate has been determined and is ready for confirmation.

    ```json theme={null}
    {
      "event": "transfer_request.rate.received",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "fetching_rates",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 6.44,
        "currency": "USDC"
      },
      "rate": {
        "value": 1552.87,
        "expires_at": "2025-12-18T09:00:00.000000Z"
      },
      "payment_instructions": {},
      "events": [
        {
          "status": "pending",
          "timestamp": "2025-12-18T08:27:15.056854Z"
        },
        {
          "status": "fetching_rates",
          "timestamp": "2025-12-18T08:27:15.056869Z"
        }
      ],
      "payments": [],
      "timestamp": 1763559040,
      "webhook_id": "a44bc86f-c420-5533-b751-f2b1374427ge"
    }
    ```
  </Tab>

  <Tab title="transfer_request.rate.expired">
    Sent when the rate has expired before it was confirmed.

    ```json theme={null}
    {
      "event": "transfer_request.rate.expired",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "fetching_rates",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 6.44,
        "currency": "USDC"
      },
      "rate": {
        "value": 1552.87,
        "expires_at": "2025-12-18T09:00:00.000000Z"
      },
      "payment_instructions": {},
      "events": [
        {
          "status": "pending",
          "timestamp": "2025-12-18T08:27:15.056854Z"
        },
        {
          "status": "fetching_rates",
          "timestamp": "2025-12-18T08:27:15.056869Z"
        }
      ],
      "payments": [],
      "timestamp": 1763560840,
      "webhook_id": "b55cd97g-d531-6644-c862-g3c2485538hf"
    }
    ```
  </Tab>

  <Tab title="transfer_request.payment.awaiting">
    Sent when the rate has been confirmed and the transfer is awaiting payment.

    ```json theme={null}
    {
      "event": "transfer_request.payment.awaiting",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "awaiting_payment",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 6.44,
        "currency": "USDC"
      },
      "rate": {
        "value": 1552.87,
        "expires_at": "2025-12-18T09:00:00.000000Z"
      },
      "payment_instructions": {
        "type": "bank_transfer",
        "bank_transfer": {
          "account_number": "4693125866",
          "account_name": "Hashrails Ltd",
          "bank_name": "Nombank MFB"
        }
      },
      "events": [
        {
          "status": "pending",
          "timestamp": "2025-12-18T08:27:15.056854Z"
        },
        {
          "status": "fetching_rates",
          "timestamp": "2025-12-18T08:27:15.056869Z"
        },
        {
          "status": "awaiting_payment",
          "timestamp": "2025-12-18T08:30:00.000000Z"
        }
      ],
      "payments": [],
      "timestamp": 1763559100,
      "webhook_id": "c66de08h-e642-7755-d973-h4d3596649ig"
    }
    ```
  </Tab>

  <Tab title="transfer_request.payment.received">
    Sent when a payment has been received. This is typically triggered for split payments.

    ```json theme={null}
    {
      "event": "transfer_request.payment.received",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "confirmed",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 6.44,
        "currency": "USDC"
      },
      "rate": {
        "value": 1552.87,
        "expires_at": "2025-12-18T09:00:00.000000Z"
      },
      "payment_instructions": {
        "type": "bank_transfer",
        "bank_transfer": {
          "account_number": "4693125866",
          "account_name": "Hashrails Ltd",
          "bank_name": "Nombank MFB"
        }
      },
      "payments": [
        {
          "id": "pay_01K9X1BR5C9",
          "amount": 5000,
          "currency": "NGN",
          "session_id": "100004240121191726000236980560",
          "status": "received",
          "received_at": "2025-12-18T08:35:00.000000Z"
        }
      ],
      "timestamp": 1763559200,
      "webhook_id": "d77ef19i-f753-8866-e084-i5e4607750jh"
    }
    ```
  </Tab>

  <Tab title="transfer_request.payment.completed">
    Sent when full payment has been confirmed and the transfer is being processed for settlement.

    ```json theme={null}
    {
      "event": "transfer_request.payment.completed",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "payment_confirmed",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 6.44,
        "currency": "USDC"
      },
      "rate": {
        "value": 1552.87,
        "expires_at": "2025-12-18T09:00:00.000000Z"
      },
      "payment_instructions": {
        "type": "bank_transfer",
        "bank_transfer": {
          "account_number": "4693125866",
          "account_name": "Hashrails Ltd",
          "bank_name": "Nombank MFB"
        }
      },
      "payments": [
        {
          "id": "pay_01K9X1BR5C9",
          "amount": 10000,
          "currency": "NGN",
          "session_id": "100004240121191726000236980560",
          "status": "confirmed",
          "received_at": "2025-12-18T08:35:00.000000Z"
        }
      ],
      "timestamp": 1763559300,
      "webhook_id": "e88fg20j-g864-9977-f195-j6f5718861ki"
    }
    ```
  </Tab>

  <Tab title="transfer_request.completed">
    Sent when the transfer has been fully settled and funds have been delivered to the recipient.

    ```json theme={null}
    {
      "event": "transfer_request.completed",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "completed",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 6.44,
        "currency": "USDC"
      },
      "rate": {
        "value": 1552.87,
        "expires_at": "2025-12-18T09:00:00.000000Z"
      },
      "recipient": {
        "id": "bfc164ca-17ca-4db8-a181-cbe84c56ac1b",
        "type": "crypto",
        "name": "My USDT Wallet",
        "details": {
          "network": "Polygon",
          "wallet_address": "0x3fA91D6b84bE2c0BFD9647a92E9B1A2Ec6F8C91e",
          "symbol": "USDC"
        }
      },
      "transaction_hash": "0xabc123def456...",
      "timestamp": 1763559500,
      "webhook_id": "f99gh31k-h975-0088-g206-k7g6829972lj"
    }
    ```
  </Tab>

  <Tab title="transfer_request.cancelled">
    Sent when a transfer request has been cancelled.

    ```json theme={null}
    {
      "event": "transfer_request.cancelled",
      "id": "c17d2777-e604-45e2-b6d5-7743652eadf1",
      "reference": "TXN-2Z82FVYO6BW22RC7",
      "type": "onramp",
      "status": "cancelled",
      "source": {
        "amount": 10000,
        "currency": "NGN"
      },
      "destination": {
        "amount": 0,
        "currency": "USDC"
      },
      "rate": {
        "value": 0,
        "expires_at": null
      },
      "payment_instructions": {},
      "payments": [],
      "timestamp": 1763559600,
      "webhook_id": "g00hi42l-i086-1199-h317-l8h7930083mk"
    }
    ```
  </Tab>
</Tabs>

***

## Payload Fields

| Field                  | Type   | Description                                         |
| ---------------------- | ------ | --------------------------------------------------- |
| `event`                | string | The webhook event name                              |
| `id`                   | string | Unique transfer request ID                          |
| `reference`            | string | Human-readable transfer reference                   |
| `type`                 | string | Transfer type (`onramp` or `offramp`)               |
| `status`               | string | Current internal status                             |
| `source`               | object | Source amount and currency                          |
| `destination`          | object | Destination amount and currency                     |
| `rate`                 | object | Exchange rate and expiry time                       |
| `payment_instructions` | object | Payment details for completing the transfer         |
| `recipient`            | object | Recipient details (included on completion)          |
| `payments`             | array  | Payment records received for this transfer          |
| `transaction_hash`     | string | Blockchain hash (included on completion for crypto) |
| `timestamp`            | number | Unix timestamp of the event                         |
| `webhook_id`           | string | Unique identifier for this webhook delivery         |
