🖥️For Developers

API

API Documentation

Sakoly is a secure, multi-tenanted microfinance platform.

The goal of the Sakoly API is to empower developers to build apps on top of the Sakoly Platform. The reference app (username: admin, password: 123456) works on the same demo 'tenant' as the interactive links in this documentation.

The API is organized around REST.

The API is designed to have: - predictable, resource-oriented URLs - to use HTTP response codes to indicate API errors - to use built-in HTTP features, like HTTP authentication and HTTP verbs, which can be understood by off-the-shelf HTTP clients.

JSON is returned in all responses from the API, including errors.

Much of the API presentation and design ideas are owed to the excellent Apigee "Web API Design" eBook/PDF and the very good Stripe API reference.

Try The API From Your Browser

GET (read) examples can be run directly from this documentation. It is just a matter of clicking a link. Most browsers display the output on the same page (or another tab if you right click and select that option). Internet Explorer will probably treat the output as if you wanted to download a file. In that case just elect to open the output in a text editor.

If you want to check out the POST, PUT and DELETE (update) examples a good approach is to take a moment to install a REST plugin for your browser e.g. RESTClient for FireFox

The REST plugins will allow you to:

  • Select the "Verb" (e.g. POST)

  • Enter the resource name (e.g. offices)

  • Add a header to indicate you are sending JSON data as part of the request body (Content-Type: application/json)

  • Add a header to indicate your 'tenant' (Sakoly-Platform-TenantId: default)

  • Paste the example JSON into a Request Body

  • Send the Request (and receive a Response)

Generic Options

Convenience Templates

There are a list of convenience resources (see Template menu option). These resources end with "/template" and can be useful when building maintenance user interface screens for client applications. The template data returned may consist of any or all of:

  • Field Defaults

  • Allowed Value Lists

Also, many "Retrieve a" type resources (Retrieve a Client for example) allow the parameter option "template=true". This appends any "Allowed Value Lists" which can be useful when building update functionality.

Restrict Returned Fields

Parameter "fields={fieldlist}" can be used on GET requests to restrict the fields returned.

Normal Request:

offices/1

Request (restricting fields returned):

offices/1?fields=id,name

Pretty JSON Formatting

Parameter "pretty=true" can be used to display JSON from GET requests in an easy-to-read format. This parameter is used in this documentation.

Easy-to-read JSON output for POSTs, PUTs and DELETEs will available in the REST plugin you use e.g. RESTClient for FireFox

Normal Request (with pretty printing/formatting):

offices/1?pretty=true

Creating and Updating

When you want to 'Create a ...' you have to at least supply the mandatory fields. The mandatory fields are listed in this documentation under the relevant 'Create a ...' heading.

When you want to 'Update a ...' you can update individual fields or a combination of fields (subject to data integrity rules).

Updating Dates and Numbers

Dates

Dates are returned in GET requests as an array e.g. [ 2007, 4, 11]. However, the API accepts them as strings in POST and PUT requests. If there are any dates in your POST or PUT requests, you need to provide the "locale" and "dateFormat". This can be any date pattern supported by Joda-Time. This capability can help you when saving data in your client application as you shouldn't need to do any date format conversion prior to issuing your POST or PUT request.

JSON examples: { "locale": "en_US", "dateFormat": "dd MMMM yyyy", "openingDate": "01 July 2007" } { "locale": "en_US", "dateFormat": "yyyy-MM-dd", "openingDate": "2007-03-21" }

Numbers

You must provide a "locale" when updating numbers. Numbers are not "Ids" or "Types" but are typically money amounts or percentages that relate to loans. In any case, the API will send back an error message if you forget.

JSON examples: { "locale": "en_US", "principal": "240,400.88" } { "locale": "fr_CH", "principal": "240 400.88" }

Field Descriptions

Most fields are self-explanatory. Fields that aren't are described under the relevant resource heading e.g. AUTHENTICATION

Authentication Overview

Authentication to the API can be configured to be supported via HTTP Basic Auth or OAuth2.

Default authentication is using HTTP Basic Auth. Oauth2 can be enabled by using -Psecurity=oauth option on gradle build command , refer the platform setup wiki for additional details.

Optionally, two-factor authentication can be enabled by using -Ptwofactor=enabled on gradle build. Details of the authentication workflow with two-factor authentication enabled can be found here.

The platform has been configured to reject plain HTTP requests and to expect all API requests to be made over HTTPS. All requests must be authenticated.

Authentication HTTP Basic

Authentication to the API occurs via HTTP Basic Auth.

