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
- Endpoint: /bankDocument/list
- Description: Customers must agree to all bank documents as part of the onboarding process.
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 thecustomerId
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 thefromId
and theaccountId
from step 5 as thetoId
. You can choose anyamount
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:
- Issue then verify a debit card for the customer's Helix account
- Fetch the customer's data in Helix
- Get a list of transactions for the customer's Helix account
- Lock the customer's Helix account
- Unlock the customer's Helix account