Quickstart

Want to make your first Helix API call ASAP? You've come to the right place. Helix is highly configurable and many features can be toggled on or off depending on the program you're looking to build. We've set up an example program with some of the most common settings and features enabled so you can begin testing right now. In this example we will walk through how to onboard a new customer, open an account on Helix, and fund it.

Credentials

Domain: https://sandbox-api.helix.q2.com
API Key / Username: example1
API Secret / Password: example1

1. Get your program settings

Click to expand
  • Endpoint: /program/get
  • Description: This step is not required, but it’s an easy first API call!
curl --request GET \
     --url https://sandbox-api.helix.q2.com/program/get \
     --header 'Accept: application/json' \
     --header 'Authorization: Basic ZXhhbXBsZTE6ZXhhbXBsZTE='

Note the products array on the returned program object. There are many sample products configured in this environment. For this workflow we are going to use productId=19797713 (in a later step).

{
  "data": {
    ...
    "products": [
      ...
      {
        "balanceLimit": {
          "maximumAmount": 999999999.0
        },
        "category": "Checking",
        "description": "Sample Checking no KYC",
        "interestRates": [],
        "isExternalWithdrawEnabled": true,
        "isRecurringContributionEnabled": true,
        "name": "Sample Checking no KYC",
        "perTransactionDepositLimit": {
          "maximumAmount": 999999999.0,
          "minimumAmount": 0.01
        },
        "perTransactionWithdrawLimit": {
          "maximumAmount": 999999999.0,
          "minimumAmount": 0.01
        },
        "productId": 19797713,
        "type": "Checking"
      },
      ...
    ],
    ...
  },
  "errors": [],
  "requestId": "3e33ae23-6e74-45f7-bcbd-957f14ed82ca",
  "status": 200
}

2(a). Fetch a list of bank documents

Click to expand
curl --request GET \
     --url https://sandbox-api.helix.q2.com/bankDocument/list/culture \
     --header 'Accept: application/json' \
     --header 'Authorization: Basic ZXhhbXBsZTE6ZXhhbXBsZTE='

This endpoint returns metadata for all available bank documents.

{
  "data": [
    {
      "bankId": 212,
      "culture": "en-US",
      "customerId": 9049,
      "documentId": 13550052,
      "documentType": "eStatement",
      "downloadUrl": "https://sandbox-api.corepro.io/bankdocument/download/en-US/13550052",
      "effectiveDate": "2021-01-10T00:00:00.000-06:00",
      "expireDate": "9999-12-31T23:59:59.999+00:00",
      "html": "<p><b>E-Sign Disclosure</b></p>\r\n\t\t<p>This is an example e-Sign document.</p>",
      "programId": 9049,
      "title": "Example Bank eStatement"
    },
    {
      "bankId": 212,
      "culture": "en-US",
      "customerId": 9049,
      "documentId": 240684,
      "documentType": "PrivacyPolicy",
      "downloadUrl": "https://sandbox-api.corepro.io/bankdocument/download/en-US/240684",
      "effectiveDate": "2014-01-01T00:00:00.000+00:00",
      "html": "<p>Rev 08 2014</p>\r\n\t\t<p>This is an example Privacy Policy document.</p>",
      "programId": 9049,
      "title": "Example Privacy Policy"
    },
    {
      "bankId": 212,
      "culture": "en-US",
      "customerId": 9049,
      "documentId": 240683,
      "documentType": "TermsAndConditions",
      "downloadUrl": "https://sandbox-api.corepro.io/bankdocument/download/en-US/240683",
      "effectiveDate": "2014-01-01T00:00:00.000+00:00",
      "html": "<p><b>TERMS AND CONDITIONS OF YOUR ACCOUNT </b></p>\r\n\t\t<p>This is an example Terms and Conditions document.</p>",
      "programId": 9049,
      "title": "Example Terms and Conditions"
    },
    {
      "bankId": 212,
      "culture": "en-US",
      "customerId": 9049,
      "documentId": 13550055,
      "documentType": "TruthInSavings",
      "downloadUrl": "https://sandbox-api.corepro.io/bankdocument/download/en-US/13550055",
      "effectiveDate": "2021-01-09T00:00:00.000-06:00",
      "html": "<p>Example Savings Account</p>\r\n\t\t<p>This is an example Truth In Savings document.</p>",
      "programId": 9049,
      "title": "Example Truth In Savings"
    }
  ],
  "errors": [],
  "requestId": "eae7c3e6-0d51-43a9-93bb-9f6e292d21b3",
  "status": 200
}

