NAV Navbar
specs javascript python java go

Introduction

There is no code for this section.

Welcome to the Sila API!

Sila allows you to build financial applications quickly and easily. Our API endpoints enable:

We will soon be adding support for card payments, business ID verification, and international payments.

By using us to build financial applications, you can:

Quickstart

By following the steps in this section, you will be able to:

Developer Registration

STEPS:

  1. Registration includes a KYC verification process, which should take less than 24 hours. Register by visiting : https://console.silamoney.com/register
    NOTE: Do not use spaces in your Handle.
  2. You will receive an email to confirm your account. Click the link that is sent to you.
  3. Clicking the link will open a login window. Log in with the credentials you provided in step 1.
  4. Now that you are logged in, let’s create Ethereum keys!

Generating Ethereum Keys

In order to create an app and authenticate API calls, you will need Ethereum public and private keys. There are a number of ways you can create the keys if you do not have them already. One way is to use myetherwallet.com. Another way is to use a browser extension named MetaMask which is detailed below.

Key Generation Using MetaMask and Chrome

  1. Visit https://metamask.io/
  2. Click 'GET CHROME EXTENSION' to open the Chrome web store.
  3. Click 'Add to Chrome'
  4. A confirmation dialog is launched. Confirm by Clicking 'Add extension'
  5. A welcome screen will launch. Click 'Get Started'
  6. Click 'Yes, let’s get set up!'
  7. You will now see an Opt-in screen for data collection. Choose the option you feel comfortable with.
  8. You are now asked to create a password. Choose one and keep it in a safe place.
  9. After checking the disclosure box and clicking 'Create', a Secret Backup Phrase screen is launched.
  10. Click the grayed box to reveal secret words. Follow the tips on the right.
  11. Click 'Next'. You now need to confirm the phrase that was disclosed to you on the previous screen.
  12. Hopefully, you are now at a Congratulations screen. Click 'All Done'
  13. You are now on your wallet screen.

Retrieving your Public Key using MetaMask

  1. To launch MetaMask, click the MetaMask icon at the top left of Chrome. (it looks like an orange fox)
  2. You may be prompted for a password, sign in if necessary.
  3. Click the account name at the top center of the MetaMask window and your public key will be copied to your clipboard.

The format of your Public Key will be similar to the below. Note that it could be in all uppercase or mixed-case, but will always start with 0x
0xC2D7CF95645D33006175B78989035C7c9061d3F9

Retrieving your Private Key using MetaMask

  1. To launch MetaMask, click the MetaMask icon at the top left of Chrome. (it looks like an orange fox)
  2. You may be prompted for a password, sign in if necessary.
  3. Click the three dots to the right of your account name and select 'Account Details'.
  4. Click 'Export Private Key'.
  5. Enter your password and click 'Confirm'.
  6. Click to copy your Private Key and keep it somewhere safe.

The format of your Private Key will look similar to the below and may be in all UPPERCASE. Note that it does NOT start with 0x.
3a1076bf45ab87712ad64ccb3b10217737f7faacbf2872e88fdd9a537d8fe266

NOTE: Keep these app private keys secure; leave them out of your source code and never store them in an unsafe place. If they are ever compromised, please immediately replace your app keys using the Developer Console.

Registering an App

  1. Visit: https://console.silamoney.com/apps/new
  2. Give your application a unique Handle, avoiding special characters and spaces.
    NOTE: If you choose a handle that already exists you will not be able to register your app.
  3. Enter your Ethereum Address.
    NOTE: Your Ethereum Address is your Public Key obtained through the 'Generating Ethereum Keys' section.
  4. Click 'Submit'. It will validate for a few seconds and your app will be created.

Installing the SDK Demo

  1. Clone the Node SDK Demo app to a local directory. The app is available here: https://github.com/Sila-Money/sila-sdk-demo
  2. Follow the instructions in the README file to install and run the SDK demo.
  3. Visit http://localhost:3000 to interact with the demo app.

Using the SDK Demo

Before we use the SDK Demo, let's take a moment to review how we authenticate API requests.
Sila uses Elliptic Curve Digital Signature Algorithm (ECDSA) for authentication of API requests. We do not use API keys or OAuth routines as is common. ECDSA provides an additional layer of security not possible with other methods.

When you start building your own app WE STRONGLY RECOMMEND USING THE CODE EXAMPLES FOR AUTHENTICATION AVAILABLE HERE TO ENSURE YOUR MESSAGES ARE BEING PROPERLY SIGNED.

Now back to using the Sila SDK Demo.
1. To set your authentication parameters, click the 'Settings' button. We will be setting parameters for Prod (the Settings screen will open to this environment by default). 2. Enter your Auth Handle. It is easiest to cut and paste it from the Developer Console HERE. Make sure you grab the full handle, ending in .app.silamoney.eth. 3. Enter your Auth Key. This is the Private Key that is associated with the Public Key used when creating your app. You can access your Private Key by following the instructions in the 'Generating Ethereum Keys' section.
NOTE: the private key you enter is never sent over the network, it is only used locally to sign API requests. 5. Click 'Update App Authentication'.

You are now ready to use the Demo SDK.

The first two actions that would normally be performed to create a new user would be to 1. Check to see if a user handle is available. If the handle is available... 2. Register the user & kick off the KYC process

Both of these actions can be performed by using the Sila SDK Demo app, with API responses shown.

Basic Concepts

Getting Started

To use our API endpoints, you will need to get registered on our Developer Console, have an Ethereum public/private key pair, and have an app registered. The actions to do this are outlined in detail in the Quickstart section.

Endpoint Flow

This section describes a high-level overview of how our API might be used and the order in which our endpoints might be called.

User Registration

The first step is typically to register a new User. Every user added to an application must have their own public-private key pair and handle (along with KYC information so that we can send them through a KYC verification process).

KYC information required to register users in this version of the API:

  1. Generate a private key for the user. You can have them generate and manage it themselves (in a wallet such as Metamask or MyEtherWallet) if desired.
  2. Either randomly generate a handle for the user, or allow the user to pick a handle for themselves. Handles have to be globally unique, so they should be checked against the /check_handle endpoint for availability.
  3. The user must pass in their required KYC information and the public key derived from the user's private key. This information should be used to populate a /register request.
  4. It may take some time for the KYC process to complete. A success response from /register only means that the verification process has started, not that the user has been verified. Subsequent /check_kyc requests are the only way to know whether the person's information has been verified.

Bank Account Linking

Bank account linking is provided through our partner, Plaid.

On the client side of your application, integrate Plaid Link, obtain the public token from your user's interaction with the interface, then send it on to our /link_account endpoint.

