Sila API Docs | Sila Banking and Payments API

Welcome to the Sila API!

/link_account

Links a checking or savings bank account to a verified entity, either with a Plaid public token or with account/routing numbers.

❗️

Plaid Public Key (Legacy) Integrations

If you integrated Plaid through the Sila API before May 2021, you may have a legacy integration. This documentation has moved.

If you are using the legacy Plaid public key integration, supporting documentation is here: https://docs.silamoney.com/docs/legacy-plaid-integration

🚧

If you have your own Plaid account and want to link accounts with Sila, please use a processor_token from Plaid's /processor/token/create and pass that processor_token as a "plaid_token" into this endpoint. Learn more here.

This endpoint accepts a token and account ID from a customer's interaction with a Plaid Link modal. Alternatively, we offer a method for direct account linking upon approval of use case by your Sila onboarding team.

At a minimum, your frontend Plaid integration will need to:

  • be set to the "sandbox" environment for sandbox apps, and the "production" environment for production apps.
  • use a link_token generated from /plaid_link_token to initialize Plaid Link
  • retrieve the public_token from the onSuccess() callback of the Plaid Link plugin
  • use our API to send us the public_token and we will query the routing number and account number of the bank account from Plaid and store it securely on our systems
  

Testing Bank Account Linking

In only the sandbox, you can test bank account linking with any bank that shows up in the Plaid Link interface. Specify the username as "user_good" and the password as "pass_good".

In only the sandbox, you can test the scenario when the entity name does not match the account holder name. Set a value of no match (case insensitive) in the ”account_name” field.

Requests

📘

Plaid tokens and token types

In the JSON spec below, the "plaid_token" can be one of: "public-xxx-xxx" or "processor-xxx-xxx". The "plaid_token_type" can be one of: "link", "processor", or "legacy". If you are using Sila's Plaid account , use a public token and indicate a "link" token type. If you have your own Plaid account, use a processor token and indicate a "processor" token type. If you are using Sila's Plaid account with Sila's legacy public_key, use a public token and indicate a "legacy" token type.

POST /0.2/link_account HTTP/1.1
Host: sandbox.silamoney.com
authsignature: [GENERATED AUTHSIGNATURE HEX STRING HERE]
usersignature: [GENERATED USERSIGNATURE HEX STRING HERE]
Content-Type: application/json

{
  "header": {
    "created": 1234567890, 
    "app_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "<your unique id>"
  }, 
  "plaid_token": "processor-xxx-xxx",
  "account_name": "Custom Account Name",
  "selected_account_id": "selected_account_id",
  "plaid_token_type": "processor"
}

***

HTTP/1.1  200 OK

{
  "success": true,
  "status": "SUCCESS",
  "reference": "ref",
  "message": "Bank account successfully linked.",
  "account_name": "Custom Account Name",
  "match_score": 0.825,
  "account_owner_name": "Sally Smith",
  "entity_name": "Sally Smith",
}

***
// Plaid verification flow (recommended)
const res = await Sila.linkAccount(
  userHandle,
  walletPrivateKey,
  token,
  accountName, // Account Name is not required
  accountId, // Account Id parameters is required
);


//Public token received in the /link/item/create plaid endpoint.

// Direct account-linking flow (restricted by use-case, contact Sila for approval)
const res = await Sila.linkAccountDirect(
  userHandle,
  walletPrivateKey,
  accountNumber,
  routingNumber,
  accountName,
  accountType,
); // Account Type and Account Name parameters are not required

//The only permitted account type is "CHECKING"

// Success Response Object
console.log(res.statusCode); // 200
console.log(res.data.reference); // Random reference number
console.log(res.data.status); // SUCCESS
console.log(res.data.success);
console.log(res.data.message); // Bank account successfully linked
console.log(res.data.account_name);
console.log(res.data.match_score);
console.log(res.data.account_owner_name);
console.log(res.data.entity_name);
### Link Account with Plaid
payload = {
    "public_token": "public-development-0dc5f214-56a2-4b69-8968-f27202477d3f",  # Required token from plaid
    "user_handle": "user.silamoney.eth"                                         # Required
    "account_name": "Custom Account Name"                                       # Optional (default value is "default")
    "selected_account_id": "account id",
}                                       # Required

