Create a Subscription

Create a subscription for user, node, and transaction webhooks

Information in our system is constantly changing and updating, long after API calls have been made. A user could be flagged on a sanctions list after it was marked verified, a node’s balance could update after a payment has posted, or a transaction could be queued a little while after the transaction was created. You can subscribe to webhooks to receive updates on users, nodes and transactions automatically.

API Endpoint

https://uat-api.synapsefi.com/v3.1/subscriptions

PATH PARAMETER

url:
required
string

Webhook URL

scope:
required
array of strings

Scope of the subscription

BODY PARAMETER

_id :
String

Object ID of a subscription object

_links.self.href :
string

HAL style link for the subscription object

client_id :
String

ID of the client who the subscription belongs to

is_active :
boolean

This lets you toggle the subscription as active and inactive

url :
string

URL for the webhooks

scope :
array of strings

Scope of the subscription

Scope Syntax

Scope tells us when this webhook should be triggered. Following are the ways you can supply scope for subscriptions.

Only one subscription can be enabled for each scope. So if you had multiple subscription objects, we recommend disabling subscriptions that you do not wish to use any longer.

Scope
Effect

NODE|POST

Whenever a Node is created with your gateway credentials, you will receive a webhook.

NODE|PATCH

Whenever a node is updated with your gateway credentials, you will receive a webhook.

USER|POST

Whenever a user is created with your gateway, you will receive a webhook.

USER|PATCH

Whenever a user in your platform is updated, you will receive a webhook.

TRANS|POST

Whenever a transaction is created within your gateway credentials, you will receive a webhook.

TRAN|PATCH

Whenever a transaction is updated with your gateway credentials, you will receive a webhook.

Example Request

POST /v3.1/subscriptions HTTP/1.1
Host: uat-api.synapsefi.com
X-SP-GATEWAY: client_id_2bb1e412edd311e6bd04e285d6015267|client_secret_2bb1e714edd311e6bd04e285d6015267
Content-Type: application/json

{
  "scope": [
    "USERS|POST",
    "USER|PATCH",
    "NODES|POST",
    "NODE|PATCH",
    "TRANS|POST",
    "TRAN|PATCH"
  ],
  "url": "https://requestb.in/zp216zzp"
}
webhook_url = "https://requestb.in/zp216zzp"
scope =  [
  "USERS|POST",
  "USER|PATCH",
  "NODES|POST",
  "NODE|PATCH",
  "TRANS|POST",
  "TRAN|PATCH"
]

subs = client.create_subscription(webhook_url, scope)
const subscriptionUrl = 'https://requestb.in/zp216zzp';

client.createSubscription('<SUBSCRIPTION_URL>');
body = {
  "scope": [
    "USERS|POST",
    "USER|PATCH",
    "NODES|POST",
    "NODE|PATCH",
    "TRANS|POST",
    "TRAN|PATCH"
  ],
  "url": "https://requestb.in/zp216zzp"
}

client.create_subscriptions(scope: body)
$body = (object) [
     scope" => [
       "USERS|POST",
       "USER|PATCH",
       "NODES|POST",
       "NODE|PATCH",
       "TRANS|POST",
       "TRAN|PATCH"
     ],
      'url' => 'https://requestb.in/zp216zzp'
];

$client->create_subscription( $body );
body := `{
  "scope": [
    "USERS|POST",
    "USER|PATCH",
    "NODES|POST",
    "NODE|PATCH",
    "TRANS|POST",
    "TRAN|PATCH"
  ],
  "url": "https://requestb.in/zp216zzp"
}`

data, err := client.CreateSubscription(body)

Example Successful 200 Response

{
    "_id": "589b6adec83e17002122196c",
    "_links": {
        "self": {
            "href": "https://uat-api.synapsefi.com/v3.1/subscriptions/589b6adec83e17002122196c"
        }
    },
    "_v": 2,
    "client_id": "589acd9ecb3cd400fa75ac06",
    "is_active": true,
    "scope": [
        "USERS|POST",
        "USER|PATCH",
        "NODES|POST",
        "NODE|PATCH",
        "TRANS|POST",
        "TRAN|PATCH"
    ],
    "url": "https://requestb.in/zp216zzp"
}

HMAC FOR WEBHOOKS

Every webhook will be signed with HMAC.

HMAC is a protocol that helps you judge the authenticity of the received message. This comes in handy when you want to quickly find out whether the web hook was sent by SynapsePay or a malicious/notorious party.

The signature is a SHA-1 and SHA-256 HMAC hash of the object_id + your client_id, with the secret key as your client_secret.

You will be able to rebuild the signature the following way:

import hmac 
from hashlib import sha1, sha256

key = 'your_client_secret'
raw = '{0}+{1}'.format(payload['_id']['$oid'],'your_client_id')