In order to make public tokens that we can use, you will need to use our public key in your Plaid calls. You should gain access to this key when you register. Check out our demo app to see what other parameters we use!

Currently, responses at the /link_account endpoint are synchronous, meaning that a success response indicates a successfully-linked bank account.

Token Transfers

The SILA token is used to exchange USD value among users. For example, this would be the process of transferring $51.73 from user A to user B:

  1. Users A and B successfully pass KYC in our system.
  2. Users A and B successfully link their bank accounts.
  3. /issue_sila is called for user A, requesting issuance of 5173 SILA to their Ethereum address.
  4. $51.73 is debited from A's bank account via ACH and sent to our backend, where it will be traded for US Treasuries.
  5. When the $51.73 transaction is marked as "finally settled," which takes 2-3 business days, 5173 SILA are minted at user A's Ethereum address.
  6. During this process, you can poll /get_transactions to check the status of this transaction.
  7. When user A has 5173 SILA, those SILA can be transferred to user B's address either with the /transfer_sila endpoint or directly on our ERC-20 smart contract(which will incur variable "gas costs" in Ethereum for which the developer is responsible). The transaction can only be tracked with /get_transactions if the /transfer_sila endpoint was called; otherwise, you can use something like Etherscan to monitor the transaction yourself.
  8. When user B has 5173 SILA at their address, they can then have /redeem_sila called for them, requesting 5173 SILA to be redeemed.
  9. 5173 SILA are immediately burned from B's address and the process of crediting $51.73 to their linked bank account from our backend is started. (If crediting fails, perhaps due to the bank account being closed, the transaction will be rolled back, thus re-minting the SILA at B's address.)
  10. Thus, A has been debited $51.73 and B has been credited $51.73.

Initializing SDKs

Currently-available SDKs:

- Python
- Node/JavaScript
// No SDK available in Java yet. Check back later!
// No SDK available in Go yet. Check back later!

While the API is accessible via HTTP requests through any language, we have provided some official SDKs to simplify implementation.

If there is an SDK available for our example languages, the code snippets in these docs will use it.

Node/JavaScript SDK

// Installation:
npm i sila-sdk

// Usage:
sila = require('sila-sdk/lib/index.js');

sila.configure({
    appKey: APPLICATION_PRIVATE_KEY,
    appHandle: APPLICATION_HANDLE,
})

// Switch to production when app is enabled for access;
// SDK uses the sandbox environment by default.
//sila.disableSandbox();

The current version is designed as a singleton, so you will need to use require to use the library.

Then, set up the private key and handle for the SDK to use for signing subsequent requests with configure. The other SDK functionality will not be available until this configuration is completed. The SDK does not store this information outside of the instance that is configured. It is never transmitted over the network or stored outside the scope of that instance.

For simplicity and consistency, all API calls return a Promise. All success and failure responses are passed into the .then() callback method. Only unhandled errors such as network issues, etc., are handled in the .catch() callback.

Installation and configuration instructions can be found here.

Python SDK

# Installation:
pip3 install silasdk

# Usage:
from silasdk import App
from silasdk import User
from silasdk import Transaction

silaApp = App("SANDBOX", app_private_key, app_handle)

Version 0.2 requires Python version >= 3.6. This SDK abstracts the signature piece for signing the messages locally using users' private keys. github link

Initialization sets up the app private key and handle for the SDK to use for signing subsequent requests. The other SDK functionality will not be available until this configuration is completed. The SDK does not store this information outside of the instance that is configured. Private keys are never transmitted over the network or stored outside the scope of that instance.

Installation and configuration instructions can be found here.

Production Access

When you sign up through the developer console and obtain an app key, you will immediately be granted sandbox access. This means that you will be able to authenticate requests made to the sandbox.silamoney.com domain. However, requests made to our sandbox will not move any real money, and the resulting SILA tokens will be on a testnet contract, not a mainnet contract.

When you've tested your implementation, you can request production access for an app key through the Developer Console. If production access is granted, you will be able to make successful requests to the api.silamoney.com domain.

Sila HTTPS Domains

Environment Domain Description
Sandbox sandbox.silamoney.com Requests to this domain will not result in actual KYC verification or real-money transfers. Tokens will be on a Rinkeby testnet contract.
Production api.silamoney.com Requests to this domain must use real KYC verification data; transaction requests will result in real-money transfers. Tokens will be on a mainnet contract.

Authentication

Pick a language tab for a signature generation example.

1. Import a library for hashing and signing.
2. Get appropriate private key to use in signature.
3. Marshal request body to JSON, producing a "message."
    * If just testing signatures locally, you can use an example string.
4. Hash message with the Keccak-256 algorithm.
5. Sign the hash with the private key, producing a "signature."
6. Check and adjust results with further steps if needed.
    * Remove 0x prefix from signature hex string if present.
    * Check for an offset issue (last few characters will differ from expected results).
    * If there is an offset issue:
        - Do hex arithmetic to figure out the difference between expected and actual results.
        - When producing signatures, add the discovered offset.
        - Make sure corrected signature strings are 130 characters long.
// JavaScript authentication example:

// For this example, we will use a library for message signing.
// See: https://github.com/pubkey/eth-crypto
const EthCrypto = require('eth-crypto');

// You will need a message (request body contents) and a private key.
// This private key will be an Ethereum private key, hex-encoded 
// and 64 characters in length, omitting any "0x" that might precede it.
var private_key = 'badba7368...c0202a97c';
var messageJSON = { test: 'message' };

// Stringify the message. (The string that gets hashed should be
// guaranteed to be the same as what is sent in the request.)
// NOTE: if testing the example strings, you can just declare them as
// strings, e.g. var message = 'Sila';
var message = JSON.stringify(messageJSON);

// Generate the message hash using the Keccak 256 algorithm.
var msg_hash = EthCrypto.hash.keccak256(message);

// Create a signature using your private key and the hashed message.
var signature = EthCrypto.sign(private_key, messageHash);

// The EthCrypto library adds a leading '0x' which should be removed 
// from the signature.
signature = signature.substring(2);

// The raw message should then be sent in an HTTP request body, and the signature
// should be sent in a header.
var request_data = {};
request_data.headers.signature = signature;
request_data.body = message;

//...
# Python authentication example:

# For this example, we will use a library for message signing.
# See: https://github.com/ethereum/eth-account
from eth_account import Account
import sha3
import json

# You will need a message (request body contents) and a private key.
# This private key will be an Ethereum private key, hex-encoded 
# and 64 characters in length, omitting any "0x" that might precede it.
key = 'badba7368...c0202a97c'
msg = {
    'test': 'message'
}

