Overview

A large number Modern Treasury's integrations are asynchronous in nature and do not take effect immediately. Primarily this is due to how the underlying systems operate (e.g. file-based messaging over FTP) but it also allows Modern Treasury to efficiently batch its communications to the bank. Fewer files often translates into lower costs and less operational overhead.

To make dealing with these systems easier, the Modern Treasury API is built around the idea of sending important updates over HTTP webhooks. These endpoints can be configured through the webhooks settings page inside the application and apply to the entire organization. If needed, separate URLs may be provided for live and test traffic.

Technical Details

All endpoints must be configured to receive a HTTP POST with a JSON payload. The webhook system will wait a maximum 5 seconds for a 2XX HTTP status code in order to mark the payload as delivered. If the endpoint takes longer to respond or an error is returned, the webhook will be re-enqueued for delivery at a later time subject to an exponential backoff.

All endpoints are strongly encouraged to use HTTPS as this protects the payload in-transit.

Authentication

To verify that a webhook was actually sent by Modern Treasury, every payload is signed with a signature that is passed through as the HTTP header X-Signature. The signature is Hex encoded and can be replicated by applying HMAC-SHA-256 to the body of the webhook with your specific webhook key, which can be found in your webhook settings page.

Please contact support if your webhook key is accidentally made public. We will rotate the key and coordinate the change with you.

IP addresses

Modern Treasury's IP addresses are included below if you would like to verify the transmission IP as part of a webhook receipt solution.

52.35.210.16
52.13.201.237
52.35.218.169
35.162.115.65

Webhook Idempotency

Each webhook has a unique ID. This is passed through as the HTTP header X-Webhook-ID. You can save these IDs as you process webhooks to ensure each webhook is only processed once. If a webhook is sent multiple times, its ID will remain the same between requests.

Live vs Test

When making API calls that invoke webhooks, the endpoint URL will depend on whether the live or test key was used. If you want to use the same URL for both live and test webhooks, you can still differentiate using the HTTP header X-Live-Mode which is true for live traffic and false for test traffic.

Topics

Each webhook payload contains a topic that describes which category the event belongs to. This is passed through as the HTTP header X-Topic.

Topic

Description

balance_report

Any balance report lifecycle event.

external_account

Any external account lifecycle event.

expected_payment

Any expected payment lifecycle event.

paper_item

Any paper item lifecycle event.

payment_order

Any payment order lifecycle event.

return

Any return lifecycle event.

reversal

Any reversal lifecycle event.

transaction

Any transaction lifecycle event.

incoming_payment_detail

Any incoming payment detail lifecycle event.

ledger_transaction

Any ledger transaction lifecycle event.

Contents and Structure

Webhook skeleton

All Modern Treasury webhooks have the same top level structure.

  • event specifies what happened to the object.
  • data contains the updated object that changed.
{
  "event": "event_type",
  "data": {
    // serialized object
  }
}

Sample webhook headers

{
  "Content-Length": "464",
  "Content-Type": "application/json",
  "X-Topic": "paper_item",
  "X-Event-ID": "f8651bc8-6862-49c1-9a1a-7ff5ea7aa228",
  "X-Live-Mode": "true",
  "X-Signature": "62d1745dcb53d510963cfb9d3588109903a9ff2cb895ea0f59e5ed38472f6ac8",
  "X-Webhook-ID": "7b5bc00751e4c9760974ee85",
  "X-Delivery-ID": "0413352f-93df-4a4a-851b-2baaa47b4fe5",
  "X-Organization-ID": "<ORGANIZATION_ID>",
  "X-Internal-Signature": "884ee247af1d1d5b0c7122c3e69e1aadf7f83f16c992ea6c7fe557679e7753db",
  "User-Agent": "http.rb/4.2.0"
}

Sample webhook body

{
  "event": "created",
  "data": {
    "account_number": "222222223",
    "amount": 9900,
    "check_number": "11",
    "created_at": "2019-12-12T22:34:59Z",
    "currency": "USD",
    "deposit_date": "2019-12-12",
    "id": "9e5c22be-2145-4da4-963f-b0434765d18f",
    "lockbox_number": "12345",
    "memo_field": "Christmas Tip",
    "object": "paper_item",
    "remitter_name": "Cristina Angela",
    "routing_number": "021000021",
    "status": "pending",
    "transaction_id": null,
    "transaction_line_item_id": null,
    "updated_at": "2019-12-12T22:34:59Z"
  }
}