SVB requires HMAC signing for access to ACH, VCN, Counterparties and Webhooks APIs.
Request signing uses a second secret key that is never transmitted over the wire to SVB API, mitigating two additional attack vectors:
(1) an attacker is unable to replay a previous request
(2) an attacker is unable to modify the API request during transmission


To sign a request, you’ll need a few things:

  • a crypto library that supports HMAC-SHA-256;
  • your secret HMAC signing key;
  • your HTTP request contents; and
  • the current time (from a reasonably accurate clock).

The signature is calculated using the following fields:

secret string HMAC secret key from SVB, provided as a string FNAqNywCi0hmo845Ni43p06mx3l4ub7C
timestamp int Number of seconds since the Unix epoch 1490041002
method string HTTP method as an upper case string POST
path string Path to the resource /v1/vcn
params string Params passed in the URL (if any) foo=bar&baz=quux
body string Body of the request (if any) See below














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
    The signature is:
HEX( HMAC( your_secret_key,
           timestamp + "\n" +
           method + "\n" +
           path + "\n" +
           query + "\n" +
           body ))


  • body is only used for JSON bodies with the application/json type. if the body is any other type or is missing, then an empty string should be used instead.
  • path always begins with a slash.
  • query omits the leading question mark, and is an empty string if there is no query string.



After calculating the signature, add the following two HTTP headers to your request:

  • X-Timestamptimestamp, from step (2) above
  • X-Signature: the request signature

For a request to be considered valid, it must have a timestamp within 30 seconds of the server’s time as well as a valid signature.


Code Samples and Examples

SVB API documentation includes Python and Postman examples to simplify client integrations. There are sample Python code snippets and Postman collections for each API product, on the respective API product page. 

HMAC Postman Pre-Request Script

HMAC signing is a required step when accessing SVB APIs from Postman.

  • SVB Postman collections already include the HMAC signing script as a "pre-request" script.
    The script can be accessed through clicking  "Edit"on collection and  navigating to "pre-request script"tab. 

    For reference, pre-request script is included below:

    Note: Signature variable on the below Postman script is the secret that is shared by the SVB team. If Postman script is used, there is no need to manually add X-Signature and X-Timestamp on the request headers.

    let apigee = 1;
    var signature = "";
    const { Property, Url } = require('postman-collection');
    var moment = require("moment")
    var requestTimeStamp = moment(new Date().toUTCString()).valueOf() / 1000;
    let resolvedUrl = Property.replaceSubstitutions(pm.request.url.toJSON(), 
    pm.variables.toObject()),newUrl = new Url(resolvedUrl);
    var dataUrl = requestTimeStamp + "\n" + pm.request.method + "\n" + 
    newUrl.getPath() + "\n" + newUrl.getQueryString() + "\n";
    while (dataUrl.indexOf("{{") >= 0) {
     var variableName = dataUrl.substring(dataUrl.indexOf("{{") + 2, 
     var variableValue = pm.globals.get(variableName);
     dataUrl = dataUrl.replace("{{" + variableName + "}}", variableValue);
    while (apigee && dataUrl.indexOf("[") >= 0) {
     dataUrl = dataUrl.replace("[", "%5B")
    while (apigee && dataUrl.indexOf("]") >= 0) {
     dataUrl = dataUrl.replace("]", "%5D")
    while (apigee && dataUrl.indexOf("\"") >= 0) {
     dataUrl = dataUrl.replace("\"", "%22")
    if (pm.request.body)
     dataUrl = dataUrl.concat(pm.request.body);
    var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA256, signature);
    var hash = hmac.update(dataUrl).finalize();
    pm.request.headers.add({ 'key': 'X-Timestamp', 'value': requestTimeStamp });
    pm.request.headers.add({ 'key': 'X-Signature', 'value': '' + hash });

Once the account is ready, update credentials (api_key and secret) on the sandbox or production environment variables.
Note: Production api key will be denoted by the "live_" string in the beginning of the api key.