# Stringify the message. (The string that gets hashed should be
# guaranteed to be the same as what is sent in the request.)
# NOTE: if testing the example strings, you can just declare them as strings.
encoded_message = (json.dumps(msg)).encode("utf-8")

# Generate the message hash using the Keccak 256 algorithm.
k = sha3.keccak_256()
k.update(encoded_message)
message_hash = k.hexdigest()

# Sign the message_hash.
signed_message = Account.signHash(message_hash, key)
sig_hx = signed_message.signature.hex()

# replace 0x with empty string
signature = str(sig_hx.replace("0x","")))

# Use encoded_message in the request body and sig_hx
# in the appropriate signature header.
print(signature)
print(encoded_message)

#...

# You can also sign messages with the Sila-Python SDK.

from silasdk import EthWallet

EthWallet.signMessage("my_message", "private_key")
// No signing example here yet. Check back later!
// Go authentication example:

package main

import (
    "encoding/hex"
    "encoding/json"
    "log"
    "math/big"

    // For this example, we will use a library for message signing.
    // See: https://github.com/ethereum/go-ethereum/crypto
    "github.com/ethereum/go-ethereum/crypto"
)

func main() {
    // You will need a message (the contents of the request body
    // you will send) and a private key.
    // This private key will be an ethereum private key. In this 
    // example, it should be a hex string 64 characters in length,
    // omitting any "0x" that might precede the number.
    privateKey := "badba7368...c0202a97c"
    messageJSON := map[string]interface{}{
        "test": "message",
    }

    // Convert a private key from hex to the *ecdsa.PrivateKey
    // type in your function if needed.
    pk, err := crypto.HexToECDSA(privateKey)
    if err != nil {
        log.Fatal(err)
    }

    // Marshal the message to JSON; this function returns bytes.
    // (The bytes that get hashed should be guaranteed to be the
    // same as what is sent in the request.)
    // NOTE: if testing the example strings, you can just declare them as
    // strings and cast them to bytes, e.g. message := []byte("Sila")
    message, err := json.Marshal(&messageJSON)
    if err != nil {
        log.Fatal(err)
    }

    // Generate the message hash using the Keccak 256 algorithm.
    msgHash := crypto.Keccak256(message)

    // Create a signature using your private key and hashed message.
    sigBytes, err := crypto.Sign(msgHash, pk)
    if err != nil {
        log.Fatal(err)
    }

    // The signature just created is off by -27 from what the API
    // will expect. Correct that by converting the signature bytes 
    // to a big int and adding 27.
    var offset int64 = 27
    var bigSig = new(big.Int).SetBytes(sigBytes)
    sigBytes = bigSig.Add(bigSig, big.NewInt(offset)).Bytes()

    // The big library takes out any padding, but the resultant 
    // signature must be 130 characters (65 bytes) long. In some 
    // cases, you might find that sigBytes now has a length of 64 or
    // less, so you can fix that in this way (this prepends the hex 
    // value with "0" until the requisite length is reached).
    // Example: if two digits were required but the value was 1, you'd 
    // pass in 01.
    var sigBytesLength = 65 // length of a valid signature byte array
    var arr = make([]byte, sigBytesLength)
    copy(arr[(sigBytesLength-len(sigBytes)):], sigBytes)

    // Encode the bytes to a hex string.
    sig := hex.EncodeToString(arr)

    // The raw message should then be sent in an HTTP request body, and
    // the signature should be sent in a header.
    log.Println("Message:", string(message))
    log.Println("Signature:", sig, "Signature length:", len(sig))
}

Where many other API systems may require client IDs and secrets, Sila uses the Elliptic Curve Digital Signature Algorithm (ECDSA) to secure and validate requests. Apps and users will have private keys, and Sila will only store addresses, which are directly derived from public keys. Since private keys cannot be derived from addresses or public keys, this can be considered a zero knowledge proof.

Here is a rough overview of the whole process:

  1. A private/public ECDSA key pair is generated.
  2. An "address" is derived from the public key.
  3. The address is registered to a "handle" (like usernames in the Sila ecosystem) and stored by Sila.
  4. A JSON request body is constructed and stringified. (This is the "message.")
  5. A hash is generated from the message (using SHA3/Keccak-256).
  6. The private key is used to sign the hash, which produces a signature.
  7. A valid request to Sila can now be sent. The original "message" is sent in the POST request body, and a hex-encoded signature string is sent in a request header.
  8. When a Sila endpoint receives the request, it will derive a public key from the message and the signature. An address is then derived from that public key.
  9. If the derived address is registered under the handle that is specified in the request body, the request is validated.

Implementing Digital Signatures

While digital signatures are generally considered highly secure and require zero knowledge of the original private key to verify ownership of the private key, here are a few hurdles you may encounter when implementing this authentication protocol.

Expected Values:

Known Pitfalls:

Sample Input/Outputs

These are some sample inputs and outputs using a sample private key.

Private key: badba7368134dcd61c60f9b56979c09196d03f5891a20c1557b1afac0202a97c
Address: 0x65a796a4bD3AaF6370791BefFb1A86EAcfdBc3C1

Message String Signature Hex String
Sila ea3706a8d2b4c627f847c0c6bfcd59f001021d790f06924ff395e9faecb510c53c09274b70cc1d29bde630d277096d570ee7983455344915d19085cc13288b421b
test f9978f3af681d3de06b3bcf5acf2181b5ebf54e0110f1d9d773d691ca2b42bdc39bf478d9ea8287bd15369fa3fd25c09b8c3c02bdbafd19f2aad043e350a037c1b
{"test":"message"} 835e9235dcdc03ed8928df5ace375bc70ea6f41699cd861b8801c9c617b4f2b658ff8e2cda47ea84401cab8019e5bb9daf3c0af2e7d2ab96cba6966a75e017171b
{"test": "message"} 2de2f5d3f778e485f234956679373b9730b717c33e628651c3371e7eb31c4a27738af1a3bf85472a2a7dfc0628ddd21f8611ff0e170ebd24003c2a34b2760d5c1c

If your signatures look almost the same except for the last few characters, you most likely have an offset issue. The good news is that your offset should be constant across your generated signatures. Some other libraries, such as the one we use in our Go example, also have this issue.

Generating and Managing User Private Keys

Select a language tab to see an example of generating a private key.
from silasdk import EthWallet

EthWallet.create("provide some entropy for randomness")
wallet = sila.generateWallet()
// Java private key generation example coming soon!
// Go private key generation example coming soon!

It is critical for users' and apps' private keys to be kept secure. While we are able to freeze and restore users with new addresses in case of security crisis or fraud, this is by no means a desirable situation; too many private key hacks and your application could be at risk for having production access revoked or diminished.