User.linkAccount(silaApp, payload, user_private_key, plaid=True)

### Link Account with Direct Account Linking
payload={
            "user_handle": "user.silamoney.eth",    # Required
            "account_number": "123456789012",       # Required
            "routing_number": "123456789",          # Required
            "account_type": "CHECKING",             # Optional (default value is CHECKING)
            "account_name": "Custom Account Name"   # Optional (default value is "default"),
        }

User.linkAccount(silaApp,payload,user_private_key)

### Success Response Object
{
    status: 'SUCCESS',
    success: True,
    message: 'Bank account successfully manually linked.',
    reference: 'f9f23fc2-26e7-4358-99c8-75cb8aec76fb',
    account_name: 'default',
    status_code: 200,
    match_score: 0.825,
    account_owner_name: 'Sally Smith',
    entity_name: 'Sally Smith'
}

### Failure Response Object
{
    status: 'FAILURE'
}
//NOTE - as of Java SDK v0.2.21, we have refactored requests to make them more flexible 
//for future modifications.  Below are examples of the new method and the original method.  
//The original method will be deprecated at some point in future SDK versions, but is 
//still valid for backwards compatibility purposes.  Please use the new method moving 
//forward as you upgrade your SDK


//The new method (use this moving forward)
// Using plaid token
LinkAccountRequest request = LinkAccountRequest.builder()
    .accountName("defaultpt")
    .plaidToken("Plaid token")
    .selectedAccountId("Plaid account id")
    .userHandle("user handle")
    .userPrivateKey("user private key")
    .build();

LinkAccountResponse response = LinkAccount.send(request);

response.getStatus();
response.getAccountName();
response.getAccountOwnerName();
response.getEntityName();
response.getMessage();
response.getReference();

// For Direct Account Link
LinkAccountRequest request = LinkAccountRequest.builder()
    .accountName("default")
    .accountNumber("123456789012")
    .routingNumber("123456789")
    .accountType("CHECKING")
    .userHandle("user handle")
    .userPrivateKey("user private key")
    .build();

LinkAccountResponse response = LinkAccount.send(request);

response.getStatus();
response.getAccountName();
response.getMessage();
response.getReference();

//--------------------------------------------

//This is the original method (still valid but will soon be deprecated)

String userHandle = 'user.silamoney.eth';
String accountName = 'plaid'; // Your desired account name
String publicToken = 'public-sandbox-xxx' // Your Plaid token
String userPrivateKey = 'some private key';
String accountId = 'plaid account id'; // Required

ApiResponse response = api.linkAccount(userHandle, userPrivateKey, accountName, publicToken, accountId);

// For Direct Account Link
String userHandle = 'user.silamoney.eth';
String accountName = 'direct'; // Your desired account name
String accountNumber = '123456789012';
String routingNumber = '123456789';
String accountType = 'CHECKING'; // Currently the only allowed value
String userPrivateKey = 'some private key';

ApiResponse response = api.linkAccount(userHandle, userPrivateKey, accountName, accountNumber, routingNumber, accountType);

// Success Response
System.out.println(response.getStatusCode()); // 200
LinkAccountResponse parsedResponse = (LinkAccountResponse) response.getData();
System.out.println(parsedResponse.getStatus()); // SUCCESS
System.out.println(parsedResponse.isSuccess()); // true
System.out.println(parsedResponse.getReference()); // Reference number
System.out.println(parsedResponse.getMessage()); // Successfully linked
System.out.println(parsedResponse.getAccountName()); // Your desired account name
System.out.println(parsedResponse.getMatchScore()); // Match score
// **Public token received in the /link/item/create endpoint: https://plaid.com/docs/#integrating-with-link **

