External Bank Accounts
Add and verify external bank accounts to process ACH
An External Bank Account is a bank account outside of Lithic that your program can send or receive funds via ACH. To set-up an External Bank Account, you will provide information on the bank account and owner. Most programs will verify ownership of that bank account via Plaid or micro deposits, while some will have the ability to verify the bank account's information via prenotifications (also known as prenotes). Once enabled, your program can then collect from and send funds to this external bank account via ACH originations with Lithic's Payments API.
Verification Methods
Lithic currently offers two methods to verify ownership of an external bank account: MICRO_DEPOSIT
or PLAID
. MICRO_DEPOSIT
verifies a bank account using small dollar test deposits via ACH. This method works on all bank accounts but generally takes 1-2 business days to complete. PLAID
verifies the bank account of joint Lithic and Plaid customers through Plaid's processor_token
.
Depending on the use case (e.g., in cases where the program cannot or does not need to verify ownership), the ability to use PRENOTE
to validate bank account information may be made available. Prenotes validate the information of the bank account but does not verify ownership.
Micro deposit verification
Micro deposit verification consists of three steps:
-
Your user provides information on the external bank account's owner and the bank account type and routing and account number. Program passes this information to Lithic with a
POST
request to/external_bank_accounts
with theverification_method
set toMICRO_DEPOSIT
. The external bank account enters averification_state
ofPENDING
. -
Lithic sends two small dollar deposits (totaling less than $2) to the external bank account and then immediately collects the sum of both amounts. Both the deposits and the collection can be seen in the external bank account in 1-2 business days.
-
Your user provides the two deposit amounts they see in their bank account, and the program passes this information to Lithic with a
POST
request toexternal_bank_accounts/{external_bank_account_token}/micro_deposits
. If the amounts match, the external bank account will be verified and entered into averification_state
ofENABLED
.
If the incorrect micro deposit amounts are provided more than 5 times, then the external bank account will switch to a state of FAILED_VERIFICATION
and can no longer be verified programmatically. You must provide additional documentation establishing account ownership (e.g., bank statement) to Lithic, and our operations team will manually verify and enable the bank account.
Plaid verification
To use Plaid with Lithic and create a Plaid processor token, first follow the instructions on Plaid's docs. Once you have completed those steps, you should be able to generate a response similar to the one below for an external bank account:
{
"processor_token": "processor-sandbox-0asd1-a92nc",
"request_id": "m8MDnv9okwxFNBV"
}
You should then pass that processor_token
to Lithic with a POST
request to /external_bank_accounts
with the verification_method
set to PLAID
. Lithic will then retrieve the external bank account information from Plaid, generate an External Bank Account object, and set its verification_state
to ENABLED
. If we receive an error message from Plaid, we will return a JSON object containing the Plaid error fields shown below:
{
"error_data": {
"error_code": String,
"error_type": String,
"error_message": String
}
}
Prenote verification
Prenote verification consists of three steps:
- Your user provides information on the external bank account's routing and account number. Program passes this information to Lithic with a
POST
request to/external_bank_accounts
with theverification_method
set toPRENOTE
, and the token of the operating account from which the prenote will originate. The external bank account enters averification_state
ofPENDING
. - Lithic automatically generates a prenote (i.e., a $0 credit) and sends it to the external bank account.
- Lithic lets two banking days pass after the settlement date of the prenote. If by the start of the third banking day no return is received, then that bank account is considered verified and enters into a
verification_state
ofENABLED
.
If a return is generated by the external bank account’s financial institution, then the bank account information is considered invalid, and the external bank account will switch to a state of FAILED_VERIFICATION
and can no longer be verified programatically. You should confirm the bank account details with the end-user and go through the external bank account creation process again.
External Bank Account Lifecycle
An External Bank Account has two lifecycles that are tracked by verification_state
and state
. The former indicates whether an external bank account has been verified by you and is generally finalized during initial set-up. The latter tracks the actual state of the external bank account throughout the lifetime of the account.
For example, an External Bank Account that has a verification_state
of ENABLED
and state
of ENABLED
indicates the account has been verified and can process ACH transactions. If the user decides to close their external bank account at their bank, the External Bank Account state
will change to CLOSED
, but its verification_state
will remain ENABLED
.
External Bank Account Schema
{
"token": String,
"type": String,
"verification_method": String,
"owner_type": String,
"owner": String,
"state": String,
"verification_state": String,
"routing_number": String,
"last_four": String,
"name": String,
"currency": String,
"country": String,
"account_token": String,
"created": String,
"company_id": String,
"processor_token": String,
"dob": Date,
"doing_business_as": String,
"address": Address,
"user_defined_id": String,
"verification_attempts": Integer,
"verification_failed_reason": String
}
token | Globally unique identifier for this record of an external bank account. If an external bank account is linked to multiple end-user accounts or to the program and an end-user account, then Lithic will return each record of the association |
type | CHECKING , SAVINGS |
verification_method | MANUAL , MICRO_DEPOSIT , PLAID , PRENOTE |
owner_type | INDIVIDUAL , BUSINESS |
owner | Legal Name of the business or individual who owns the external account. This will appear in statements |
state | ENABLED , CLOSED , PAUSED |
verification_state | PENDING , ENABLED , FAILED_VERIFICATION , RETURNED_VERIFICATION |
routing_number | Routing number of your external bank account |
last_four | The last 4 digits of the bank account. Derived by Lithic from the account number passed |
name | The nickname given to this record of External Bank Account |
currency | Currency of the external bank account in 3-digit alphabetic ISO 4217 code |
country | The country that the external bank account is located in using ISO 3166-1. Lithic currently only accepts US bank accounts (US) |
account_token | The Lithic end-user account that an external bank account is associated with. For external bank accounts that are associated with the program, account_token field returned will be null |
created | Date and time of when this external bank account was associated with a Lithic end-user account or program |
company_id | Unique identifier assigned to an external bank account by the bank. Lithic utilizes this information to manage ACH receipts |
processor_token | Unique identifier provided by Plaid. Only applicable if verification method is via Plaid |
dob | Date of birth. Only applicable if the owner type is INDIVIDUAL |
doing_business_as | Any name that the BUSINESS or INDIVIDUAL operates under that is not its legal business name (if applicable). |
address | Business's physical address - PO boxes, UPS drops, and FedEx drops are not acceptable; APO/FPO are acceptable. Required only if the owner type is BUSINESS . See Address Schema. |
user_defined_id | Additional metadata provided by customers that may help with reconciliation against other systems |
verification_attempts | Number of attempts to verify external bank account |
verification_failed_reason | Optional additional context behind a failed or returned verification. For micro-deposits that are returned by the ACH network, this field will be populated with the return reason code e.g. R01 |
Address Schema
address1 | Valid deliverable address (no PO boxes) |
address2 | Unit or apartment number (if applicable) |
city | City name |
state | Valid state code. Only USA state codes are currently supported |
postal_code | Valid postal code. Only USA ZIP codes are currently supported |
country | Country name. Only US is currently supported |
Create external bank account
POST https://api.lithic.com/v1/external_bank_accounts
Sample Request: Plaid Verification
curl https://api.lithic.com/v1/external_bank_accounts \
-X POST \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '
{
"verification_method": "PLAID",
"owner_type": "BUSINESS",
"owner": "John Doe LLC",
"processor_token": "processor-sandbox-0asd1-a92nc"
}
'
verification_method (required) | PLAID |
owner_type (required) | Indicates whether bank account is a consumer or commercial account String. Permitted values: INDIVIDUAL , BUSINESS |
owner (required) | Legal Name of the business or individual who owns the external account String. Permitted values: 1-100 characters. |
account_token (optional) | The Lithic end-user account that the external bank account is associated with. String. Permitted values: 36-digit version 4 UUID (including hyphens). |
company_id (optional) | Unique identifier assigned to an external bank account by the bank. String. Permitted values: 1-10 characters. |
user_defined_id (optional) | Additional metadata provided by customers that may help with reconciliation against other systems String. Permitted values: 1-512 characters. |
processor_token (required) | Plaid processor token. String |
dob (required) | Date of birth. Required only if the owner type is INDIVIDUAL String. RFC 3339 format (yyyy-MM-dd). |
doing_business_as (optional) | Any name that the BUSINESS or INDIVIDUAL operates under that is not its legal business name (if applicable).String. |
Sample Request: Micro Deposit or Prenote Verification
curl https://api.lithic.com/v1/external_bank_accounts \
-X POST \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '
{
"verification_method": "MICRO_DEPOSIT",
"financial_account_token": "f2f74f63-d4b3-4f51-b40e-7156b45a1e56",
"owner_type": "BUSINESS",
"owner": "John Doe LLC",
"type": "CHECKING",
"routing_number": "021000021",
"account_number": "123456789",
"name": "Funding Account",
"country": "USA",
"currency": "USD",
"address": {
"address1": "456 Main Street",
"city": "New York",
"state": "NY",
"postal_code": "10128",
"country": "USA"
}
}
'
type (required) | Type of bank account; Lithic advises using checking accounts only String. Permitted values: CHECKING , SAVINGS |
verification_method (required) | MICRO_DEPOSIT or PRENOTE |
financial_account_token (required) | Token representing the operating account that is originating the micro deposit or prenote. String. Permitted values: 36-digit version 4 UUID (including hyphens). |
owner_type (required) | Indicates whether bank account is a consumer or commercial account String. Permitted values: INDIVIDUAL , BUSINESS |
owner (required) | Legal Name of the business or individual who owns the external account String. Permitted values: 1-100 characters. |
routing_number (required) | Routing number of your external bank account String. Permitted values: Valid US Bank Routing Number. |
account_number (required) | Account number of your external bank account String. Permitted values: Valid US Bank Account Number. |
name (optional) | The nickname given to this record of external bank account String. Permitted values: 1-50 characters. |
currency (required) | Currency of the external bank account in ISO 4217 code String. Permitted values: USD . |
country (required) | The country that the external bank account is located in using ISO 3166-1. String. Permitted values: USA . |
account_token (optional) | The Lithic end-user account that the external bank account is associated with. String. Permitted values: 36-digit version 4 UUID (including hyphens). |
company_id (optional) | Unique identifier assigned to an external bank account by the bank. String. Permitted values: 1-10 characters. |
user_defined_id (optional) | Additional metadata provided by customers that may help with reconciliation against other systems String. Permitted values: 1-512 characters. |
dob (required) | Required only if the owner type is INDIVIDUAL Date of birth. String. RFC 3339 format (yyyy-MM-dd). |
doing_business_as (optional) | Any name that the BUSINESS or INDIVIDUAL operates under that is not its legal business name (if applicable).String. |
address (required) | Required only if the owner type is BUSINESS .Business's physical address - PO boxes, UPS drops, and FedEx drops are not acceptable; APO/FPO are acceptable. Only USA addresses are currently supported. Object. Valid address object. |
Address Schema in Requests
address1 (required) | Valid deliverable address (no PO boxes) String. Max length 40 |
address2 (optional) | Unit or apartment number (if applicable) String. Max length 40 |
city (required) | City name String. Max length 40 |
state (required) | Valid state code. Only USA state codes are currently supported String. Entered in uppercase ISO 3166-2 two-character format |
postal_code (required) | Valid postal code. Only USA ZIP codes are currently supported String. Entered as a five-digit ZIP or nine-digit ZIP+4. |
country (required) | Country name. Only USA is currently supported String. ISO 3166-1 |
Sample Response
{
"token": "2da0a808-de12-4b42-b413-ca736d6892c5",
"type": "CHECKING",
"verification_method": "MICRO_DEPOSIT",
"owner_type": "BUSINESS",
"owner": "John Doe LLC",
"state": "ENABLED",
"verification_state": "PENDING",
"routing_number": "021000021",
"last_four": "6789",
"name": "Funding Account",
"country": "USA",
"currency": "USD",
"account_token": "4998a704-636f-4d79-97da-478ea19b152a",
"created": "2020-07-15T19:17:22Z",
"company_id": "0924752",
"user_defined_id": "ABC",
"verification_attempts": 1,
"verification_failed_reason": "",
"address": {
"address1": "456 Main Street",
"city": "New York",
"state": "NY",
"postal_code": "10128",
"country": "USA"
}
}
List external bank accounts
GET https://api.lithic.com/v1/external_bank_accounts
Sample Request
curl https://api.lithic.com/v1/external_bank_accounts \
-H 'AUTHORIZATION: YOUR_API_KEY'
Sample Response
{
"data": [
"token": "2da0a808-de12-4b42-b413-ca736d6892c5",
"type": "CHECKING",
"verification_method": "MICRO_DEPOSIT",
"owner_type": "BUSINESS",
"owner": "John Doe LLC",
"state": "ENABLED",
"verification_state": "PENDING",
"routing_number": "021000021",
"last_four": "6789",
"name": "Funding Account",
"country": "USA",
"currency": "USD",
"account_token": "4998a704-636f-4d79-97da-478ea19b152a",
"created": "2020-07-15T19:17:22Z",
"company_id": "0924752",
"user_defined_id": "ABC",
"verification_attempts": 1,
"verification_failed_reason": "",
"address": {
"address1": "456 Main Street",
"city": "New York",
"state": "NY",
"postal_code": "10128",
"country": "USA"
}
],
"has_more": false
}
account_token (optional) | The Lithic end-user account that the external bank account is associated with. String. Permitted values: 36-digit version 4 UUID (including hyphens). |
owner_types (optional) | Query by types of owner Array of Strings. Permitted values: INDIVIDUAL , BUSINESS |
account_types (optional) | Query by types of external bank account Array of Strings. Permitted values: CHECKING , SAVINGS |
states (optional) | Query by states of external bank account Array of Strings. Permitted values: ENABLED , CLOSED , PAUSED |
verification_states (optional) | Query by verification states of the external bank account record Array of Strings. Permitted values: PENDING , ENABLED , FAILED_VERIFICATION |
countries (optional) | Query by countries using ISO 3166-1. Array of Strings. Permitted values: ISO 3166-1 code. |
page_size (optional, query parameter) | For cursor-based pagination - specifies the number of entries to be included on each page in the response. Default value is 100. Integer. Permitted values: 1-100. |
starting_after (optional, query parameter) | For cursor-based pagination - specifies the next object in a list to be returned. Requests can only use either starting_after or ending_before. For example, you have a list of 100 Financial Transaction objects where the first entry is UUID abcd and last entry is UUID wxyz . A request of starting_after = abcd and page_size = 100 will return 99 results (abcd is excluded from the response)String. Permitted values: 36-digit version 4 UUID (including hyphens). |
ending_before (optional, query parameter) | For cursor-based pagination - specifies the last object in a list to be returned. Requests can only use either starting_after or ending_before. For example, you have a list of 100 Financial Transaction objects where the first entry is UUID abcd and last entry is UUID wxyz . A request of ending_before = wxyz and page_size = 100 will return the full list of 100String. Permitted values: 36-digit version 4 UUID (including hyphens) |
Get external bank account
GET https://api.lithic.com/v1/external_bank_accounts/{external_bank_account_token}
Sample Request
curl https://api.lithic.com/v1/external_bank_accounts/2da0a808-de12-4b42-b413-ca736d6892c5 \
-H 'AUTHORIZATION: YOUR_API_KEY'
Sample Response
{
"token": "2da0a808-de12-4b42-b413-ca736d6892c5",
"type": "CHECKING",
"verification_method": "MICRO_DEPOSIT",
"owner_type": "BUSINESS",
"owner": "John Doe LLC",
"state": "ENABLED",
"verification_state": "PENDING",
"routing_number": "021000021",
"last_four": "6789",
"name": "Funding Account",
"country": "USA",
"currency": "USD",
"account_token": "4998a704-636f-4d79-97da-478ea19b152a",
"created": "2020-07-15T19:17:22Z",
"company_id": "0924752",
"user_defined_id": "ABC",
"verification_attempts": 1,
"verification_failed_reason": "",
"address": {
"address1": "456 Main Street",
"city": "New York",
"state": "NY",
"postal_code": "10128",
"country": "USA"
}
}
external_bank_account_token (required, path parameter) | Globally unique identifier for the external bank account record that should be returned. String. Permitted values: 36-digit version 4 UUID (including hyphens). |
Patch external bank account
PATCH https://api.lithic.com/v1/external_bank_accounts/{external_bank_account_token}
Sample Request
curl https://api.lithic.com/v1/external_bank_accounts/2da0a808-de12-4b42-b413-ca736d6892c5 \
-X PATCH \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '
{
"owner": "John Doe INC",
"name": "Corporate Funds",
"company_id": "1234567",
}
'
Sample Response
{
"token": "2da0a808-de12-4b42-b413-ca736d6892c5",
"type": "CHECKING",
"verification_method": "MICRO_DEPOSIT",
"owner_type": "BUSINESS",
"owner": "John Doe INC",
"state": "ENABLED",
"verification_state": "PENDING",
"routing_number": "021000021",
"last_four": "6789",
"name": "Corporate Funds",
"country": "USA",
"currency": "USD",
"account_token": "4998a704-636f-4d79-97da-478ea19b152a",
"created": "2020-07-15T19:17:22Z",
"company_id": "1234567",
"user_defined_id": "ABC",
"verification_attempts": 1,
"verification_failed_reason": "",
"address": {
"address1": "456 Main Street",
"city": "New York",
"state": "NY",
"postal_code": "10128",
"country": "USA"
}
}
external_bank_account_token (required, path parameter) | Globally unique identifier for the external bank account record that should be patched. String. Permitted values: 36-digit version 4 UUID (including hyphens). |
owner_type (optional) | INDIVIDUAL , BUSINESS |
owner (optional) | Legal Name of the business or individual who owns the external account String. Permitted values: 1-100 characters. |
name (optional) | The nickname given to this record of external bank account String. Permitted values: 1-50 characters. |
company_id (optional) | Unique identifier assigned to an external bank account by the bank. String. Permitted values: 1-10 characters. |
dob (optional) | Date of birth. String. RFC 3339 format (yyyy-MM-dd). |
doing_business_as (optional) | Any name that the BUSINESS or INDIVIDUAL operates under that is not its legal business name (if applicable).String. |
user_defined_id (optional) | dditional metadata provided by customers that may help with reconciliation against other systems String. Permitted values: 1-512 characters. |
address (optional) | Business's physical address - PO boxes, UPS drops, and FedEx drops are not acceptable; APO/FPO are acceptable. Only USA addresses are currently supported. Object. Valid address object. |
Verify via micro deposit
If you are testing in sandbox, please enter the micro deposit amounts of 19 and 89.
POST https://api.lithic.com/v1/external_bank_accounts/{external_bank_account_token}/micro_deposits
Sample Request
To complete onboarding for an external bank account added via micro deposit verification, you will need your users to provide the two small-dollar amounts deposited into their bank account and submit these amounts to Lithic via a POST
request similar to the one below:
curl https://api.lithic.com/v1/external_bank_accounts/2da0a808-de12-4b42-b413-ca736d6892c5/micro_deposits \
-X POST \
-H "Authorization: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '
{
"micro_deposits": ["19", "89"]
}
'
Sample Response
If the amounts posted match the amounts deposited, the verification_state
of the external bank account will update to ENABLED
:
{
"token": "2da0a808-de12-4b42-b413-ca736d6892c5",
"type": "CHECKING",
"verification_method": "MICRO_DEPOSIT",
"owner_type": "BUSINESS",
"owner": "John Doe INC",
"state": "ENABLED",
"verification_state": "ENABLED",
"routing_number": "021000021",
"last_four": "6789",
"name": "Corporate Funds",
"country": "USA",
"currency": "USD",
"account_token": "4998a704-636f-4d79-97da-478ea19b152a",
"created": "2020-07-15T19:17:22Z",
"company_id": "1234567",
"user_defined_id": "ABC",
"verification_attempts": 1,
"verification_failed_reason": ""
}
external_bank_account_token (required, path parameter) | Globally unique identifier for the external bank account record that needs to be verified via micro deposits String. Permitted values: 36-digit version 4 UUID (including hyphens). |
micro_deposits (required) | The two deposits (totaling less than $1) that your users see in their bank accounts. Array of Strings Permitted values: two values. |
Events API and Webhooks
You can receive notification of External Bank Account events by subscribing to the following event types in the Events API:
external_bank_account.created
: notification that an external bank account resource has been createdexternal_bank_account.updated
: notification that an external bank account has been updated e.g., name change
Updated 4 months ago