Some applications may want to leave it to the user to keep private keys secure and sign requests as needed, but for many use cases, the private key layer may be better left concealed from users. In that case, applications will need to generate private keys for each of their users.

Use HD (hierarchical deterministic) wallets if you are managing users' private keys.

Endpoints

/check_handle

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

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "header_msg"
}

***

HTTP/1.1 200 OK

{
  "reference": "ref",
  "message": "user.silamoney.eth is available.",
  "status": "SUCCESS"
}
var handle = 'user.silamoney.eth';

sila.checkHandle(handle)
    .then(res => { /* Handle response */ })
    .catch(err => { /* Handle errors */ });
payload = {
  "user_handle": "user.silamoney.eth" # Required
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
User.checkHandle(silaApp, payload)
// check_handle Java example coming soon
// check_handle Go example coming soon

Checks if a specific handle is already taken.

A "handle" works like a username in the Sila ecosystem. This endpoint ensures that a potential handle is available for use. If an entity has already been created with that handle, this endpoint will respond with a message that says that the handle is already in use and a "status": "FAILURE" in the JSON response body.

Requests

In the header.user_handle field, put the handle for which you want to check availability. The entry for header.auth_handle should have your developer handle.

The request body format for this endpoint is the header_msg JSON object.

An authsignature header is required for this request. (Create this using the keypair associated with the auth_handle; see authentication for help generating this signature.)

Responses

The status attribute is a JSON key sent in the response body.

Status Code status Attribute Description
200 "SUCCESS" Handle sent in header.user_handle is available.
200 "FAILURE" Handle sent in header.user_handle is taken.
400 "FAILURE" Handle sent in header.user_handle is a reserved handle according to our JSON schema. (Or: request body otherwise does not conform to JSON schema.)
401 "FAILURE" Auth signature is absent or derived address does not belong to auth_handle.

/register

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

{
  "header": {
    "reference": "SOME ID",
    "created": 1234567890,
    "user_handle": "user.silamoney.eth",
    "auth_handle": "handle.silamoney.eth",
    "version": "0.2",
    "crypto": "ETH"
  },
  "message": "entity_msg",
  "address": {
    "address_alias": "home",
    "street_address_1": "123 Main Street",
    "city": "New City",
    "state": "OR",
    "country": "US",
    "postal_code": "97204-1234"
  },
  "identity": {
    "identity_alias": "SSN",
    "identity_value": "123452222"
  },
  "contact": {
    "phone": "503-123-4567",
    "contact_alias": "",
    "email": "example@silamoney.com"
  },
  "crypto_entry": {
    "crypto_alias": "Address 1",
    "crypto_address": "0x1234567890abcdef1234567890abcdef12345678",
    "crypto_code": "ETH"
  },
  "entity": {
    "birthdate": "1900-01-31",
    "entity_name": "Example User",
    "first_name": "Example",
    "last_name": "User",
    "relationship": "user"
  }
}

***

HTTP/1.1 200 OK

{
  "reference":"SOME ID",
  "message":"user.silamoney.eth was successfully registered ",
  "status":"SUCCESS"
}
var user = {
  handle: 'user.silamoney.eth', // Required: Must not be already in use
  first_name: 'Example',        // Required
  last_name: 'User',            // Required
  name: 'Example User',         // Optional: defaults to `first_name last_name`
  address: '123 Main St.',      // Required: must be a valid USPS mailing address
  address_2: 'Suite 101',       // Optional: required if USPS requires it
  city: 'New City',             // Required: Must be a valid US City matching the zip
  state: 'OR',                  // Required: Must be a 2 character US State abbr.
  zip: '97204-1234',            // Required: Must be a valid US Postal Code
  phone: '123-456-7890',        // Required: Must be a valid phone number (format not enforced)
  email: 'fake@email.com'       // Required: Must be a valid email address
}

sila.register(user)
    .then(res => { /* Handle response */ })
    .catch(err => { /* Handle errors */ });
payload = {
  "country": "US",
  "user_handle": 'user.silamoney.eth',    # Required: Must not be already in use
  "first_name": 'Example',                # Required
  "last_name": 'User',                    # Required
  "entity_name": 'Example User',          # Required
  "identity_value": "123452222",          # Required (SSN)
  "phone": 1234567890,                    # Required:  Must be a valid phone number (format not enforced)
  "email": "fake@email.com",              # Required:  Must be a valid email address
  "street_address_1": '123 Main Street',  # Required:  Must be a valid USPS mailing address
  "city": 'New City',                     # Required:  Must be a valid US City matching the zip
  "state": 'OR',                          # Required:  Must be a 2 character US State abbr.
  "postal_code": 97204,                   # Required:  Must be a valid US Postal Code
  "crypto_address": '0x123...890',        # Required:  Must be a valid ethereum 20 byte address starting with 0x
  "birthdate": "1990-05-19",              # Required
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
User.register(silaApp, payload)
// Java register example coming soon
// Go register example coming soon

Attaches KYC data and specified blockchain address to an assigned handle.

This is the endpoint you will use to create a new user and attach information that will be used to verify their identity. This does not start verification of the KYC data; it only adds the data to be verified. See /request_kyc and /check_kyc for verifying KYC status.

Requests

At this endpoint, you will need to complete all fields with user information and include a valid Ethereum address (must not be already used in Sila system and not a smart contract). The private key associated with the crypto_entry.crypto_address should be used to generate usersignature headers on some subsequent calls.

In this version of the API, required KYC data includes:

Expect these requirements to change in upcoming versions!

This endpoint's request body is the entity_msg JSON object.

An authsignature header is required for this request.

Responses

Status Code status Attribute Description
200 "SUCCESS" Handle successfully added to system with KYC data.
400 "FAILURE" Invalid request body format, handle already in use, or blockchain address already in use.
401 "FAILURE" authsignature header was absent or incorrect.

/request_kyc

POST /0.2/request_kyc 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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "header_msg"
}

***

HTTP/1.1 200 OK

{
  "reference":"ref",
  "message":"user.silamoney.eth submitted for KYC review",
  "status":"SUCCESS"
}
var user = {
  handle: 'user.silamoney.eth', // Required
}

// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key

sila.requestKYC(user, ethereum_private_key)
    .then(res => { /* Handle response */ })
    .catch(err => { /* Handle errors */ });
payload = {
  "user_handle": "user.silamoney.eth" # Required
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
User.requestKyc(silaApp, payload) 
// check_handle Java example coming soon
// check_handle Go example coming soon

Starts KYC verification process on a registered user handle.

After having created a user at a handle with /register, you can start the KYC verification process on the user with this endpoint. The verification results for a handle are asynchronously returned at the /check_kyc endpoint.

Requests

The request body at this endpoint is the header_msg JSON object.

header.user_handle should have the registered handle to be verified.

An authsignature header is required for this request.

Responses

Status Code status Attribute Description
200 "SUCCESS" The verification process for the user registered under header.user_handle has been successfully started.
400 "FAILURE" Invalid request body format.
401 "FAILURE" authsignature or usersignature header was absent or incorrect.

/check_kyc

POST /0.2/check_kyc 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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "header_msg"
}

***

HTTP/1.1 200 OK

{
  "reference":"ref",
  "message":"KYC passed for user.silamoney.eth",
  "status":"SUCCESS"
}
var handle = 'user.silamoney.eth';

// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key

sila.checkKYC(handle, ethereum_private_key)
    .then(res => { /* Handle response */ })
    .catch(err => { /* Handle errors */ });
payload = {
  "user_handle": "user.silamoney.eth" # Required
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
# user_private_key should be 64 characters long and
# associated with registered address. (This key is used
# to sign requests, not sent over any network.)
User.checkKyc(silaApp, payload, user_private_key)
// Java example coming soon
// Go example coming soon

Returns whether entity attached to user handle is verified, not valid, or still pending.

This endpoint should be run after successfully completing /register and /request_kyc calls.

Since ID verification is a relatively lengthy process (generally will take around 30 minutes to an hour to complete), /request_kyc will never confirm in its response that an entity was verified. Therefore, /check_kyc may be polled until a final confirmation is returned.

Requests

The request body at this endpoint is the header_msg JSON object.

The handle for which KYC confirmation is being checked should be in the header.user_handle field.

Both authsignature and usersignature headers are required for this request. (The usersignature header should be generated with the keypair associated with the user; see authentication section for more details.)

Responses

Status Code status Attribute Description
200 "SUCCESS" The user handle has successfully passed KYC verification.
200 "FAILURE" The user handle has not successfully passed KYC verification (may be pending, not have been registered, or have failed; message attribute will contain "pending" or "failed" substring).
400 "FAILURE" Invalid request body format.
401 "FAILURE" authsignature or usersignature header was absent or incorrect.
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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "link_account_msg",
  "public_token": "public-xxx-xxx",
  "account_name": "Custom Account Name",
  "selected_account_id": "optional_selected_account_id"
}

***

HTTP/1.1 200 OK

{
  "status": "SUCCESS"
}
var handle = 'user.silamoney.eth';
var publicToken = 'public-xxx-xxx'; // Token from Plaid


// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key

sila.linkAccount(handle, ethereum_private_key, publicToken)
    .then(res => { /* Handle response res */ })
    .catch(err => { /* Handle errors err */ });
'''
The Python demo app in the Sila-Python GitHub repository 
(https://github.com/Sila-Money/Sila-Python) shows how to use the 
Plaid plugin and get a public token to make this request.
'''

payload = {
  "public_token": "public-xxx-xxx",     # Required token from Plaid
  "user_handle": "user.silamoney.eth"   # Required
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
# user_private_key should be 64 characters long and
# associated with registered address. (This key is used
# to sign requests, not sent over any network.)
User.linkAccount(silaApp, payload, user_private_key)

// Java example coming soon
// Go example coming soon

Uses a provided Plaid public token to link a bank account to a verified entity.

This endpoint accepts results from customer interaction with a Plaid Link integration.

Your frontend Plaid integration will need to:

In the sandbox, you will be connecting to Plaid's sandbox Auth product. In the sandbox, you can test with any bank that shows up in the Plaid plugin, and specify the username as "user_good", and the password as "pass_good". In production you will need to use real usernames and passwords for bank accounts of course. The onSuccess function of the Plaid plugin will return a public token and metadata object to your code. Please 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. (For an example of how this looks, you can look at Plaid's documentation and review our demo app.)

Requests

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

The public_token key is a required field and must have the public token returned in the onSuccess function of Plaid Link.

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.

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

Both authsignature and usersignature headers are required for this request.

Responses

Status Code status Attribute Description
200 "SUCCESS" Bank account successfully linked.
200 "FAILURE" Bank account not successfully linked (public token may have expired; tokens expire in 30 minutes after creation).
400 "FAILURE" Invalid request body format.
401 "FAILURE" authsignature or usersignature header was absent or incorrect.

/get_accounts

POST /0.2/get_accounts 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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2",
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "get_accounts_msg"
}