// SANDBOX ONLY: You can generate a testing public token instead of using the Plaid Link plugin with:
$client = new \GuzzleHttp\Client(["base_uri" => "https://sandbox.plaid.com"]);
$options = [
    'json' => [
        "public_key" => "fa9dd19eb40982275785b09760ab79",
        "initial_products" => ["transactions"],
        "institution_id" => "ins_109508",
        "credentials" => [
            "username" => "user_good",
            "password" => "pass_good"
        ]
    ]
];
$response = $client->post('/link/item/create', $options);
$content = json_decode($response->getBody()->getContents());
$public_token = $content->public_token; // Public Token to pass to linkAccount()
$account_id = $content->accounts[0]->account_id; // Required Account ID to pass to linkAccount()

// **IMPORTANT!** If you do not specify an `$account_id` in `linkAccount()`, the first account returned by Plaid will be linked by default.

// Plaid token flow
// Load your information
$userHandle = 'user.silamoney.eth';
$accountName = 'Custom Account Name'; // Defaults to 'default'
$publicToken = 'public-xxx-xxx'; // A temporary token returned from the Plaid Link plugin. See above for testing.
$accountId = 'string'; // Recommended but not required. See note above.
$userPrivateKey = 'some private key'; // The private key used to register the specified user

// Call the api
$response = $client->linkAccount($userHandle, $userPrivateKey, $publicToken, $accountName, $accountId);

// Direct Link account
// Load your information
$userHandle = 'user.silamoney.eth';
$accountName = 'Custom Account Name'; // Defaults to 'default' if not provided. (not required)
$routingNumber = '123456789'; // The routing number. 
$accountNumber = '123456789012'; // The bank account number
$userPrivateKey = 'some private key'; // The private key used to register the specified user
$accountType = 'CHECKING'; // The account type (not required). Only available value is CHECKING

// Call the api
$response = $client->linkAccountDirect($userHandle, $userPrivateKey, $accountNumber, $routingNumber, $accountName, $accountType);

// Success 200
echo $response->getStatusCode(); // 200
echo $response->getData()->getStatus(); // SUCCESS
echo $response->getData()->getReference();
echo $response->getData()->getMessage();
echo $response->getData()->getAccountName();
echo $response->getData()->getAccountOwnerName();
//NOTE - as of C# SDK v0.2.21, we have refactored requests to make them more flexible 
//for future modifications.  Below are examples of the new method and the original method.  
//The original method will be deprecated at some point in future SDK versions, but is 
//still valid for backwards compatibility purposes.  Please use the new method moving 
//forward as you upgrade your SDK


//The new method (use this moving forward)
// Public token received in the /link/item/create plaid endpoint.

// Plaid verification flow (recommended)
LinkAccountRequest request = new LinkAccountRequest{
    UserHandle = "user handle",
    UserPrivateKey = "user private key",
    PlaidToken = "plaid token",
    AccountName = "account name",
    SelectedAccountId = "selected account id"
};

LinkAccountResponse response = LinkAccount.Send(request);

response.Success;
response.Account;
response.AccountOwnerName;
response.Message;
response.Reference;
response.Status;
response.MatchScore;
// Account Name is not required 
// Account Id is required

// Direct account-linking flow (restricted by use-case, contact Sila for approval)
LinkAccountRequest request = new LinkAccountRequest{
    UserHandle = "user handle",
    UserPrivateKey = "user private key",
    AccountName = "account name",
    AccountNumber = "account number",
    RoutingNumber = "routing number",
    AccountType = "account type"
};

LinkAccountResponse response = LinkAccount.Send(request);

response.Success;
response.Account;
response.AccountOwnerName;
response.Message;
response.Reference;
response.Status;
response.MatchScore; Account Type and Account Name parameters are not required 

//--------------------------------------
//This is the original method (still valid but will soon be deprecated)

// Public token received in the /link/item/create plaid endpoint.

// Plaid verification flow (recommended)

ApiResponse<object> response = api.LinkAccount(userHandle, publicToken, walletPrivateKey, accountName, accountId); 
// Account Name is not required 
// Account Id is required

// Direct account-linking flow (restricted by use-case, contact Sila for approval)

ApiResponse<object> response = api.LinkAccountDirect(userHandle, walletPrivateKey, accountNumber, routingNumber, accountType, accountName); // Account Type and Account Name parameters are not required 

// Success Response Object