hashed_sha1 = hmac.new(key, raw, sha1)
hashed_sha256 = hmac.new(key, raw, sha256)

# The signature
print hashed_sha1.hexdigest()
print hashed_sha256.hexdigest()

Please note that raw should look like this (with +):
"563db3fb86c27307d925871f+e3f19e4bd4022c86e7f2"

Not like this (without +):
"563db3fb86c27307d925871fe3f19e4bd4022c86e7f2".

Since the sha1 signature is in hex, it should look like this: bce964c20b0c36313d8f7cffc2ff4772d0c96750.

We then take this signature and add it into the header of the request with name X-Synapse-Signature and X-Synapse-Signature-Sha256.

Webhook Format

The webhook always returns a user, node, or transaction object. These are the same as the objects returned by the API responses, with a couple exceptions:

  • The value of ids are objects storing an $oid, which is the object ID.
  • The value of dates are objects storing a $date.

If you wish to consume exactly the same responses as you get from the API, look under key _rest. If you also want to see who the object was updated by and what function was used to perform the update, look under webhook_meta.

{
  "documents": [
    {
      "permission_scope": "SEND|RECEIVE|1000|DAILY",
      "social_docs": [
        {
          "last_updated": {
            "$date": 1498312100872
          },
          "document_type": "FACEBOOK",
          "status": "SUBMITTED|VALID",
          "id": "8f314a6a53f36ee569455761e49a2a7fe790d251c5611c65255befdb303602b7"
        },
        {
          "last_updated": {
            "$date": 1498312100872
          },
          "document_type": "PHONE_NUMBER",
          "status": "SUBMITTED|VALID",
          "id": "fda60784d6375bc44edafaaeae149626c4c13dcb92e85a2a7a00eec2cdfd2b6f"
        },
        {
          "last_updated": {
            "$date": 1498312100872
          },
          "document_type": "EMAIL",
          "status": "SUBMITTED|VALID",
          "id": "2c45158f6431ca874bbe82f63d5905567854dde4d8b81539944e5779e5eee741"
        },
        {
          "last_updated": {
            "$date": 1498312100872
          },
          "document_type": "IP",
          "status": "SUBMITTED|VALID",
          "id": "28d9177b22c127d9a51d8903893864accf6e553ac326704a4c0d585eaad2516a"
        }
      ],
      "physical_docs": [
        {
          "last_updated": {
            "$date": 1498312100869
          },
          "document_type": "GOVT_ID",
          "status": "SUBMITTED|VALID",
          "id": "4d9f76fd95d00f501b6c9ab307948438b7f03ddd5b7d57300db8889cf5c44b9f"
        }
      ],
      "name": "Test User",
      "id": "2a4a5957a3a62aaac1a0dd0edcae96ea2cdee688ec6337b20745eed8869e3ac8",
      "virtual_docs": [
        {
          "last_updated": {
            "$date": 1498312100867
          },
          "document_type": "SSN",
          "status": "SUBMITTED|VALID",
          "id": "ee596c2896dddc19b76c07a184fe7d3cf5a04b8e94b9108190cac7890739017f"
        }
      ]
    }
  ],
  "phone_numbers": [
    "[email protected]",
    "901.111.1111"
  ],
  "doc_status": {
    "virtual_doc": "SUBMITTED|VALID",
    "physical_doc": "SUBMITTED|VALID"
  },
  "webhook_meta": {
    "updated_by": "BACKEND",
    "function": "USER|PATCH"
  },
  "permission": "SEND-AND-RECEIVE",
  "_rest": {
    "documents": [
      {
        "permission_scope": "SEND|RECEIVE|1000|DAILY",
        "social_docs": [
          {
            "last_updated": 1498312100872,
            "document_type": "FACEBOOK",
            "status": "SUBMITTED|VALID",
            "id": "8f314a6a53f36ee569455761e49a2a7fe790d251c5611c65255befdb303602b7"
          },
          {
            "last_updated": 1498312100872,
            "document_type": "PHONE_NUMBER",
            "status": "SUBMITTED|VALID",
            "id": "fda60784d6375bc44edafaaeae149626c4c13dcb92e85a2a7a00eec2cdfd2b6f"
          },
          {
            "last_updated": 1498312100872,
            "document_type": "EMAIL",
            "status": "SUBMITTED|VALID",
            "id": "2c45158f6431ca874bbe82f63d5905567854dde4d8b81539944e5779e5eee741"
          },
          {
            "last_updated": 1498312100872,
            "document_type": "IP",
            "status": "SUBMITTED|VALID",
            "id": "28d9177b22c127d9a51d8903893864accf6e553ac326704a4c0d585eaad2516a"
          }
        ],
        "physical_docs": [
          {
            "last_updated": 1498312100869,
            "document_type": "GOVT_ID",
            "status": "SUBMITTED|VALID",
            "id": "4d9f76fd95d00f501b6c9ab307948438b7f03ddd5b7d57300db8889cf5c44b9f"
          }
        ],
        "name": "Test User",
        "id": "2a4a5957a3a62aaac1a0dd0edcae96ea2cdee688ec6337b20745eed8869e3ac8",
        "virtual_docs": [
          {
            "last_updated": 1498312100867,
            "document_type": "SSN",
            "status": "SUBMITTED|VALID",
            "id": "ee596c2896dddc19b76c07a184fe7d3cf5a04b8e94b9108190cac7890739017f"
          }
        ]
      }
    ],
    "phone_numbers": [
      "[email protected]",
      "901.111.1111"
    ],
    "doc_status": {
      "virtual_doc": "SUBMITTED|VALID",
      "physical_doc": "SUBMITTED|VALID"
    },
    "permission": "SEND-AND-RECEIVE",
    "logins": [
      {
        "email": "[email protected]",
        "scope": "READ_AND_WRITE"
      }
    ],
    "is_hidden": false,
    "legal_names": [
      "Test User"
    ],
    "_id": "594e6da41acea2002e666987",
    "client": {
      "name": "SynapseFI",
      "id": "589acd9ecb3cd400fa75ac06"
    },
    "photos": [],
    "emails": [],
    "extra": {
      "extra_security": false,
      "is_business": false,
      "cip_tag": 1,
      "date_joined": 1498312095716,
      "public_note": null,
      "last_updated": 1498312100856,
      "supp_id": "122eddfgbeafrfvbbb"
    }
  },
  "logins": [
    {
      "email": "[email protected]",
      "scope": "READ_AND_WRITE"
    }
  ],
  "is_hidden": false,
  "legal_names": [
    "Test User"
  ],
  "_id": {
    "$oid": "594e6da41acea2002e666987"
  },
  "client": {
    "name": "SynapseFI",
    "id": "589acd9ecb3cd400fa75ac06"
  },
  "photos": [],
  "emails": [],
  "extra": {
    "extra_security": false,
    "is_business": false,
    "cip_tag": 1,
    "date_joined": {
      "$date": 1498312095716
    },
    "public_note": null,
    "last_updated": {
      "$date": 1498312100856
    },
    "supp_id": "122eddfgbeafrfvbbb"
  }
}
{
  "allowed": "CREDIT-AND-DEBIT",
  "timeline": [
    {
      "date": {
        "$date": 1498312299937
      },
      "note": "Node created."
    },
    {
      "date": {
        "$date": 1498312300555
      },
      "note": "Micro deposits initiated."
    },
    {
      "date": {
        "$date": 1498312309798
      },
      "note": "Correct Micro Deposit amounts attempted. Node's 'allowed' changed to 'CREDIT-AND-DEBIT'"
    }
  ],
  "is_active": true,
  "info": {
    "bank_long_name": "BANK OF AMERICA",
    "routing_num": "0017",
    "class": "CHECKING",
    "account_num": "2134",
    "bank_name": "BANK OF AMERICA",
    "balance": {
      "amount": "0.00",
      "currency": "USD"
    },
    "address": "8001 VILLA PARK DRIVE, HENRICO, VA, US",
    "match_info": {
      "email_match": "not_found",
      "phonenumber_match": "not_found",
      "name_match": "not_found"
    },
    "type": "PERSONAL",
    "name_on_account": " ",
    "nickname": "Fake Account"
  },
  "webhook_meta": {
    "function": "NODE|PATCH",
    "updated_by": "SELF"
  },
  "_rest": {
    "allowed": "CREDIT-AND-DEBIT",
    "timeline": [
      {
        "date": 1498312299937,
        "note": "Node created."
      },
      {
        "date": 1498312300555,
        "note": "Micro deposits initiated."
      },
      {
        "date": 1498312309798,
        "note": "Correct Micro Deposit amounts attempted. Node's 'allowed' changed to 'CREDIT-AND-DEBIT'"
      }
    ],
    "is_active": true,
    "info": {
      "bank_long_name": "BANK OF AMERICA",
      "routing_num": "0017",
      "class": "CHECKING",
      "account_num": "2134",
      "bank_name": "BANK OF AMERICA",
      "balance": {
        "amount": "0.00",
        "currency": "USD"
      },
      "address": "8001 VILLA PARK DRIVE, HENRICO, VA, US",
      "match_info": {
        "email_match": "not_found",
        "phonenumber_match": "not_found",
        "name_match": "not_found"
      },
      "type": "PERSONAL",
      "name_on_account": " ",
      "nickname": "Fake Account"
    },
    "_id": "594e6e6c12e17a002f2e39e4",
    "client": {
      "id": "589acd9ecb3cd400fa75ac06",
      "name": "SynapseFI"
    },
    "type": "ACH-US",
    "extra": {
      "supp_id": "ABC124"
    },
    "user_id": "594e6da41acea2002e666987"
  },
  "_id": {
    "$oid": "594e6e6c12e17a002f2e39e4"
  },
  "client": {
    "id": "589acd9ecb3cd400fa75ac06",
    "name": "SynapseFI"
  },
  "type": "ACH-US",
  "extra": {
    "supp_id": "ABC124"
  },
  "user_id": "594e6da41acea2002e666987"
}
{
  "timeline": [
    {
      "status": "CREATED",
      "note": "Transaction Created.",
      "status_id": "1",
      "date": {
        "$date": 1498312348440
      }
    }
  ],
  "webhook_meta": {
    "updated_by": "BACKEND",
    "function": "TRAN|PATCH"
  },
  "fees": [
    {
      "fee": 0.2,
      "note": "Synapse Facilitator Fee",
      "to": {
        "id": {
          "$oid": "55b3f8c686c2732b4c4e9df6"
        }
      }
    }
  ],
  "amount": {
    "currency": "USD",
    "amount": 20.1
  },
  "_rest": {
    "timeline": [
      {
        "status": "CREATED",
        "note": "Transaction Created.",
        "status_id": "1",
        "date": 1498312348440
      }
    ],
    "fees": [
      {
        "fee": 0.2,
        "note": "Synapse Facilitator Fee",
        "to": {
          "id": "55b3f8c686c2732b4c4e9df6"
        }
      }
    ],
    "_v": 2,
    "from": {
      "user": {
        "legal_names": [
          "Test User"
        ],
        "_id": "594e6da41acea2002e666987"
      },
      "type": "ACH-US",
      "nickname": "Fake Account",
      "id": "594e6e6c12e17a002f2e39e4"
    },
    "_id": "594e6e9c4599e8002fe62e3c",
    "client": {
      "name": "SynapseFI",
      "id": "589acd9ecb3cd400fa75ac06"
    },
    "to": {
      "user": {
        "legal_names": [
          "Test User"
        ],
        "_id": "594e6da41acea2002e666987"
      },
      "type": "ACH-US",
      "nickname": "Fake Account",
      "id": "594e6e6c12e17a002f2e39e4"
    },
    "recent_status": {
      "status": "CREATED",
      "note": "Transaction Created.",
      "status_id": "1",
      "date": 1498312348440
    },
    "extra": {
      "note": "Test transaction",
      "created_on": 1498312348440,
      "process_on": 1498312348440,
      "supp_id": "1122444",
      "ip": "192.168.0.1",
      "latlon": "0,0"
    },
    "amount": {
      "currency": "USD",
      "amount": 20.1
    }
  },
  "extra": {
    "note": "Test transaction",
    "created_on": {
      "$date": 1498312348440
    },
    "process_on": {
      "$date": 1498312348440
    },
    "supp_id": "1122444",
    "ip": "192.168.0.1",
    "latlon": "0,0"
  },
  "_v": 2,
  "_id": {
    "$oid": "594e6e9c4599e8002fe62e3c"
  },
  "client": {
    "name": "SynapseFI",
    "id": "589acd9ecb3cd400fa75ac06"
  },
  "to": {
    "user": {
      "legal_names": [
        "Test User"
      ],
      "_id": {
        "$oid": "594e6da41acea2002e666987"
      }
    },
    "type": "ACH-US",
    "nickname": "Fake Account",
    "id": {
      "$oid": "594e6e6c12e17a002f2e39e4"
    }
  },
  "recent_status": {
    "status": "CREATED",
    "note": "Transaction Created.",
    "status_id": "1",
    "date": {
      "$date": 1498312348440
    }
  },
  "from": {
    "user": {
      "legal_names": [
        "Test User"
      ],
      "_id": {
        "$oid": "594e6da41acea2002e666987"
      }
    },
    "type": "ACH-US",
    "nickname": "Fake Account",
    "id": {
      "$oid": "594e6e6c12e17a002f2e39e4"
    }
  }
}

Webhook Logistics

If for some reason we fail to deliver a webhook to you, we will continue trying to send the request every hour until we are successful in delivering the webhook, up to 24 hours. After that, we will log the webhook and make it available for viewing on our dashboard. That way, even if we fail to deliver the request, you can still access the original request and the reason as to why the webhook failed.

A webhook delivery is considered a failure if your server does not respond with one of the following HTTP codes: 200, 204, 400, 404, 405.

Testing Webhooks

Tools like https://webhook.site/ are helpful when testing webhooks