***

HTTP/1.1 200 OK

[
  {
    "account_number": "*1234",
    "account_name": "default",
    "account_type": "CHECKING",
    "account_status": "active"
  }
]
var handle = 'user.silamoney.eth';

// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key


sila.getAccounts(handle, ethereum_private_key)
    .then((res) => { /* Handle response res */ })
    .catch((err) => { /* Handle error `err` */ });
payload = {
  "user_handle": "user.silamoney.eth" # Required
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
# user_private_key should be 64 characters long and
# associated with registered address. (This key is used
# to sign requests, not sent over any network.)
User.getAccounts(silaApp, payload, user_private_key)         
// Java example coming soon
// Go example coming soon

Gets basic bank account names linked to user handle.

This will return a list of account names, along with basic account information, linked to the requested user handle. These are the accounts that were linked using the /link_account endpoint.

Requests

The request body at this endpoint is the get_accounts_msg JSON object.

Both authsignature and usersignature headers are required for this request.

Responses

Status Code Description
200 Successfully fetched array of accounts.
400 Invalid request body format.
401 authsignature or usersignature header was absent or incorrect.

/issue_sila

POST /0.2/issue_sila 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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "issue_msg",
  "amount": 1000,
  "account_name": "default"
}

***

HTTP/1.1 200 OK

{
  "reference": "ref",
  "message": "ref submitted to ACH queue",
  "status": "SUCCESS"
}
var handle = 'user.silamoney.eth';
var amount = 1000; // Must be an integer value > 100; this is the SILA amount.

// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key

sila.issueSila(amount, handle, ethereum_private_key)
    .then((res) => { /* Handle response res */ })
    .catch((err) => { /* Handle error `err` */ });
