Manual Account Linking
IMPORTANT!
Manually linking is allowed ONLY for testing ACHNow, RTP, FedNow transactions in Sandbox or with explicit permission from Sila in Production.
This endpoint allows bank accounts can be linked manually rather than through Plaid or MX.
Permission must be given from Sila to allow Production use of this endpoint.
Sandbox ACHNow, RTP, FedNow Testing
A specific routing number is required to successfully transact with RTP and FedNow in Sandbox. So, these accounts will need to be manually linked.
Bank accounts linked normally through Plaid and MX will work as expected for regular ACH transactions and wires in Sandbox.
Testing requirement:
In order to successfully test RTP and FedNow transactions, use the below routing number in this request:
"routing_number": "122105155"
IN PRODUCTION there is no need to manually link bank accounts for successful RTP and FedNow transactions. Link accounts like normal using Plaid or MX.
Request
POST /0.2/link_account HTTP/1.1
Host: sandbox.silamoney.com
// if using OAuth2
Authorization: Bearer [GENERATED JWT TOKEN HERE]
// if using ECDSA
authsignature: [GENERATED AUTHSIGNATURE HEX STRING HERE]
usersignature: [GENERATED USERSIGNATURE HEX STRING HERE]
Content-Type: application/json
{
"header": {
"created": 1234567890,
"app_handle": "app_handle",
"user_handle":"user_handle",
"version": "0.2",
"reference": "ref"
},
"account_number": "123456789012", // required
"routing_number": "123456789", // required
"account_type": "CHECKING",
"account_name": "Custom Account Name"
}
***
HTTP/1.1 200 OK
{
"success": true,
"message": "Bank account successfully linked.",
"reference": "ref",
"account_name": "Custom Account Name",
"payment_instrument_id": "<uuid>",
"provider": "manual",
"web_debit_verified": true,
"capabilities": {
"aba_routing_number": "<routing_number>",
"fednow": {
"credit_enabled": false,
"debit_enabled": false
},
"rtp": {
"credit_enabled": true,
"debit_enabled": true
}
},
"status": "SUCCESS",
"sila_reference_id": "auto-generated uuid"
}
// Direct account-linking flow for receive-only entities only
// 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);
### Direct account-linking flow for receive-only entities only
### Restricted by use-case, contact Sila for approval
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
// Direct account-linking flow for receive-only entities only
// Restricted by use-case, contact Sila for approval
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)
// Direct account-linking flow for receive-only entities only
// Restricted by use-case, contact Sila for approval
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
// Direct account-linking flow for receive-only entities only
// Restricted by use-case, contact Sila for approval
$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
// Direct account-linking flow for receive-only entities only
// 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)
// Direct account-linking flow for receive-only entities only
// 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);
Request Attributes
Key | Type | Description |
---|---|---|
header | JSON object | Required. Required keys: created - Unix epoch timestamp in seconds. Must not be future-dated and must not be dated more than 5 minutes in the past. app_handle - your app handle user_handle - the user_handle this bank account is being linked to. Optional keys: reference: String. Can be any value for your own reference. If not provided, one will be assigned. version: Cannot be null if key is present. Valid values: 0.2, v0.2, V0.2 |
account_number | string | Required. No more than 17 characters. Must be unique per entity. |
routing_number | string | Required. Valid routing number. Use 122105155 to test RTP and FedNow transactions in Sandbox. |
account_type | string | Optional. Valid option: CHECKING |
account_name | string | Optional, but strongly recommended. |
Responses
Status Code | success Attribute | Description |
---|---|---|
200 | true | Bank account successfully linked. |
202 | false | Bank account linked, but in a frozen state. Reach out to Support. |
400 | false | Check validation_details for more information. |
401 | false | authsignature or usersignature header was absent or incorrect. |
Updated 1 day ago