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:

  1. 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 the verification_method set to MICRO_DEPOSIT. The external bank account enters a verification_state of PENDING.

  2. 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.

  3. 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 to external_bank_accounts/{external_bank_account_token}/micro_deposits. If the amounts match, the external bank account will be verified and entered into a verification_state of ENABLED.

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:

  1. 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 the verification_method set to PRENOTE, and the token of the operating account from which the prenote will originate. The external bank account enters a verification_state of PENDING.
  2. Lithic automatically generates a prenote (i.e., a $0 credit) and sends it to the external bank account.
  3. 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 of ENABLED.

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	
}

tokenGlobally 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
typeCHECKING, SAVINGS
verification_methodMANUAL, MICRO_DEPOSIT, PLAID, PRENOTE
owner_typeINDIVIDUAL, BUSINESS
ownerLegal Name of the business or individual who owns the external account. This will appear in statements
stateENABLED, CLOSED, PAUSED
verification_statePENDING, ENABLED, FAILED_VERIFICATION, RETURNED_VERIFICATION
routing_numberRouting number of your external bank account
last_fourThe last 4 digits of the bank account. Derived by Lithic from the account number passed
nameThe nickname given to this record of External Bank Account
currencyCurrency of the external bank account in 3-digit alphabetic ISO 4217 code
countryThe country that the external bank account is located in using ISO 3166-1. Lithic currently only accepts US bank accounts (US)
account_tokenThe 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
createdDate and time of when this external bank account was associated with a Lithic end-user account or program
company_idUnique identifier assigned to an external bank account by the bank. Lithic utilizes this information to manage ACH receipts
processor_tokenUnique identifier provided by Plaid. Only applicable if verification method is via Plaid
dobDate of birth. Only applicable if the owner type is INDIVIDUAL
doing_business_asAny name that the BUSINESS or INDIVIDUAL operates under that is not its legal business name (if applicable).
addressBusiness'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_idAdditional metadata provided by customers that may help with reconciliation against other systems
verification_attemptsNumber of attempts to verify external bank account
verification_failed_reasonOptional 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

address1Valid deliverable address (no PO boxes)
address2Unit or apartment number (if applicable)
cityCity name
stateValid state code. Only USA state codes are currently supported
postal_codeValid postal code. Only USA ZIP codes are currently supported
countryCountry 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 100
String. 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 created
  • external_bank_account.updated: notification that an external bank account has been updated e.g., name change