payload = {
  "amount": 1000,                                        
  "user_handle": "user.silamoney.eth"
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
# user_private_key should be 64 characters long and
# associated with registered address. (This key is used
# to sign requests, not sent over any network.)
Transaction.issueSila(silaApp, payload, user_private_key) 
// Java example coming soon
// Go example coming soon

Debits a specified account and issues tokens to the address belonging to the requested handle.

The /issue_sila endpoint starts the debit of a user's linked bank account; once that transaction has officially settled, a process that takes about two business days to complete, the handle's blockchain address will be issued SILA tokens.

SILA tokens are pegged to the value of $0.01 USD. To request the debit of $795.43, for instance, you would request "amount": 79543.

Keep in mind that, especially because ACH (automated clearing house) transactions take such a long time to clear, results must be returned asynchronously. You can check the results of a transaction using the /get_transactions endpoint.

Important Note: No transaction fees are charged in this beta version of the API. Expect this to change in upcoming future versions.

Requests

The request body at this endpoint is the issue_msg JSON object.

The amount field is the amount of SILA tokens to issue, which is equivalent to a dollar amount x 100, or a number of cents. For example, to debit $1 from a user's account, you would request an amount of 100.

The account_name field is the name of the handle's linked account from which to debit the equivalent dollar amount.

Both authsignature and usersignature headers are required for this request.

Responses

Status Code status Attribute Description
200 "SUCCESS" Issuance process started.
200 "FAILURE" Issuance process not started; see message attribute.
400 "FAILURE" Invalid request body format.
401 "FAILURE" authsignature or usersignature header was absent or incorrect.

/transfer_sila

POST /0.2/transfer_sila 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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "transfer_msg",
  "amount": 13,
  "destination": "user2.silamoney.eth"
}

***

HTTP/1.1 200 OK

{
  "reference": "ref",
  "message": "ref submitted to ETH queue",
  "status": "SUCCESS"
}
var handle = 'user.silamoney.eth';
var amount = 1000;
var destinationHandle = 'user2.silamoney.eth'; // Must be a KYC-verified user.

// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key

sila.transferSila(amount, handle, ethereum_private_key, destinationHandle)
    .then((res) => { /* Handle response res */ })
    .catch((err) => { /* Handle error `err` */ });
payload = {
  "amount": 1000,                                        
  "user_handle": "user.silamoney.eth",
  "destination": "donald.silamoney.eth"
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
# user_private_key should be 64 characters long and
# associated with registered address. (This key is used
# to sign requests, not sent over any network.)
Transaction.transferSila(silaApp, payload, user_private_key)
// Java example coming soon
// Go example coming soon

Starts a transfer of the requested amount of SILA to the requested destination handle.

This request triggers a transfer of SILA tokens over the blockchain, going from the current authenticated user to the specified destination handle.

In theory, SILA tokens can be transferred from any blockchain address to any blockchain address. This endpoint assumes that the recipient has been registered with Sila and has a handle. During Sila's beta phase, token transfers are restricted to whitelisted addresses (addresses which belong to KYC-verified users). After full launch, tokens will be transferable to any address.

Since the Ethereum platform is currently the only platform we support (though we plan to support others), this will create one blockchain transaction. When other platforms are added, transfers from one platform to another will result in burning of tokens from an address on one platform to minting of tokens to an address on a different platform (two different blockchain transactions).

Important Note: No transaction fees are charged in this beta version of the API. Expect this to change in upcoming future versions.

Requests

The request body at this endpoint is the transfer_msg JSON object.

Both authsignature and usersignature headers are required for this request.

Responses

Status Code status Attribute Description
200 "SUCCESS" Transfer process started.
200 "FAILURE" Transfer process not started; see message attribute.
400 "FAILURE" Invalid request body format.
401 "FAILURE" authsignature or usersignature header was absent or incorrect.

/redeem_sila

POST /0.2/redeem_sila 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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "redeem_msg",
  "amount": 1000,
  "account_name": "default"
}

***

HTTP/1.1 200 OK

{
  "reference": "ref",
  "message": "ref submitted to ETH queue",
  "status": "SUCCESS"
}
var handle = 'user.silamoney.eth';
var amount = 1000; // Must be an integer amount in SILA.

// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key

sila.redeemSila(amount, handle, ethereum_private_key)
    .then((res) => { /* Handle response res */ })
    .catch((err) => { /* Handle error `err` */ });
payload = {
  "amount": 1000,                                        
  "user_handle": "user.silamoney.eth"
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
# user_private_key should be 64 characters long and
# associated with registered address. (This key is used
# to sign requests, not sent over any network.)
Transaction.redeemSila(silaApp, payload, user_private_key)
// Java example coming soon
// Go example coming soon

Burns given amount of SILA at the handle's blockchain address and credits their named bank account in the equivalent monetary amount.

This is the reverse process of /issue_sila; tokens are removed from the handle's associated address, then the process of crediting the named bank account is started.

If the bank account cannot be credited (for instance, if the account has been closed), this operation will roll back and re-mint the tokens at the handle's address.

Important Note: No transaction fees are charged in this beta version of the API. Expect this to change in upcoming future versions.

Requests

The request body at this endpoint is the redeem_msg JSON object.

Both authsignature and usersignature headers are required for this request.

Responses

Status Code status Attribute Description
200 "SUCCESS" Redemption process started.
200 "FAILURE" Redemption process not started; see message attribute.
400 "FAILURE" Invalid request body format.
401 "FAILURE" authsignature or usersignature header was absent or incorrect.

/get_transactions

POST /0.2/get_transactions 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, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "get_transactions_msg",
  "search_filters": {
    "transaction_id": "some UUID string assigned by Sila",
    "reference_id": "the reference string sent in the header object when transaction request was made",
    "show_timelines": true,
    "sort_ascending": false,
    "max_sila_amount": 1300,
    "min_sila_amount": 1000,
    "statuses": ["pending", "successful", "failed", "complete"],
    "start_epoch": 1234567860,
    "end_epoch": 1234567891,
    "page": 1,
    "per_page": 20,
    "transaction_types": ["issue", "redeem", "transfer"]
  }
}

***

HTTP/1.1 200 OK

{
  "success": true,
  "page": 1,
  "returned_count": 1,
  "total_count": 1,
  "transactions": [
    {
      "user_handle": "user.silamoney.eth",
      "reference_id": "ref",
      "transaction_id": "12345678-abcd-1234-abcd-1234567890ab",
      "transaction_hash": "0x1234567890abcdef1234567890abcdef",
      "transaction_type": "issue",
      "sila_amount": 1000,
      "bank_account_name": "default",
      "handle_address": "0x65a796a4bD3AaF6370791BefFb1A86EAcfdBc3C1",
      "status": "success",
      "usd_status": "success",
      "token_status": "success",
      "created": "2019-04-03T00:00:00.000Z",
      "last_update": "2019-04-03T00:00:00.003Z",
      "created_epoch": 1234567890,
      "last_update_epoch": 1234567899,
      "timeline": [
        {
          "date": "2019-04-03T00:00:00.000Z",
          "date_epoch": 1234567890,
          "status": "queued",
          "usd_status": "not started",
          "token_status": "not started"
        },
        {
          "date": "2019-04-03T00:00:00.001Z",
          "date_epoch": 1234567890,
          "status": "pending",
          "usd_status": "pending",
          "token_status": "not started"
        },
        {
          "date": "2019-04-03T00:00:00.002Z",
          "date_epoch": 1234567890,
          "status": "pending",
          "usd_status": "success",
          "token_status": "pending"
        },
        {
          "date": "2019-04-03T00:00:00.003Z",
          "date_epoch": 1234567899,
          "status": "success",
          "usd_status": "success",
          "token_status": "success"
        }
      ]
    }
  ]
}
var handle = 'user.silamoney.eth';