Console.WriteLine(response.StatusCode); // 200
Console.WriteLine(((LinkAccountResponse)response.Data).Reference); // Random reference number
Console.WriteLine(((LinkAccountResponse)response.Data).Status); // SUCCESS
Console.WriteLine(((LinkAccountResponse)response.Data).Message); // Bank account successfully linked.
Console.WriteLine(((LinkAccountResponse)response.Data).AccountName); // Account Name.
Console.WriteLine(((LinkAccountResponse)response.Data).MatchScore);

Key

Type

Description

header

JSON object

Required. Requires these keys in JSON format: created, app_handle, user_handle. See the /check_handle endpoint for the complete list of fields in this object.

plaid_token

String

Required if not setting account_number, routing_number .

If using Sila's Plaid account: Enter a valid public token from the Plaid Link modal consisting of letters, numbers, underscores, or hyphens.

If using your own Plaid account: pass a processor token obtained from Plaid. Example: processor-xxx-xxx.

This value should be match the required regex pattern: ^[-a-zA-Z0-9_]+$

account_name

String

Optional. Min length 1, Max length 40, default value if not sent in request is “default” Example: Custom Account Name
NOTE- We highly recommend specifying a custom name here as this is how an account is identified for /issue_sila, /redeem_sila, and /get_transactions.

selected_account_id

String

Required unless using your own Plaid account and linking with a processor token. This is the Plaid account ID from list of selected account IDs returned from Plaid Link flow.

Max Length 100

account_type

String

Optional. Must match either "CHECKING" or "SAVINGS".

plaid_token_type

String

Optional. Must match either "legacy", "link" or "processor". Default value if not sent in request is “legacy”.

  

The request body for this endpoint is the link_account_msg JSON object.

Both authsignature and usersignature headers are required for this request.

The account_name key is not required, but can be used to set a custom name to identify the linked checking account. If not provided, the linked account's name will be "default". We highly recommend specifying a custom name. Note: user handles cannot have two linked accounts with the same name.

  

For customers using our Plaid verification flow

The plaid_token key is a required field and must contain one of the following types of tokens:

  • a public_token returned from the onSuccess() callback of Plaid Link. In this case, set plaid_token_type to "link".
  • a processor_token from Plaid in the case that you have your own Plaid account already (see Processor Token Integration). In this case, set plaid_token_type to "processor".
  • a public_token generated through the legacy Plaid Link integration. In this case, set plaid_token_type to "legacy".

If plaid_token_type is not specified, this endpoint assumes that provided token is a "legacy" token.

You may also use the alias public_token instead of plaid_token for this endpoint, but specifying both keys in your request will be considered invalid.

The selected_account_id is not required; if provided, it should be an account ID in the array of selected accounts returned in the metadata object from Plaid Link. This ID can identify either a checking account or a savings account to link. Currently, we do not link multiple accounts at once; you will need to send only one account ID. If no account ID is provided, we will link the first checking account we encounter from the array of accounts the customer has at their chosen bank.

  

For customers using our direct account-linking flow

🚧

IMPORTANT NOTICE!

Direct account linking is only available to customers who have a direct relationship with an account linking provider. End users must never be able to enter in their account and routing numbers without verifying account ownership.

The account_type is not required; if not specified, this endpoint assumes that account is a "CHECKING" account. You can also specify that this account is a "SAVINGS" account.

The account_number is required. Must be all numeric character and no longer than 17 characters.

The routing_number is required. Must be numeric and exactly 9 characters long.

  

Responses

Status Code

success Attribute

Description

200

true

Bank account successfully linked.

200

false

Bank account not successfully linked (public token may have expired; tokens expire in 30 minutes after creation).

202

false

Bank account linked, but in a frozen state. Requires manual review - email [email protected] for steps to unfreeze this bank account.

400

false

Check validation_details for more information. PRODUCT_NOT_READY indicates the account is waiting to be linked (with microdeposit verification, for instance).

401

false

authsignature or usersignature header was absent or incorrect.

Updated 13 days ago


/link_account


Links a checking or savings bank account to a verified entity, either with a Plaid public token or with account/routing numbers.

Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.