// A Javascript/Jquery example of how to login to Sakoly and use its api. // Typically, the javascript application would // 1) Display a login page to retrieve the username and password. // 2) Send the username and password to a function // such as setBasicAuthKey below which sets the HTTP Basic Auth key. // 3) The HTTP Basic Auth key is used in all subsequent requests // (see the function executeAjaxRequest below). function setBasicAuthKey(username, password) { var jqxhr = $.ajax({ url : "authentication?username=" + username + "&password=" + password, type : 'POST', contentType : "application/json; charset=utf-8", dataType : 'json', data : "{}", cache : false, success : function(data, textStatus, jqXHR) { basicAuthKey = data.base64EncodedAuthenticationKey; }, error : function(jqXHR, textStatus, errorThrown) { //error processing } }); } function executeAjaxRequest(url, verbType, jsonData, basicAuthKey, successFunction, errorFunction) { var jqxhr = $.ajax({ url : url, type : verbType, //POST, GET, PUT or DELETE contentType : "application/json; charset=utf-8", dataType : 'json', data : jsonData, cache : false, beforeSend : function(xhr) { xhr.setRequestHeader("Authorization", "Basic " + basicAuthKey); }, success : successFunction, error : errorFunction }); }

Authentication Oauth2

Authentication to the API occurs via OAuth2. 'Resource Owner Password Credentials Grant' type is used.

// A Javascript/JQuery example of how to login to Apache Sakoly and use its API. // Typically, the JavaScript application would: // 1) Display a login page to retrieve the username and password. // 2) Send the username, password, client_id , grant_type and client_secret to a function // such as getOauthToken() below which POSTs these as x-www-form-urlencoded (but NOT in the URL, see SAKOLY-629) // and stores the token in a global variable. // 3) The HTTP bearer Auth key is used in all subsequent requests // (see the function executeAjaxRequest() below). function getOauthToken(username, password) { var jqxhr = $.ajax({ url : "/sakoly-provider/api/oauth/token", type : 'POST', dataType : 'json', data : { username: credentials.username, password: credentials.password, client_id: "community-app", grant_type: "password", client_secret: "123" }, cache : false, success : function(data, textStatus, jqXHR) { authKey = data.access_token; }, error : function(jqXHR, textStatus, errorThrown) { //error processing } }); } function executeAjaxRequest(url, verbType, jsonData, authKey, successFunction, errorFunction) { var jqxhr = $.ajax({ url : url, type : verbType, //POST, GET, PUT or DELETE contentType : "application/json; charset=utf-8", dataType : 'json', data : jsonData, cache : false, beforeSend : function(xhr) { xhr.setRequestHeader("Authorization", "bearer " + authKey); }, success : successFunction, error : errorFunction }); }

Two-Factor Authentication

Two-Factor authentication is supported by requesting & verifying one-time passwords(OTP). OTPs are sent via SMS & email.

Two-factor authentication is disabled by default. More information on how to enable TFA can be found here.

Two-factor authentication workflow:

  1. User authticates via BasicAuth / oAauth.

  2. Client requests a list of supported OTP delivery methods for the authenticated user(Get Delivery Methods).

  3. User selects an OTP delivery method and client sends a request for OTP(Request OTP).

  4. User receives an OTP and the client sends it for verification(Validate OTP).

  5. If the OTP is valid, an access token is returned

  6. The access token is sent in following requestes to the server as a header Sakoly-Platform-TFA-Token

  7. On session end, the access token should be invalidatedInvalidate Access Token).

Two-Factor authentication and delivery methods can be configured via the /twofactor/configure endpoint.

Get Delivery Methods

Returns a list of possible OTP delivery methods for the current user.

Requires first-factor authenticated user.

GET https://DomainName/api/v1/twofactor [ { "name": "sms", "target": "08888888888" }, { "name": "email", "target": "user@example.com" } ]

Request OTP

Requests an OTP.

Requires first-factor authenticated user.

ARGUMENTS

deliveryMethodString mandatory, the delivery method nameextendedTokenboolean optional, whether to request an extended token, default falsePOST https://DomainName/api/v1/twofactor?deliveryMethod=sms&extendedToken=false { "requestTime": 1500000000000, "tokenLiveTimeInSec": 300, "extendedAccessToken": false, "deliveryMethod": { "name": "sms", "target": "08888888888" } }

Validate OTP

Validates an OTP. If the OTP is valid, an access token is created.

The returned access token is later sent as a header Sakoly-Platform-TFA-Token.

Requires first-factor authenticated user.

ARGUMENTS

tokenString mandatory, the OTP to validatePOST https://DomainName/api/v1/twofactor/validate?token=YYYYY { "token": "cb0bb6e33fc540709d50a16eb2e555f9", "validFrom": 1501530702801, "validTo": 1501617102801 }

Invalidate Access Token

Invalidates an access token.

Two factor access tokens should be invalidated on logout.

Requires fully authenticated user.

POST https://DomainName/api/v1/twofactor/invalidate { "token": "cb0bb6e33fc540709d50a16eb2e555f9" } { "resourceIdentifier": "cb0bb6e33fc540709d50a16eb2e555f9" }

Last updated