// Provide the user's ethereum private key for signing
// Must be a 64 char hex string
var ethereum_private_key = 'badba7368...c0202a97c'; // Use full private key

sila.getTransactions(handle, ethereum_private_key)
    .then((res) => { /* Handle response res */ })
    .catch((err) => { /* Handle error `err` */ });
payload = {
  "user_handle": "user.silamoney.eth" # Required
}

# Make sure silaApp is initialized with registered app_private_key and app_handle.
# user_private_key should be 64 characters long and
# associated with registered address. (This key is used
# to sign requests, not sent over any network.)
User.getTransactions(silaApp, payload, user_private_key)
// Java example coming soon
// Go example coming soon

Gets array of user handle's transactions with detailed status information.

Requests

The request body at this endpoint is the get_transactions_msg JSON object.

The search_filters object and all of its nested keys are optional. They can be used to filter the transactions that are returned.

Results are paginated; by default, the first 20 results are returned in descending order of date transaction was started. You can request up to 100 results per page ("per_page": 100) and sort them in ascending order of date transaction was started ("sort_ascending": true) if desired.

Both authsignature and usersignature headers are required for this request.

Responses

Status Code success Attribute Description
200 true Able to return transaction information.
400 false Bad request format.
403 false Bad/absent signature header.
500 false Server-side issue; let us know if you get this status code!

Contract Endpoint: /silaBalance

POST /silaBalance HTTP/1.1
Host: sandbox.silatokenapi.silamoney.com
Content-Type: application/json

{
  "address": "0xabc123abc123abc123"
}

***

HTTP/1.1 200 OK

1000
// JavaScript example coming soon
# Make sure silaApp is initialized with registered app_private_key and app_handle.
User.silaBalance(silaApp, address) # address should be a 20 byte valid ethereum address
// Java example coming soon
// Go example coming soon

Gets Sila balance for a given blockchain address.

This endpoint uses a different host and connects directly to the blockchain to query for an address's SILA balance.

Requests

The request body is in JSON and has a single key, address. It accepts a string value and expects a correctly-formatted blockchain address.

No signatures are required in the headers of this request.

Responses

Success responses at this endpoint are returned in plain text rather than JSON and are always numeric. 0 indicates the address holds no SILA tokens. 1000 would indicate the address holds 1000 SILA tokens, the equivalent of $10.00 USD.

Status Code Response Description
200 (A plaintext numeric value) Successful request.
500 {"message": "Internal Server Error"} The provided address value is not an address.

Message Types

Request bodies, also called "messages," are required to have particularly-structured JSON. These message types have names, making it easier to identify exactly what structure you need in the endpoint you need to use.

We have a public JSON schema here: https://sandbox.silamoney.com/0.2/getschema?schema=SilaSchema.

header_msg

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "header_msg"
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use header_msg. true

Used By Endpoints:

entity_msg

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "entity_msg",
  "address": {
    "address_alias": "Home Sweet Home",
    "street_address_1": "123 SW Main St. Apt 143",
    "city": "Portland",
    "state": "Oregon",
    "country": "US",
    "postal_code": "97000"
  },
  "identity": {
    "identity_alias": "SSN",
    "identity_value": "123452222"
  },
  "contact": {
    "contact_alias": "main",
    "phone": "5035035035",
    "email": "contact@silamoney.com"
  },
  "crypto_entry": {
    "crypto_alias": "primary",
    "crypto_code": "ETH",
    "crypto_address": "0x65a796a4bD3AaF6370791BefFb1A86EAcfdBc3C1"
  },
  "entity": {
    "first_name": "Holly",
    "last_name": "Golightly",
    "entity_name": "Holly Golightly",
    "birthdate": "1959-01-31",
    "relationship": "user"
  }
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use entity_msg. true
address object This object specifies the street address of the person being verified. true
identity object This is used to specify an ID and what kind of ID is being specified. (As of writing, Sila only accepts U.S. Social Security Numbers, but this will expand in the future.) true
contact object This is where the verified person's phone number and email address are sent. true
crypto_entry object Used to specify the blockchain address and network code it runs on. true
entity object Includes names, birthdates, and user type. true

Used By Endpoints:

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "link_account_msg",
  "public_token": "public_token_wH473vr",
  "account_name": "Chase Checking Account"
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use link_account__msg. true
public_token string This is the public token returned in the onSuccess function of a Plaid Link session. true
account_name string This is the name given to the linked account. If omitted, it is "default". false
selected_account_id string If one account is selected through Plaid Link, the ID found in the selected accounts array can be passed in here. If this is omitted, the endpoint will choose the first checking account it finds at the end-user's bank. false

Used By Endpoints:

get_accounts_msg

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "get_accounts_msg"
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use get_accounts__msg. true

Used By Endpoints:

issue_msg

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "issue_msg",
  "amount": 1000,
  "account_name": "default"
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use issue__msg. true
amount float Amount of Sila to issue the handle (debits amount/100 from specified account and issues Sila amount at registered blockchain address). true
account_name string Name of user handle's linked bank account to debit/credit. true

Used By Endpoints:

transfer_msg

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "transfer_msg",
  "amount": 13,
  "destination": "user2.silamoney.eth"
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use transfer__msg. true
destination string Handle of recipient of Sila amount. true
amount float Amount of Sila to transfer. true

Used By Endpoints:

redeem_msg

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "redeem_msg",
  "amount": 1000,
  "account_name": "default"
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use redeem_msg. true
amount float Amount of Sila to burn; amount/100 is credited to user handle's specified account. true
account_name string Name of user's linked account to be credited. true

Used By Endpoints:

get_transactions_msg

