Description

The endpoints allow you to manage your configuration of Webhooks receivable from the Send platform.

How to add a webhook

To receive notifications on the update events you should provide the following:

  • URL link - That URL will receive the events from the Send API
  • Events - an array of the events that the URL will receive the updates for
  • Description - Text description for the Webhook

List of currently available events:

EventDescription
account_updatedAllows tracking of the Account status during Account creation and updates.
wallet_updatedAllows tracking of the Wallet status during Wallet creation process and then the Wallet Balance.
payin_address_updatedAllows tracking of the PayIn Address status during the PayIn Address creation
payin_transaction_createdA new PayIn Transaction has been created within the system for a PayIn Address
payin_transaction_updatedAllows tracking of the PayIn Transaction after you create one for your PayIn Address
trade_transaction_updatedAllows tracking of the Trade Transaction status after you create a Trade
transfer_transaction_updatedAllows tracking of the Transfer Transaction status after you create a Transfer
payout_transaction_updatedAllows tracking of the Payout Transaction status after you create a Payout
payment_address_updatedAllows tracking of the Payment Address status during the Recipient creation process or after adding the Payment Address as a separate request.
recipient_updatedAllows tracking of the Recipient status during the Recipient creation process
all_default_eventsIf all_default_events is specified then all events that are enabled by default will be sent to the provided URL. If you have all_default_event active and Send adds a new event this new event will be automatically included in all_default_event.
Request example for POST /webhooks
{
  "url": "https://www.testtest123456666.com/apievents1",
  "events": [
    "account_registration_status_updated",
    "authorised_representative_status_updated",
    "wallet_status_updated",
    "deposit_address_status_updated",
    "deposit_transaction_created",
    "deposit_transaction_status_updated",
    "trade_transaction_status_updated",
    "payment_transaction_updated"
  ],
  "description": "Primary webhook target"
}

In response to your request you will receive either a SUCCESS 201 response or one or the error responses (400, 401, 500) See Status Codes & Error Messages.

Within the response you will receive all the data you’ve provided with the webhookId
to refer to the Webhook as well as createdAt and updatedAt dates and Webhook status.

Response example for POST /webhooks
{
  "item": {
    "webhookId": "string",
    "url": "https://www.testtest123456666.com/apievents1",
    "events": [
      "account_registration_status_updated",
      "authorised_representative_status_updated",
      "wallet_status_updated",
      "deposit_address_status_updated",
      "deposit_transaction_created",
      "deposit_transaction_status_updated",
      "trade_transaction_status_updated",
      "payment_transaction_updated"
    ],
    "description": "Primary webhook target",
    "createdAt": "2019-08-24T14:15:22Z",
    "updatedAt": "2019-08-24T14:15:22Z",
    "status": "active"
  }
}

Authenticating & Verifying Webhooks

To ensure the security and integrity of webhooks sent by the Send platform, each request includes specific headers that can be used to verify its authenticity.

X-Send-Signature

This header contains a signature generated by signing the timestamp (X-Send-Request-Timestamp header) and the message body using an asymmetric SHA256 private key. This signature can be used to ensure that the webhook originated from the Send platform and has not been altered.

Verifying the Signature
To verify the signature, follow these steps:

  1. Stringify the webhook body.
  2. Prefix the stringified body with the value from the X-Send-Request-Timestamp header.
  3. Use the provided public key to verify the signature.

An example of this implemented in Node.js is as follows:

const fs = require('fs');
const crypto = require('crypto');

const calculateStringToVerify = (webhookBody, timestampHeader) => {
  const bodyString = JSON.stringify(webhookBody);
  return `${timestampHeader}${bodyString}`;
}

const verifySignature = async (webhookBody, timestampHeader, signatureHeader) => {
  // Create the string to verify
  const stringToVerify = calculateStringToVerify(webhookBody, timestampHeader);

  // Retrieve the public key
  const publicKey = fs.readFileSync('./public-key.pem', 'utf8');

  // Set up the verifier
  const verifier = crypto.createVerify('RSA-SHA256');
  verifier.update(stringToVerify);
  verifier.end();

  // Verify the signature
  const isVerified = verifier.verify(publicKey, signatureHeader, 'base64');
  return isVerified;
}

If you intend to implement signature verification for incoming webhooks, please contact the Send team to obtain the current public key.

X-Send-Request-Timestamp

This header contains an ISO 8601 timestamp (UTC), indicating when the webhook was sent. To mitigate the risk of replay attacks, we recommend rejecting any webhook messages older than a threshold of your choosing.

This timestamp is also used in the signature calculation process described above.

Webhook Payloads

Customer Account Webhook