2(b). Download a specific bank document

Click to expand
  • Endpoint: /bankDocument/download
  • Description: Download the content of a specific bank document to display to the customer.
curl --request GET \
     --url https://sandbox-api.helix.q2.com/bankDocument/download/en-US/240684 \
     --header 'Accept: application/json' \
     --header 'Authorization: Basic ZXhhbXBsZTE6ZXhhbXBsZTE='

This endpoint returns a file content object. Your application must display this content and provide a way for the customer to agree.

{
  "data": {
    "content":"JVBERi0xLjUNCiW1tbW1DQoxIDAgb2JqDQo8PC9U ...",
    "contentLength":309103,
    "contentType":"application/pdf"
  },
"errors": [],
"requestId": "a45add02-43bb-4d82-b49c-231089996405",
"status": 200
}

3. Collect the customer's information and pass it to Helix

Click to expand
  • Endpoint: /customer/create
  • Description: The information you are required to collect from each customer will depend on your program settings. For our example program, the following pieces of information are required: firstName, lastName, birthDate, address (type=Residence), emailAddress, taxId, phone (type=Mobile).
curl --request POST \
     --url https://sandbox-api.helix.q2.com/customer/create \
     --header 'Accept: application/json' \
     --header 'Authorization: Basic ZXhhbXBsZTE6ZXhhbXBsZTE=' \
     --header 'Content-Type: application/json' \
     --data '
{
     "addresses": [
          {
               "addressLine1": "1 Rural Rt. 6",
               "addressType": "Residence",
               "city": "Honesdale",
               "country": "US",
               "state": "PA",
               "postalCode": "18431"
          }
     ],
     "phones": [
          {
               "number": "7175550177",
               "phoneType": "Mobile"
          }
     ],
     "firstName": "Dwight",
     "lastName": "Schrute",
     "birthDate": "1970-1-20T00:00:00.000+00:00",
     "taxId": "123456789",
     "emailAddress": "[email protected]",
     "isSubjectToBackupWithholding": false,
     "isOptedInToBankCommunication": true,
     "isDocumentsAccepted": true
}
'

This endpoint returns a customerId which we will use later in this workflow.

{
  "data": {
    "customerId": 19872058,
    "messages": [],
    "questions": [],
   "verificationStatus": "success"
  },
  "errors": [], 
  "requestId": "744f8536-e688-4487-8feb-96622277107d",
  "status": 200
}

4. Run KYC on the customer

Click to expand
  • Endpoint: /customer/onboard (not publicly documented)
  • Description: Helix provides a real-time KYC solution via /customer/onboard, however, the behavior of /customer/onboard can vary depending on your program settings and thus is not documented publicly. In this example workflow we are using a sample product that does not require KYC - so we can skip this step for the sake of this example workflow. Please note that any program offering full DDA or savings accounts will be required to perform this step.

5. Open a bank account for the customer

Click to expand
  • Endpoint: /account/create
  • Description: Using productId=19797713 from step 1 and the customerId returned from step 3 we can now create an account for the customer. All Helix accounts are associated to a product object which holds various account settings.
curl --request POST \
     --url https://sandbox-api.helix.q2.com/account/create \
     --header 'Accept: application/json' \
     --header 'Authorization: Basic ZXhhbXBsZTE6ZXhhbXBsZTE=' \
     --header 'Content-Type: application/json' \
     --data '
{
     "customerId": 19872058,
     "name": "Main Checking",
     "productId": 19797713
}
'

This endpoint returns the full account object. Note the accountId since we will use it later in this workflow.

