ACH Webhooks
ACH Webhooks provide event notifications when an ACH transfer's status changes.

Authentication

The Event object represents a change of state to an api object. Each event type will have a specialized schema to best describe the changes to the object.

The Webhooks object represents information on how to communicate to an api user about useful api events. Allowing the api to contact the api user, bypassing the need of constant polling by the api user.

Webhooks are signed using a similar HMAC schema as found in the authentication documentation. A few minor differences exist noted below.

The signature is calculated using the following fields:

FIELD TYPE VALUE EXAMPLE
 secret  string  The HMAC secret key.  FNAqNywCi0hmo845Ni43p06mx3l4ub7C
 timestamp  int  The number of seconds since the Unix epoch.   1490041002
 method  string  The HTTP method as an upper case string.  POST
 url  string  The callback url of the webhook, must use https.  https://www.api-svb.com/svb-webhooks
 body  string  The body of the request.  See example test webhook body

 

Using this algorithm:

  1. Let + be a function that concatenates strings, and let "\n" indicate a newline character;
  2. Let HMAC be a function that calculates an HMAC from a string and a secret key, and let HEX be a function that returns the string hexadecimal representation of its input; then
  3. The signature is:
      HEX( HMAC( your_secret_key,
                 timestamp + "\n"
                 method + "\n" +
                 url + "\n" +
                 body ))

For more information on HMAC signing, see the section on authentication documentation.

Event Types

Each event type designates a specific change to an api object. The event type describes the api object being changed as well as the change occurring.
 

ID NAME DESCRIPTION 
 1  all  Matches all event types.
 5  ach.status  Triggered when an ACH transfer fails.
 13  ach.status.advice  Triggered for non-critical ACH status updates (status other than failed or corrected).

 

Events

Event objects encapsulate detailed changes on an api object.

Attributes

NAME TYPE DESCRIPTION
id string  Uniquely identifies each event object.
event_type string  Name of event type (see event types).
payload object  Current state of the api object.
previous object  Previous state of the api object.
created_at datetime  Date and time event was created in default ISO 8601 format.

 

Both the payload and previous json fields will contain an id which refers to the api object whose data has changed. When previous is null, it indicates no previous version of the object exists and the api object was created.

Example Event object:

{
    "id": "101",
    "event_type": "all",
    "payload": {
        "id": "201",
        "status": "failed"
    },
    "previous": null,
    "created_at": "2017-21-08T13:19:09.776Z",
    "type": "event",
    "url": "/v1/events/101"
}

Retrieve an Event

Request:

GET /v1/events/:id

Response:

200 OK The event resource.

Example request:

curl "https://api.svb.com/v1/events/123" \
    -H "Authorization: Bearer YOUR_API_KEY"

Example response:

{
  "data": {
    "id": "123",
    "created_at": "2017-21-08T13:19:09.776Z",
    "event_type": "all",
    "payload": {
        "id": "201",
        "status": "failed"
    },
    "type": "event",
    "url": "/v1/events/123"
  }
}

List all Events

Request:

GET /v1/events

Response:

200 OK List of events resources.

Filtering:

This endpoint supports filtering. Depending on the event type, below parameters can be used to filter list of queried events. For more details on filtering, please refer to documentation on Conventions page. 
 

Parameter Range Support

merchant_amount

 Filter by range is supported

approval_code

 N/A

banknet_ref_num

 N/A

billing_amount

 Filter by range is supported

card_number

 N/A

financial_network_code

 N/A

mcc_description

 N/A
mcc  N/A

merchant_name

 N/A

rcn_alias

 N/A
rcn_id  N/A

transaction_date_time

 Filter by range is supported

transaction_type

 N/A
vcn_id  N/A
id  N/A
status  N/A

 

Merchant amountbanknet_ref_num and transaction_date_time fields support searches by a range. Below is an example query using transaction_date_time parameter:

 

{{URL}}/v1/events?page[limit]=1000&
filter[payload.transaction_date_time]=[2020-07-10,2020-07-11]

 

Example request:

curl "https://api.svb.com/v1/events" \
    -H "Authorization: Bearer YOUR_API_KEY"

Example response:
Header: "Prefer: return-minimal"

{
  "data": [
    {
      "id": 123,
      "type": "event",
      "url": "/v1/events/123"
    },
    {
      "id": 122,
      "type": "event",
      "url": "/v1/events/122"
    },
    {
      "id": 121,
      "type": "event",
      "url": "/v1/events/121"
    }
  ],
  "links": {
    "first": "/v1/events",
    "next": null
  }
}

Example response:

{

  "data": [
  {
    "created_at": "2018-10-23T19:15:28.976Z",
    "event_type": "ach.$$limit.exceeded",
           "id": 25473,
          "payload": {
           "id": 340455
      },
      "previous": null,
      "type": "event",
       "url": "/v1/events/25473"
    },
  
  {
      "created_at": "2020-08-17T02:03:11.205Z",
      "event_type": "virtualcard.realtime.auths",
      "id": 77012,
      "payload": {
           "acquirer_ica": "003286",
           "approval_code": "020936",
           "billing_amount": 4245,
           "billing_currency": "USD",
           "card_number": "556338######2882",
           "issuer_response": "Approved",
           "mcc": "8931",
           "mcc_description": "ACCOUNTING, AUDITING AND BOOKKEEPING SERVICES",
           "merchant_amount": 9090,
           "merchant_currency": "USD",
           "merchant_id": "242661000053360",
           "merchant_name": "SQ *DELTA TOWING SAN ANTONIO TX",
           "transaction_date_time": "2020-07-11T16:53:11.000Z",
           "transaction_type": "Authorization Advice",
           "vcn_id": 3090180,
           "vcn_response": "Valid"
      },
      "previous": null,
      "type": "event",
      "url": "/v1/events/77012"
    },
    {
      "created_at": "2019-10-25T10:20:03.696Z",
      "event_type": "ach.status",
      "id": 75773,
      "payload": {
           "id": 5956,
           "return_code": "R01",
           "status": "failed"
      },
      "previous": {
      "id": 5956,
      "return_code": null,
           "status": "processing"
      },
      "type": "event",
      "url": "/v1/events/75773"
    },
    {
      "created_at": "2020-08-18T19:22:22.680Z",
      "event_type": "onboarding.company.status",
      "id": 77083,
      "payload": {
           "id": 28827,
           "status": "pending"
      },
      "previous": null,
      "type": "event",
      "url": "/v1/events/77083"
    },
    {
      "created_at": "2020-08-18T19:22:07.671Z",
      "event_type": "virtualcard.created",
      "id": 77081,
      "payload": {
           "available_balance": 12345,
           "currency": "USD",
           "id": "3188156",
           "per_transaction_max": 12345,
           "per_transaction_min": 0,
           "rcn_alias": "Test Account 1",
           "rcn_id": 126507,
           "status": "Approved",
           "total_card_amount": 12345,
           "transactions_max": 41,
           "valid_ending_on": "2021-12-31",
           "valid_starting_on": "2020-08-17"
      },
      "previous": null,
      "type": "event",
      "url": "/v1/events/77081"
    }
  ]
}

Webhooks Object

Webhooks object consist of a url to which to post events occuring on the api.

NoteWebhooks only support one callback URL per event type. Maximum of one callback URL can be configured per event type.

 

NAME TYPE DESCRIPTION 
 id  string  Uniquely identifies each webhook object.
 event_type_ids  int array  Ids of event types which cause webhook to trigger.
 secret  string  Key used for HMAC signing of request.
 status  enum("active", "inactive")  Only active webhooks will be triggered.
 callback_url  string  Url to post requset to, must use https.

Example Webhooks object:

{
    "id": "101",
    "event_type_ids": [1],
    "secret": "qwertyuipasdfghjklzxcvbnm1234567890",
    "status": "active",
    "callback_url": "https://www.somewhere.com/svb-webhooks",
    "type": "webhook",
    "url": "/v1/webhooks/101"
}

Create a Webhook

Request:

POST /v1/webhooks

Parameters:

NAME TYPE DESCRIPTION
event_type_ids int array  Ids of event types which cause webhook to trigger.
secret string  Optional client-specified secret key to encrypt requests.
status enum(active,inactive)  Only ‘active’ webhooks will be triggered.
callback_url
required
string  Url to post requset to, must use https.

 

Response:

200 OK The new webhook resource.

Example request:

curl "https://api.svb.com/v1/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -X POST \
  -d '{
        "data": {
          "callback_url": "https://www.somewhere.com/svb-webhooks",
          "event_type_ids": [1],
          "secret": "qwertyuipasdfghjklzxcvbnm1234567890",
          "status": "active"
        }
      }'

Example response:

{
  "data": {
    "id": "123",
    "callback_url": "https://www.somewhere.com/svb-webhooks",
    "event_type_ids": [1],
    "secret": "qwertyuipasdfghjklzxcvbnm1234567890",
    "status": "active",
    "type": "webhook",
    "url": "/v1/webhooks/123"
  }
}

Retrieve a Webhook

For security reasons the hmac secret field is only returned on create.

Request:

GET /v1/webhooks/:id

Response:

200 OK The webhook resource.

Example request:

curl "https://api.svb.com/v1/webhooks/123" \
    -H "Authorization: Bearer YOUR_API_KEY"

Example response:

{
  "data": {
    "id": "123",
    "callback_url": "https://www.somewhere.com/svb-webhooks",
    "event_type_ids": [1],
    "secret": null,
    "status": "active",
    "type": "webhook",
    "url": "/v1/webhooks/123"
  }
}

Update a Webhook

Request:

PATCH /v1/webhooks/:id

Parameters:

NAME TYPE DESCRIPTION
event_type_ids int array  Ids of event types which cause webhook to trigger.
status enum(active,inactive)  Only 'active’ webhooks will be triggered.

Response:

200 OK The updated webhook resource.

Example request:

curl "https://api.svb.com/v1/webhooks/123" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -X PATCH \
    -d '{
          "data": {
            "status": "inactive"
          }
        }'

Example response:

{
  "data": {
    "id": "123",
    "callback_url": "https://www.somewhere.com/svb-webhooks",
    "event_type_ids": [1],
    "secret": null,
    "status": "inactive",
    "type": "webhook",
    "url": "/v1/webhooks/123"
  }
}

Delete a Webhook

Request:

DELETE /v1/webhooks/:id

Response:

204 No Content

Example request:

curl "https://api.svb.com/v1/webhooks/123" \
    -H "Authorization: Bearer YOUR_API_KEY" \
    -X DELETE

List all Webhooks

Request:

GET /v1/webhooks

Response:

200 OK List of webhook resources.

Example request:

curl "https://api.svb.com/v1/webhooks" \
    -H "Authorization: Bearer YOUR_API_KEY"

Example response:

{
  "data": [
    {
      "id": 123,
      "type": "webhooks",
      "url": "/v1/webhooks/123"
    },
    {
      "id": 122,
      "type": "webhook",
      "url": "/v1/webhooks/122"
    },
    {
      "id": 121,
      "type": "webhook",
      "url": "/v1/webhooks/121"
    }
  ],
  "links": {
    "first": "/v1/webhooks",
    "next": null
  }
}

Test a Webhook

To help aid in debugging whether a webhook has been configured correctly, the test route can be used to manually trigger a webhook.

The response status of the callback url will be returned.

Note: - both active and inactive webhooks will be triggered by the test route - event type ids attached to the webhook are ignored - a test type “webhooks.test” will be attached to the webhook payload - an event id of 0 will be attached to the payload, indicating test data - the payload data will return data from the webhook being tested

Request:

GET /v1/webhooks/:id/test

Response:

200 OK Test webhook resource response.

Example request:

curl "https://api.svb.com/v1/webhook/123/test" \
    -H "Authorization: Bearer YOUR_API_KEY"

Example response:

{
  "data": {
    "status": 200
  }
}

Example test webhook request body:

{
  "data": {
    "date": "2017-08-21T16:34:26.330Z",
    "event-id": 0,
    "payload": {
        "id": 123,
        "callback_url": "https://www.api-svb.com/svb-webhooks",
        "event_type_ids": [1],
        "status": "active"
    },
    "type": "webhooks.test"
  }
}

Webhook Retries

Webhooks will be retried anytime we do not receive a successful response from the destination url/server, in other words, if we receive a 5xx response.  We will send the retries a total of 5 times with the following spacing: 

ATTEMPT TIME
First attempt 0
Second attempt  10minutes
Third attempt  28 minutes
Fourth Attempt  78 minutes
Fifth Attempt 108 minutes