{
  "header": {
    "created": 1234567890, 
    "auth_handle": "handle.silamoney.eth", 
    "user_handle":"user.silamoney.eth", 
    "version": "0.2", 
    "crypto": "ETH", 
    "reference": "ref"
  }, 
  "message": "get_transactions_msg",
  "search_filters": {
    "transaction_id": "some UUID string assigned by Sila",
    "reference_id": "the reference string sent in the header object when transaction request was made",
    "show_timelines": false,
    "sort_ascending": false,
    "max_sila_amount": 1300,
    "min_sila_amount": 1000,
    "statuses": ["pending", "successful", "failed", "complete"],
    "start_epoch": 1234567860,
    "end_epoch": 1234567891,
    "page": 1,
    "per_page": 20,
    "transaction_types": ["issue", "redeem", "transfer"]
  }
}
Key Type Description Required
header object This object is required in every call. The information it includes is used to verify the signature. true
message string This tag specifies the JSON schema object to validate against. For this call, use get_transactions_msg. true
search_filters object This is an optional object with all-optional attributes. The values inside this object filter the results to be returned. false

Used By Endpoints:

Message Object References

These are objects referenced in the Message Types section.

Key Type Description Required
auth_handle string This is the superuser handle used to identify the API consumer making the call. true
user_handle string This is the user handle attached to the KYC'd entity. true
created integer Epoch time that the API call was started (in nanoseconds). true
crypto string This tag specifies the blockchain network to use. (As of writing, the only valid crypto tag available is ETH.) true
reference string This is an idempotency string used to identify the call you've made. true
version string This tag specifies the version of the API you want to use. (As of writing, the only valid version string to use is 0.2.) true

Referenced in Message Types:

address

Key Type Description Required
address_alias string This is a nickname that can be attached to the address object. While a required field, it can be left blank if desired. true
street_address_1 string This is line 1 of a street address. Post office boxes are not accepted in this field. true
street_address_2 string This is line 2 of a street address (optional). This may include suite or apartment numbers (though, if desired, you can put these in line 1). false
city string Name of the city where the person being verified is a current resident. true
state string Name of state where verified person is a current resident. (As of writing, this is a required field as the only accepted country is the US, but this may be expected to change in future versions.) true
country string Two-letter country code. (As of writing, the only acceptable value is US.) true
postal_code string In the US, this can be the 5-digit ZIP code or ZIP+4 code. true

Referenced in Message Types:

crypto_entry

Key Type Description Required
crypto_alias string A name to identify the address/code pairing. Can be left blank. true
crypto_code string Code to identify network address is on. (As of writing, the only acceptable value is ETH.) true
crypto_address string Hex-encoded blockchain address (prefixed with "0x"). true

Referenced in Message Types:

identity

Key Type Description Required
identity_alias string This describes what kind of ID is being sent. (As of writing, the only accepted value is SSN.) true
identity_value string This is where the ID value would go. true

Referenced in Message Types:

contact

Key Type Description Required
contact_alias string Any name attached to the email/phone pair. If desired, leave empty, but don't leave out. true
email string This is the verified person's email true
phone string This is the verified person's phone number. Please specify area code at a minimum and country code if anywhere but US. true

Referenced in Message Types:

entity

Key Type Description Required
birthdate string Date of birth/inception. Must be formatted YYYY-MM-DD. true
entity_name string Full name of entity. This field is used because some names are "Last First" rather than the "First Last" format usually expected in the US; also allows inclusion of any middle names, titles, etc. true
first_name string First name of entity. true
last_name string Last name of entity. true
relationship string This is the entity type. Specify user in this field to manage the entity as a user. true

Referenced in Message Types:

search_filters

Key Type Description Required
transaction_id string The UUID that Sila assigns to a transaction. false
reference_id string The reference sent in the message header object when the transaction was first created. false
statuses string array Possible values in the array include "pending", "complete", "successful", and "failed". An empty/absent array results in no filter on transaction status. false
transaction_types string array Possible values in the array include "issue", "redeem", and "transfer". An empty/absent array just results in returning all types. false
max_sila_amount float If specified and > 0, returns transactions with amounts less than or equal to this amount. false
min_sila_amount float If specified and > 0, returns transactions with amounts greater than or equal to this amount. false
start_epoch integer Nanosecond epoch time. If specified and is a date after 1969, returns transactions started after this date. false
end_epoch integer Nanosecond epoch time. Returns transactions started before this date. false
page integer Specifies page of results to return (default 1). false
per_page integer Number of results to return in a single call (1-100, default 20). false
sort_ascending boolean If true, returns the oldest transactions first instead of the newest first. false
show_timelines boolean If true, adds a timeline array to each transaction object in the JSON response. false

Referenced in Message Types:

Transaction Error Codes

Transactions returned from the /get_transactions endpoint, if they have failed, will have an error code and error message returned with them. These are the error codes we return as of version 0.2.

Error Code Meaning
ACH_ACCT_DNE A bank account with the given name does not exist under the user handle's linked accounts.
ACH_ACCT_INVALID The specified bank account is invalid. It may be closed or have invalid values.
ACH_INSUFF_FUNDS A bank account debit could not be completed due to insuffient funds.
ACH_REJECTED For whatever reason, an ACH transaction was rejected. This could be due to suspected fraud.
ACH_RETURN There was an ACH return on a transaction.
ADDR_BLACKLISTED An address in this transaction is blacklisted.
ADDR_INSUFF_FUNDS There are insufficient funds at the user handle's associated blockchain address.
ADDR_INVALID Provided blockchain address for user handle is invalid. It could be that it is a smart contract address, is not a real address, or is not on our betalist (temporary whitelist).
ADDR_NOT_BETALISTED An address in this transaction is not on the contract's betalist (temporary whitelist).
APPL_LIMIT The request count limit has been reached for the current application.
BLOCK_TIMEOUT The transaction timed out on the blockchain and can be retried.
EMERGENCY_FLAG All further transactions are temporarily disabled on the Sila platform.
FEE_INSUFF_FUNDS The address specified to pay the transaction fee had insufficient funds.
NON-ACH_TRANS_UNSUPPORTED A non-ACH transaction was requested while non-ACH transactions are temporarily unsupported.
RATE_LIMIT Too many transactions have been requested in a short span of time. Try waiting and retrying later.
TRANS_AMNT_TOO_LOW The amount specified in the transaction was too low for it to complete.
TRANS_AMNT_TOO_HIGH The amount specified in the transaction was higher than allowed transaction limit.
TRANS_AMNT_INVALID The amount may have been for an issue or redeem transaction and been a decimal value; this would convert to a fraction of a cent, which is not permitted on bank account transactions.
UNKNOWN This is an unknown error. Contact us ASAP if a transaction has this error code!
USER_HANDLE_FROZEN This user is not permitted to transact at this time.
USER_KYC_INCOMPLETE The user has not been KYC-verified.
Any code in <> This is a specific issue on our end that we should fix. Contact us ASAP if you catch one of these!