{
  "data": {
    ...
    "accessTypeCode": "FULL",
    "accountBalance": 0.0,
    "accountId": 19872303,
    "accountNumber": "91299633",
    "accountNumberMasked": "*************9633",
    "availableBalance": 0.0,
    "balanceLastModifiedDate": "2021-07-26T13:13:35.745-05:00",
    "createdDate": "2021-07-26T13:13:35.485-05:00",
    "customerId": 19872058,
    "isCloseable": true,
    "isLocked": false,
    "isPrimary": true,
    "lastModifiedDate": "2021-07-26T13:13:35.670-05:00",
    "lockReasonTypeCode": "UNK",
    "lockTypeCode": "UNL",
    "name": "Main Checking",
    "pendingBalance": 0.0,
    "primaryCustomerId": 19872058,
    "productId": 19797713,
    "routingNumber": "073923033",
    "routingNumberMasked": "*****3033",
    "status": "Open",
    "tag": "",
    "type": "Checking"
    ...
  },
  "errors": [],
  "requestId": "4a665112-3e5b-493c-a3f0-f100f5cc0ae4",
  "status": 200
}

6. Link the customer's external account

Click to expand
  • Endpoint: /externalAccount/create
  • Description: Before we can initiate funds transfers to/from a customer's account we must verify customer ownership of an external account. Most of our clients use an IAV service such as Plaid to instantly verify external account ownership and this is the scenario we will imitate in this example workflow. Once an external account is verified via an IAV service simply pass the account number, routing number, and a few other pieces of information to the /externalAccount/create route.
curl --request POST \
     --url https://sandbox-api.helix.q2.com/externalAccount/create \
     --header 'Accept: application/json' \
     --header 'Authorization: Basic ZXhhbXBsZTE6ZXhhbXBsZTE=' \
     --header 'Content-Type: application/json' \
     --data '
{
     "customerId": 19872058,
     "routingNumber": "123456789",
     "accountNumber": "1111444422222",
     "firstName": "Dwight",
     "lastName": "Schrute",
     "type": "Checking"
}
'

This endpoint returns a full external account object. Note the externalAccountId since we will use it later in this workflow.

{
  "data": {
    "accountNumberMasked": "*************2222",
    "customerId": 19872058,
    "customField1": "",
    "customField2": "",
    "customField3": "",
    "customField4": "",
    "customField5": "",
    "externalAccountId": 19872933,
    "firstName": "Dwight",
    "isActive": true,
    "isLocked": false,
    "lastModifiedDate": "2021-07-26T13:27:57.973-05:00",
    "lastName": "Schrute",
    "lockedReason": "",
    "name": "COREPRO SANDBOX BANK",
    "nickName": "COREPRO SANDBOX BANK",
    "nocCode": "",
    "routingNumberMasked": "*****6789",
    "status": "Verified",
    "statusDate": "2021-07-26T13:27:57.973-05:00",
    "tag": "",
    "type": "Checking"
  },
  "errors": [],
  "requestId": "b3377ef7-aafa-4700-aa5a-ec9f12f79029",
  "status": 200
}

Helix also natively supports micro deposit verification. Please see Verifying External Accounts for more details.


7. Fund the customer's Helix account

Click to expand
  • Endpoint: /transfer/create
  • Description: Once you have created an account and verified an external account, you can initiate ACH transfers via Helix. For this example workflow, use the externalAccountId from step 6 as the fromId and the accountId from step 5 as the toId. You can choose any amount you like as no actual money movement occurs in sandbox.
curl --request POST \
     --url https://sandbox-api.helix.q2.com/transfer/create \
     --header 'Accept: application/json' \
     --header 'Authorization: Basic ZXhhbXBsZTE6ZXhhbXBsZTE=' \
     --header 'Content-Type: application/json' \
     --data '
{
     "amount": 350,
     "customerId": 19872058,
     "fromId": 19872933,
     "toId": 19872303
}
'

This endpoint returns a transfer response object containing the transactionId of the corresponding transaction. Please see Transfer Timeline for details on how and when transfers will settle.

{
  "data": [
    {
      "customerId": 19872058,
      "masterId": 2447985493,
      "tag": "",
      "transactionId": 2447985494
    }
  ],
  "errors": [],
  "requestId": "76f915b9-1753-495e-b334-8921ff9cefd9",
  "status": 200
}

Congratulations! You have successfully onboarded a customer, opened a new account and funded it!

Want to do more? Try some of these: