Open Banking APIs that expose simplified data services with plausible & dynamic content โ great for enablement, demos, and POCs. Run them in containers on your local environment or in any cloud that gives you Docker.
Some of the endpoints are available online: Live Endpoints The bank also has a public website and a developer portal.
Available APIs and Webservices:
- Account Info & Balance - OAuth (3-legged)
- Credit Card Balance - Full CRUDL REST interface (Create, Read, Update, Delete, List)
- Bank Assets - SOAP/XML, 2 methods
- Currency Exchange Rates - REST/JSON, 1 parameter
- Payments - (currently in development, coming soon)
- Stock Quote - REST/JSON, 0 parameters, cached output.
- Fixed Deposit Calculator - REST/JSON, 2 parameters, semantic error handling, complex output
- Investments - /v1 and /v2 endpoints with respective Swagger specs
- ATM Locator - Full CRUDL REST interface (Create, Read, Update, Delete, List)
- Short Loan Product - Full CRUDL REST interface (Create, Read, Update, Delete, List)
Looking for a quick way to deploy? Docker Compose | Chef Cookbook
A webservice that gives you total assets and debt of the bank. Each request will produce a slightly different result - it's a busy bank so cash is flowing in & out constantly! You could use this to show SOAP to REST conversion.
docker run -d -p 8080:8080 u1ih/yoisho-assets
curl http://localhost:8080/?WSDL
This API gives you exchange rates for currencies (USD, GBP and SGD) that the bank buys and sells. Each time you ask for a quote the amounts might be slighly different - they're really busy adjusting the rates constantly!
docker run -d -p 8080:8080 u1ih/yoisho-currency
curl http://localhost:8080/swagger
{"info": {"version": "1.0", "description": "", "title": "Yoisho Currency Exchange"}, "paths": {"/get_currency": {"get": {"responses": {"default": {"description": "successful operation"}}, "produces": ["application/json"], "description": "", "parameters": [{"required": true, "type": "string", "description": "The desired currency", "name": "currency", "in": "query"}], "operationId": "get_currency"}}}, "schemes": ["http"], "basePath": "/currency", "host": "", "x-axway": {"deprecated": false, "serviceType": "rest", "basePaths": [""], "corsEnabled": true, "tags": {}}, "swagger": "2.0"}
curl http://localhost:8080/get_currency?currency=USD
{"sell": "489.185", "timestamp": "2017-09-17 02:58:40.194337", "buy": "389.105"}
When playing with the endpoint, you'll observe a couple of things:
- if you're not adding ?currency= to the request, you'll get a nasty 500 error. Of course, this should be handled by the backend properly, but it also helps highlight the contractual aspects of Swagger and the need for API Managament to only pass on API requests to the backend if it has verified its integrity
- from an API design perspective, the development team could realize that there's two things that should change: (1) we need an API base path and (2) get_currency is not exactly a good name for a resource in order to be swagger compliant and align with API design best practices
curl http://localhost:8080/fx/swagger
curl http://localhost:8080/fx/currency?currency=USD
{"sell": "489.185", "timestamp": "2017-09-17 02:58:40.194337", "buy": "389.105"}
This API gives you a full CRUDL interface (Create, Read, Update, Delete, List) for ATM locations, using an in memory database.
Two versions:
- /banking/v1 offers CREATE, READ, UPDATE
- /banking/v2 offers CREATE, READ, UPDATE, DELETE, LIST ALL
docker run -d -p 8080:8080 u1ih/yoisho-atm
curl http://localhost:8080/banking/v2/swagger
{ "swagger": "2.0", "info": { "version": "", "title": "ATM Locations", "description": "List of ATM locations for Yoisho Banking Corporation" }, "basePath": "/banking/v2", "consumes": [ "application/json" ], "produces": [ "application/json" ], "paths": { "/atm/{id}": { "parameters": [ { "name": "id", "in": "path", "required": true, "type": "string" } ], "get": { "operationId": "GET-atm-location", "summary": "Get ATM Location", "tags": [ "Atm locations" ], "responses": { "200": { "description": "", "schema": { "$ref": "#/definitions/api-location-input" } } } }, "put": { "operationId": "PUT-atm-location", "summary": "Update ATM Location", "tags": [ "Atm locations" ], "parameters": [ { "name": "body", "in": "body", "schema": { "$ref": "#/definitions/api-location-input" } } ], "responses": { "200": { "description": "", "schema": { "$ref": "#/definitions/api-location-input" } } } }, "delete": { "operationId": "DELETE-atm-location", "summary": "Delete ATM Location", "tags": [ "Atm locations" ], "responses": { "204": { "description": "" } } } }, "/atm": { "get": { "operationId": "LIST-atm-locations", "summary": "List Atm locations", "tags": [ "Atm locations" ], "responses": { "200": { "description": "", "schema": { "type": "object", "properties": { "result": { "type": "array", "items": { "type": "object", "properties": { "lat": { "type": "string" }, "lon": { "type": "string" }, "location": { "type": "string" }, "id": { "type": "string" } } } } } }, "examples": { "application/json": { "data": [ { "lat": "35.6684231", "lon": "139.6833085", "location": "Ebisu Station" }, { "lat": "35.6284713", "lon": "139.736571", "location": "Shinagawa Station" } ] } } } } }, "post": { "operationId": "POST-atm-location", "summary": "Create ATM Location", "tags": [ "Atm locations" ], "parameters": [ { "name": "body", "in": "body", "schema": { "$ref": "#/definitions/api-location-input" } } ], "responses": { "201": { "description": "", "schema": { "$ref": "#/definitions/api-location-input" } } } } } }, "definitions": { "atm-location-input": { "title": "ATM Location Input", "type": "object", "properties": { "location": { "type": "string" }, "lat": { "type": "string" }, "lon": { "type": "string" } }, "required": [ "location" ] } }
The entries with id 1 and 2 are prepopulated when the container starts:
curl http://localhost:8080/banking/v2/atm/1
{"lat": "35.6284713", "lon": "139.736571", "location": "Shinagawa Station"}
curl http://localhost:8080/banking/v2/atm/2
{"lat": "35.6684231", "lon": "139.6833085", "location": "Ebisu Station"}
curl -X POST http://localhost:8192/banking/v2/atm -d '{ "lat": "35.4657858", "lon": "139.6201245,17", "location": "Yokohama Station" }'"
{"message": "created", "id": "565"}
curl -X DELETE http://localhost:8080/banking/v2/atm/565
{"message": " 565 deleted"}
curl -X PUT http://localhost:8080/banking/v2/atm/105 -d '{"lat": "123", "lon": "982", "location": "some place"}'
{"message": "updated", "id": 105}
curl http://localhost:8080/banking/v2/atm
{"result": [{"lat": "35.6684231", "lon": "139.6833085", "location": "Ebisu Station", "id": "2"}, {"lat": "35.6284713", "lon": "139.736571", "location": "Shinagawa Station", "id": "1"}]}
This APIs works just like v2 of to the ATM locator.
docker run -d -p 8080:8080 u1ih/yoisho-creditcard
curl http://localhost:8080/cardservices/swagger
This API provides investment insights of top performing funds. One endpoint, but two different versions. Version 2 is has one additional output field (previous_performance_rating).
docker run --rm -d -p 8080:8080 u1ih/yoisho-invest:latest
curl http://localhost:8080/invest/v1/swagger
{"info": {"version": "", "description": "Provides investment insights of top performing funds", "title": "Investments"}, "paths": {"/investments": {"get": {"summary": "Get Top Performing Funds", "responses": {"200": {"description": "", "schema": {"$ref": "#/definitions/investments"}}}, "tags": ["Investments"], "operationId": "GET-investments"}}}, "produces": ["application/json"], "definitions": {"investments": {"items": {"type": "object", "properties": {"performance": {"type": "string"}, "currency": {"type": "string"}, "performance_rating": {"type": "string"}, "id": {"type": "string"}, "name": {"type": "string"}}}, "type": "array", "example": [{"performance": "78", "currency": "JPY", "performance_rating": "1", "id": "YB0GB893", "name": "First Arima Onsen"}, {"performance": "71", "currency": "USD", "performance_rating": "2", "id": "YB0IM691", "name": "Castle Rock Index Fund"}], "title": "investments"}}, "basePath": "/v1", "swagger": "2.0", "consumes": ["application/json"]}
curl http://localhost:8080/invest/v1/products
[{"performance": "78", "currency": "JPY", "performance_rating": "1", "id": "YB0GB893", "name": "First Arima Onsen"}, {"performance": "71", "currency": "USD", "performance_rating": "2", "id": "YB0IM691", "name": "Castle Rock Index Fund"}, {"performance": "69", "currency": "RMB", "performance_rating": "2", "id": "YB0SD611", "name": "Odee Hangzhou BC"}, {"performance": "56", "currency": "USD", "performance_rating": "3", "id": "YB0AA223", "name": "Sedona 500"}, {"performance": "51", "currency": "EUR", "performance_rating": "4", "id": "YB0DE781", "name": "Munich WB2"}]
curl http://localhost:8080/invest/v2/swagger
{"info": {"version": "", "description": "Provides investment insights of top performing funds", "title": "Investments"}, "paths": {"/investments": {"get": {"summary": "Get Top Performing Funds", "responses": {"200": {"description": "", "schema": {"$ref": "#/definitions/investments"}}}, "tags": ["Investments"], "operationId": "GET-investments"}}}, "produces": ["application/json"], "definitions": {"investments": {"items": {"type": "object", "properties": {"performance_rating": {"type": "string"}, "name": {"type": "string"}, "previous_performance_rating": {"type": "string"}, "currency": {"type": "string"}, "performance": {"type": "string"}, "id": {"type": "string"}}}, "type": "array", "example": [{"performance_rating": "1", "name": "First Arima Onsen", "previous_performance_rating": "2", "currency": "JPY", "performance": "78", "id": "YB0GB893"}, {"performance_rating": "2", "name": "Castle Rock Index Fund", "previous_performance_rating": "3", "currency": "USD", "performance": "71", "id": "YB0IM691"}], "title": "investments"}}, "basePath": "/v2", "swagger": "2.0", "consumes": ["application/json"]}
curl http://localhost:8080/invest/v2/products
[{"performance_rating": "1", "name": "First Arima Onsen", "previous_performance_rating": "1", "currency": "JPY", "performance": "78", "id": "YB0GB893"}, {"performance_rating": "2", "name": "Castle Rock Index Fund", "previous_performance_rating": "1", "currency": "USD", "performance": "71", "id": "YB0IM691"}, {"performance_rating": "2", "name": "Odee Hangzhou BC", "previous_performance_rating": "0", "currency": "RMB", "performance": "69", "id": "YB0SD611"}, {"performance_rating": "3", "name": "Sedona 500", "previous_performance_rating": "4", "currency": "USD", "performance": "56", "id": "YB0AA223"}, {"performance_rating": "4", "name": "Munich WB2", "previous_performance_rating": "2", "currency": "EUR", "performance": "51", "id": "YB0DE781"}]
This API returns the stock price of Yoisho Banking Corp. The data updates every minute, it's also sending additional Cache-Control headers.
docker run --rm -d -p 8080:8080 u1ih/yoisho-stockquote:latest
curl http://localhost:8080/stockquote/swagger
{ "swagger" : "2.0", "host" : "", "basePath" : "/stockquote", "schemes" : [ "http" ], "paths" : { "/current" : { "get" : { "description" : "", "operationId" : "get_quote", "produces" : [ "application/json" ], "responses" : { "default" : { "description" : "successful operation" } } } } }, "info" : { "title" : "Yoisho Stock Quote", "description" : "", "version" : "1.0" }, "x-axway" : { "corsEnabled" : true, "basePaths" : [ "" ], "serviceType" : "rest", "deprecated" : false, "tags" : { } } }
curl http://localhost:8080/get_quote
{"message": "Stock Price refreshes every minute", "stockprice": "371.44"}
This API calculates the total interest earned from a fixed deposit, along with a breakdown for the number of years the deposit is running. Parameters: amount, number of years the fixed deposit will run
docker run --rm -d -p 8080:8080 u1ih/yoisho-deposit:latest
curl http://localhost:8080/swagger
{ "swagger" : "2.0", "host" : "", "basePath" : "/fixeddeposit", "schemes" : [ "http" ], "paths" : { "/calculate" : { "get" : { "description" : "Calculates the total interest earned from a fixed deposit, along with a breakdown for the number of years the deposit is running.", "operationId" : "calculate", "produces" : [ "application/json" ], "parameters" : [ { "description" : "The number of years the fixed deposit is running.", "required" : true, "in" : "query", "name" : "years", "type" : "string" }, { "description" : "The amount for the fixed deposit", "required" : true, "in" : "query", "name" : "amount", "type" : "string" } ], "responses" : { "200" : { "description" : "OK" }, "400" : { "description" : "Invalid request" } } } } }, "info" : { "title" : "Fixed Deposit Calculator", "description" : "", "version" : "1.0" } }
curl "http://localhost:8080/calculate?amount=50000&years=12"
{"info": "Current interest rate is 3.15% pa.", "yield_breakdown_by_year": [{"amount": "50,000.00", "year": "1"}, {"amount": "51,575.00", "year": "2"}, {"amount": "53,199.61", "year": "3"}, {"amount": "54,875.40", "year": "4"}, {"amount": "56,603.98", "year": "5"}, {"amount": "58,387.00", "year": "6"}, {"amount": "60,226.19", "year": "7"}, {"amount": "62,123.32", "year": "8"}, {"amount": "64,080.20", "year": "9"}, {"amount": "66,098.73", "year": "10"}, {"amount": "68,180.84", "year": "11"}, {"amount": "70,328.53", "year": "12"}], "deposit_amount": "50,000.00", "yield_amount": "70,328.53", "years": "12"}
Gives you an account balance API with a 3-legged OAuth flow including consumer banking login.
- Consumer: the app, identified by client_id and client_secret
- Resource Owner: the banking customer, here it's Dave and Jane
- API: the account balance service
- client_id: 7b6fc8ed5127b0b2f076d
- client_secret: 724e6890757b0ae624684b70e111b705fe6b050c
- user accounts: jane, dave (use any random password)
docker run --rm -d -p 8080:8080 u1ih/yoisho-account:latest
Access this URL in the browser (replace the redirect_uri with your own):
http://localhost:8080/authorize?redirect_uri=http://www3.sotong.io&client_id=7b6fc8ed5127b0b2f076d
Login with either 'dave' or 'jane' (any random password).
?code=4990047
Use the code from the previous step to exchange it for an access token. Of course, you'd typically do that server side.
curl http://localhost:8080/access_token?code=4990047&client_id=7b6fc8ed5127b0b2f076d&client_secret=724e6890757b0ae624684b70e111b705fe6b050c
{"token_type": "bearer", "scope": "read", "access_token": "eSlcNwnLxTuzsYXyzFrhGGU3mrCKPxQ5fy51Jx93.MTUzMjM1NDM0OA=="}
Now with this access token we can call the actual API and retrieve the account info from the resource owner, which is the banking client.
curl -X GET http://localhost:8080/info -H 'Authorization: Bearer eSlcNwnLxTuzsYXyzFrhGGU3mrCKPxQ5fy51Jx93.MTUzMjM1NDM0OA=='
{"account_owner": "dave", "fullname": "Dave Thompson", "email": "[email protected]", "address": "491-1295, Nishimiyanosawa 6-jo, Teine-ku Sapporo-shi, Hokkaido", "phone": "+8183-977-7817"}
With the same access token we retrieve the account balance from the resource owner, which is the banking client.
curl -X GET http://localhost:8080/balance -H 'Authorization: Bearer eSlcNwnLxTuzsYXyzFrhGGU3mrCKPxQ5fy51Jx93.MTUzMjM1NDM0OA=='
{"account_owner": "dave", "account_balance": "10,187.91"}
Here's a simple web based client implementation that shows the entire flow in the browser - the banking customer logs in and authorizes the app to access the account balance on their behalf: Yoisho OAuth Client (Python)