{
  "id": "2bde2e5a-7606-49c2-b28e-253792258e34",
  "customerAccountId": "2bde2e5a-7606-49c2-b28e-253792258e34",
  "status": "active",
  "externalReference": "2bde2e5a-7606-49c2-b28e-253792258e34",
  "updatedAt": "2024-02-09T13:30:00Z"
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
customerAccountIdstring [uuid]Unique identifier of the customer accountRequired
statusenumStatus of the Customer AccountRequired
externalReferencestringAn optional value that can be passed in to later reference a related resource in the partner system.Optional
updatedAtstring [stimestamp]The timestamp with timezone for date when Payment Address was updatedRequired

Status enum:

CustomerAccountStatus {
  submitted,
  pending,
  active,
  inactive,
  rejected
}

Wallet Webhook

{
  "id": "18b455af-9f60-43de-8f4b-b94f8e1b6e8b",
  "walletId": "18b455af-9f60-43de-8f4b-b94f8e1b6e8b",
  "tradingAccountId": "bfdb26af-655a-4ee2-9328-a480f4c204d7",
  "currency": "NZD",
  "status": "active",
  "availableBalance": 0,
  "cashBalance": 0,
  "committedBalance": 0,
  "updatedAt": "2024-02-14T00:01:08Z"
}
AttributeTypeDescription
idstring [uuid]Unique identifier of the webhook
walletIdstring [uuid]Unique identifier of the wallet object
tradingAccountIdstring [uuid]Unique identifier of attached trading account
currencystring3-letter Currency in what currency this wallet is denominated
statusenumStatus of the wallet
availableBalanceintegerwallet available balance
cashBalanceintegerwallet cash balance
committedBalanceintegerwallet receivable balance
updatedAtstring [stimestamp]The timestamp with timezone for when the record was updated.

Status enum:

WalletStatus {
  pending,
  active,
  inactive
}

Pay-In Address Webhook

{
  "id": "18b455af-9f60-43de-8f4b-b94f8e1b6e8b",
  "pay-inAddressId": "18b455af-9f60-43de-8f4b-b94f8e1b6e8b",
  "status": "active",
  "updatedAt": "2024-02-14T00:01:08Z"
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
pay-inAddressIdstring [uuid]Unique identifier of the Pay-In address objectRequired
statusenum: active, pending, inactiveStatus of the pay-in addressRequired
updatedAtstring [stimestamp]The timestamp with timezone for date when Payment Address was updatedRequired

Status enum:

Pay-InAddressStatus {
  pending,
  active,
  inactive
}

Pay-In Transaction Webhook

{
  "id": "9757e4bc-f9ba-49f0-beb8-1557f308b0ee",
  "pay-inId": "9757e4bc-f9ba-49f0-beb8-1557f308b0ee",
  "tradingAccountId": "bfdb26af-655a-4ee2-9328-a480f4c204d7",
  "pay-inAddressId": "987654321",
  "walletId": "9757e4bc-f9ba-49f0-beb8-1557f308b0ee",
  "amount": 1000,
  "currency": "USD",
  "status": "pending",
  "source": "BSB=944-600,ACC NO=016043596",
  "remitterDetails": "M J & L J L HATT",
  "reference": "2697D",
  "type": "local_bank_transfer",
  "updatedAt": "2024-03-21T10:05:00Z",
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
pay-inIdstring [uuid]Unique identifier of the Pay-In transactionRequired
tradingAccountIdstring [uuid]Unique identifier of attached trading accountRequired
pay-inAddressIdstring [uuid]Unique identifier of the Pay-In address objectRequired
walletIdstring [uuid]Unique identifier of the wallet objectRequired
amountintegerTransaction AmountRequired
currencystring3-letter Currency of the pay-InRequired
statusenumPay-in transaction statusRequired
sourcestringThe source response includes information about 'where' the Pay-In originated from.Required
remitterDetailsstringThe remitter response includes information about 'who' the Pay-In originated from.Required
referencestringThis is reference that the sender of the Pay-In would put on their bank transfer.Optional
typeenumPay-In transaction typeRequired
updatedAtstring [stimestamp]The timestamp with timezone for when the record was updated.Required

Status enum:

Pay-Intransaction {
  new,
  pending,
  credited,
  rejected
}

Trade Webhook

{
  "id": "9757e4bc-f9ba-49f0-beb8-1557f308b0ee",
  "paymentAddressId": "uuid",
  "tradingAccountId": "uuid",
  "status": "pending",
  "externalReference": "2bde2e5a-7606-49c2-b28e-253792258e34",
  "updatedAt": "2019-08-24T14:15:22Z",
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
tradeIdstring [uuid]Internal unique identifier of the TradeRequired
tradingAccountIdstring [uuid]Unique identifier of attached trading accountRequired
statusenumStatus of the tradeRequired
externalReferencestringAn optional value that can be passed in to later reference a related resource in the partner system.Optional
updatedAtstring [stimestamp]The timestamp with timezone for date when Payment Address was updatedRequired

Status enum:

TradeStatus {
  submitted,
  processing,
  pending_settlement,
  pending_payout_processing,
  awaiting_funds,
  settled,
  rejected
}

Payment Address Webhook

{
  "id": "9757e4bc-f9ba-49f0-beb8-1557f308b0ee",
  "paymentAddressId": "uuid",
  "tradingAccountId": "uuid",
  "status": "pending",
  "externalReference": "2bde2e5a-7606-49c2-b28e-253792258e34",
  "updatedAt": "2019-08-24T14:15:22Z",
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
paymentAddressIdstring [uuid]Internal unique identifier of the payment addressRequired
recipientIdstring [uuid]Id of the recipientRequired
tradingAccountIdstring [uuid]Unique identifier of attached trading accountRequired
statusenumStatus of the payment addressRequired
externalReferencestringAn optional value that can be passed in to later reference a related resource in the partner system.Optional
updatedAtstring [stimestamp]The timestamp with timezone for date when Payment Address was updatedRequired

Status enum:

PaymentAddressStatus {
  submitted,
  processing,
  rejected,
  active,
  inactive
}

Payout Transaction Webhook

{
  "id": "9757e4bc-f9ba-49f0-beb8-1557f308b0ee",
  "payoutId": "4f8fcf90-fad4-d319-0cb7-0b6f0dc323bb",
  "tradingAccountId": "72a9356c-7362-8dd9-ed9f-585274ec147f",
  "status": "compliance pending",
  "externalReference": "2bde2e5a-7606-49c2-b28e-253792258e34",
  "updatedAt": "2023-08-24T14:15:22Z",
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
payoutIdstring [uuid]Internal unique identifier of the payment transactionRequired
tradingAccountIdstring [uuid]Unique identifier of attached trading accountRequired
statusenumStatus of the payment TransactionRequired
externalReferencestringAn optional value that can be passed in to later reference a related resource in the partner system.Optional
updatedAtstring [stimestamp]The timestamp with timezone for date when Payment Address was updatedRequired

Status enum:

PayoutTransactionStatus {  
	submitted,
	processing, 
	awaiting_funds, 
	pending_trade_settlement,
	pending_release, 
	released, 
	returned, 
	rejected 
}

Transfer Transaction Webhook

{
  "id": "9757e4bc-f9ba-49f0-beb8-1557f308b0ee",
  "transferId": "4f8fcf90-fad4-d319-0cb7-0b6f0dc323bb",
  "tradingAccountId": "72a9356c-7362-8dd9-ed9f-585274ec147f",
  "status": "compliance pending",
  "externalReference": "2bde2e5a-7606-49c2-b28e-253792258e34",
  "updatedAt": "2023-08-24T14:15:22Z",
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
transferIdstring [uuid]Internal unique identifier of the payment transactionRequired
tradingAccountIdstring [uuid]Unique identifier of attached trading accountRequired
statusenumStatus of the payment TransactionRequired
externalReferencestringAn optional value that can be passed in to later reference a related resource in the partner system.Optional
updatedAtstring [stimestamp]The timestamp with timezone for date when Payment Address was updatedRequired

Status enum:

TransferTransactionStatus {
	submitted,
	processing, 
	awaiting_funds, 
	pending_trade_settlement,
	pending_release, 
	released, 
	returned, 
	rejected 
}

Payment Recipient Webhook

{
"id": "string",
"tradingAccountId": "string",
"status": "pending",
"externalReference": "2bde2e5a-7606-49c2-b28e-253792258e34",
"updatedAt": "2019-08-24T14:15:22Z",
}
AttributeTypeDescriptionRules
idstring [uuid]Unique identifier of the webhookRequired
recipientIdstring [uuid]Internal unique identifier of the recipientRequired
tradingAccountIdstring [uuid]Unique identifier of attached trading accountRequired
statusenumStatus of the recipientRequired
externalReferencestringAn optional value that can be passed in to later reference a related resource in the partner system.Optional
updatedAtstring [stimestamp]The timestamp with timezone for date when Payment Address was updatedRequired

Status enum:

RecipientStatus {
  submitted,
  processing,
  rejected,
  active,
  inactive
}

How to get Webhooks information and delete Webhook

Fetching the information about the Webhooks

To request the information about all the Webhooks for the Enterprise User you can send a signed GET /webhook request.

In response to your request you will receive either a SUCCESS 200 response or one or the error responses (400, 401, 500) See Status Codes & Error Messages.

Given a valid accessToken a SUCCESS response will return the details for all the previously created Webhooks.

Deleting the existing Webhook

To remove up the Webhooks for the Enterprise User you can send a signed DEL /webhooks/{webhookId} request.

In response to your request you will receive either a SUCCESS 204 response or one or the error responses (400, 401, 500) See Status Codes & Error messages.

📘

Not Seeing What You're Looking For?

We are always looking to improve our API documentation to ensure Sends systems are easy to understand and quick to build against. If you're struggling to find the answer to a question we either haven't made it easy enough to find the relevant docs or we haven't had a chance to write something up for it yet.

Either way we want to hear from you!

Head over to our Discussion Board and leave us a note. We keep a close eye on this and want to ensure we make these docs as useful as they can be so will jump on any posts quickly.