NAV Navbar
Star

Check your mailbox Something went wrong. Please contact support

Navbar
cURL C# Go Node.js PHP Python Ruby Java
EMS API

EMS - Starter Guide

This section will provide general information about the Execution Management System API (EMS API) software product and enumerate a number of features that it provides.

What is EMS API?

Execution Management System (EMS) is a software that managing orders, executions and exposure in an efficient, fast, cost-effective, and straightforward manner. An EMS allows you to route orders to multiple cryptocurrency exchanges simultaneously using a simple, robust, and unified Application Programming Interface (API).

Software can be used in 2 different ways:

Dimension Comparison Managed Cloud Self Hosted
Ease of use/installation Very easy Hard
Time to market Fast Slow
DevOps team required to maintain No Yes
Order-flow sent directly to the destination No Yes
Who manage the infrastructure (incl. monitoring) CoinAPI You
Who optimize the latency CoinAPI You (CoinAPI only in software)
How to install Instruct our Cloud Mgmt API Install on your infrastructure

Architecture and components

An self-hosted EMS cluster can be deployed on single server or multiple servers that will span multiple geographical locations, server sites or cloud providers. In the Managed Cloud version you did not care about that as we manage the server sites to be as close to the order destinations as possible.

EMS consist of several components listed and ordered by dependency relationship:

  1. Exchange - Order destination, exchange or broker.

  2. CoinAPI EMS Edge - Software that's responsible for communicating with the single specific order destination for which is deployed. This component is exposing the EMS API for diagnostics purposes which functions visibility are limited to this single destination.

  3. CoinAPI EMS API - Software that's responsible for exposing fully functional the EMS API, maintainitng connection with all instances of CoinAPI EMS Edge.

  4. CoinAPI EMS WebUI - Web interface (GUI) to the EMS API interface. (optional)

  5. Customer Application - Customer software using the EMS API exposed by CoinAPI EMS API component.

Benefits and features

Low latency support

Specific projects usually involving High-Frequency Trading (HFT) or Market Making (MM) requiring low latency access to the order destination. EMS API was designed to have native support for this kind of activity.

For every order destination in the cluster to which the submillisecond latency is required, this components should be deployed on a single server as close as possible to the order destination:

Closest proximity can be achieved using the:

The cluster can naturally contain other order destinations at the same time in this setup, and this fact doesn't affect the latency to the locally provisioned destination(s).

Normalized API abstraction

Our EMS API provides an abstraction layer that consolidates all supported third-party APIs into a single set of simple and robust data models and protocols. The Exchanges and the Assets are standardized using the Market Data REST API to which this product is compatible. More information about the exchanges and assets standardization can be found in the Documentation of the Market Data Product.

Industry standard protocols

Our API's can be accessed using multiple protocols widely adopted by the industry as a standard:

Self-host or in Cloud

Deploy your property applications and trading algorithms in your company collocated data centers or cloud providers if you need that, otherwise let us manage the infrasturcture and focus on using the API.

Security & Privacy

Don't need to worry about the issues at the audit. Order flow, exchange API keys, or execution reports are never leave your company infrastructure as the product is self-hosted.

Multi account support

Manage unlimited number exchange accounts in the cluster (for example, on behalf of your customers).

SDK and samples for 40+ languages

We have the SDK libraries and code samples available for more than 40+ languages. Full list is available here: https://github.com/coinapi/coinapi-sdk/tree/master/oeml-sdk

Comprehensive support

Leverage support for all market types and order types.

High quality integrations

Our integrations with third-party APIs are heavily tested and crafted with the stability and latency in mind. For several third parties, we usually use multiple protocols simultaneously or tricks to acquire valuable pieces of information faster.

Enterprise-grade support and maintenance

EMS product is fully supported and maintained to stay ahead of the curve. This approach offloading the often disliked responsibilities of the Software and DevOps Engineers in the organization and enables them to focus on the core business.

High availability

The EMS software is designed to support high-availability deployments out of the box. For each order destination, we/you deploy multiple CoinAPI EMS Edge and CoinAPI EMS API components on different servers, availability zones, or cloud/infrastructure providers. Cluster using the service discovery backend, all components are automatically detected and interconnected.

P&L and asset monitoring

Using the EMS, your organization can manage exposure and positions in real-time across all supported order destinations and build sophisticated risk management controls.

Order lifecycle

This section will describe lifecycle of the order in the EMS sofware.

Order status description

This table describes how to interpret a specific order status.

Name Can transit to Status description
RECEIVED REJECTED
ROUTING
The order is processed by the EMS.
ROUTING ROUTED The order is (on the wire) between the EMS and the Exchange.
ROUTED REJECTED
NEW
PARTIALLY_FILLED
FILLED
CANCELED
The order has been sent to the exchange and not yet active in the order book.
NEW PARTIALLY_FILLED
FILLED
PENDING_CANCEL
CANCELED
The order is active in the book in its original state.
PENDING_CANCEL NEW
PARTIALLY_FILLED
FILLED
CANCELED
The order cancelation message has been sent to the Order destination.
PARTIALLY_FILLED FILLED
PENDING_CANCEL
CANCELED
The order is partially filled and active in the order book.
FILLED The order is filled and removed from the order book. This state is terminal.
CANCELED The order is canceled and removed from the order book. This state is terminal.
REJECTED The order is rejected. This state is terminal.

Order status lifecycle

This table describes how to interpret transitions between order statuses and their initial values.

Source Status Destination status Description
RECEIVED EMS received a new order via the API.
NEW EMS received an unseen new order from the Order destination. The order was relayed to the destination outside the EMS.
PARTIALLY_FILLED EMS received unseen partially filled order from the Order destination. The order was relayed to the destination outside the EMS.
RECEIVED REJECTED EMS rejected the order.
RECEIVED ROUTING EMS delivering the order to the Order destination.
ROUTING ROUTED EMS sent the order to the Order destination.
ROUTED REJECTED EMS received a message from the exchange that the order was rejected.
ROUTED NEW EMS received a message from the exchange that the order is active in the book in its original state.
ROUTED PARTIALLY_FILLED EMS received a message from the exchange that part of the order was executed aggressively (removed liquidity). The remaining passive part is active in the book.
ROUTED FILLED EMS received a message from the exchange that the order was executed aggressively (removed liquidity).
ROUTED CANCELED EMS received a message from the exchange that the order is in the canceled state. The order has not been in the book as the conditions for the entry were not satisfied.
NEW PARTIALLY_FILLED EMS received a message from the exchange that part of the passive order was filled.
NEW FILLED EMS received a message from the exchange that the passive order is filled.
NEW PENDING_CANCEL EMS received cancel request for the order and successfully relayed it to the Order destination.
NEW CANCELED EMS received a message from the exchange that the passive order was canceled.
PARTIALLY_FILLED FILLED EMS received a message from the exchange that the remaining part of the passive order is filled.
PARTIALLY_FILLED PENDING_CANCEL EMS received cancel request for the remaining part of the passive order and successfully relayed it to the Order destination.
PARTIALLY_FILLED CANCELED EMS received a message from the exchange that the remaining part of the passive order is canceled.
PENDING_CANCEL NEW EMS received a message from the exchange that updated the order before processing the cancellation request or the order cancellation request was rejected.
PENDING_CANCEL PARTIALLY_FILLED EMS received a message from the exchange that updated the order before processing the cancellation request or the order cancellation request was rejected.
PENDING_CANCEL FILLED EMS received a message from the exchange that updated the order before processing the cancellation request or the order cancellation request was rejected.
PENDING_CANCEL CANCELED EMS received a message from exchange` that updated the order before processing the cancellation request or the order cancellation request was rejected.

Order parameters

This section will describe parameters of the order in the EMS sofware.

Order type

EMS supports only the LIMIT order type. Market orders don't have price protection, and because of that, they are not supported. As an alternative, you can use the Immediate or Cancel IOC order and provide the worst execution price to achieve the same result.

Time in force

Time in force is a special instruction used when placing a trade to indicate how long an order will remain active before it expires.

The table below describes how to interpret time in force parameter values.

Time in force Shortcode Description
GOOD_TILL_CANCEL GTC A Good Till Cancel (GTC) is a default type of time-in-force. The order that lasts until is completed or canceled.
GOOD_TILL_TIME_EXCHANGE GTTE The Good Till Time Exchange (GTTE) time in force lets you set an expiration date and time up until which an order will be active in the book. The exchange handles the execution of the cancel originated from parameter.
GOOD_TILL_TIME_OEML GTTO The Good Till Time OEML (GTTO) time in force lets you set an expiration date and time up until which an order will be active in the book. The CoinAPI EMS Edge sending the cancel request originated from the parameter. Worth mentioning that: (a) The cancellation request will not be sent if the software will be not be running at the time of expiration. (b) This parameter does not depend on the exchange. (c) The clock of the server running CoinAPI EMS Edge is used to trigger the cancelation request at the expiration.
FILL_OR_KILL FOK Fill or kill (FOK) is a type of time in force used to instruct an exchange to execute a transaction immediately and completely or not at all. This order will only remove liquidity from the order book. It must be filled in its entirety or canceled (killed).
IMMEDIATE_OR_CANCEL IOC An immediate or cancel order (IOC) is a type of time in force used to instruct an exchange to execute all or part immediately and cancels any unfilled portion of the order. This order will only remove liquidity from the order book. It will fill whatever part of the order it can immediately and cancel any remaining amount so that no part of the order is added to the order book.

The table below displays a breakdown of the EMS support of specific time in force values by the Order destination.

Order destination id GTC GTTE GTTO FOK IOC
BINANCE X X X X
BINANCEUAT X X X X
BINANCEJE X X X X
BINANCEUS X X X X
BINANCEFTS X X X X
BINANCEFTSUAT X X X X
BINANCEFTSC X X X X
BINANCEFTSCUAT X X X X
BINANCEOPTV X X X X
BINANCEOPTVUAT X X X X
BITFINEX X X X X X
BITMEX X X X X
BITMEXUAT X X X X
BITSTAMP X X X X
BLOCKCHAINEXCHANGE X X X X
COINBASE X X X X
GEMINI X X X X
HITBTC X X X X X
KRAKEN X X X
KRAKENFTS X X X
POLONIEX X X X X
LMAXDIGITAL X X X X
LMAXDIGITALUAT X X X X
FTX X X X
FTXUS X X X
DERIBIT X X X X
DERIBITUAT X X X X

Legend: X - supported.

Execution instructions

Execution instruction puts restrictions on order handling at the matching engine. More than one instruction can apply to an order. The table below describes how to interpret execution instructions parameter values. Legend: X - supported.

Instruction Shortcode Description
AUCTION_ONLY AO An Auction Only (AO) instructs exchange that this order is for the auction only book for the next auction. The order may be cancelled up until the the auction locks, after which cancel requests will be rejected.
INDICATION_OF_INTEREST IOI An indication of interest (IOI) instructs exchange that this order should be processed as request for liquidity from block trading market markets.
MAKER_OR_CANCEL MOC A Maker or cancel (MOC) instructs exchange that this order will only add liquidity to the order book. If any part of the order could be filled immediately, the whole order will instead be rejected before any execution occurs. This instruction is also known as Post only or Participate don't initiate.
CANCEL_ON_DISCONNECT COD Cancel on System Failure (Cancel on disconnect)
DO_NOT_CANCEL_ON_DISCONNECT NCOD Reinstate on System Failure (Do not cancel on disconnect)
DO_NOT_INCREASE DNI (Reduce only) If part of a position is closed by any other means than the reduce-only order, the reduce-only order will be automatically adjusted downwards. If the trader decides to increase their position before the reduce-only order is executed, the quantity of the reduce-only order will not increase as well.

The table below displays a breakdown of the EMS support of specific execution instructions by the Order destination.

Order destination id MOC AO IOI COD NCOD DNI
BINANCE X
BINANCEUAT X
BINANCEJE X
BINANCEUS X
BINANCEFTS X
BINANCEFTSUAT X
BINANCEFTSC X
BINANCEFTSCUAT X
BINANCEOPTV X
BINANCEOPTVUAT X
BITFINEX X
BITMEX X
BITMEXUAT X
BITSTAMP
BLOCKCHAINEXCHANGE X
COINBASE X
GEMINI X X X
HITBTC
KRAKENFTS X
KRAKEN X
POLONIEX X
LMAXDIGITAL X X
LMAXDIGITALUAT X X
FTX X X
FTXUS X X
DERIBIT X X
DERIBITUAT X X

Legend: X - supported.

Time

For all input and output time values ISO 8601 standard is used.

Format specifier Description
yyyy The year as a four-digit number.
MM The month, from 01 through 12.
dd The day of the month, from 01 through 31.
HH The hour, using a 24-hour clock from 00 to 23.
mm The minute, from 00 through 59.
ss The second, from 00 through 59.
fff The milliseconds in a date and time value.
fffffff The ten millionths of a second in a date and time value.

Input time values are parsed using the following formats as far as possible:

Output time values are formatted using the following patterns:

  1. yyyy-MM-ddTHH:mm:ss.fffffffZ
  2. yyyy-MM-dd

EMS - Self Hosted Guide

This section will provide information related to self-hosted deployment of Execution Management System API (EMS API) software.

Configuration Manual

This section will provide the necessary information how to configure the CoinAPI EMS software.

Configuration keys and values

Configuration keys:

Configuration values:

Configuration providers

You can set the values of configuration parameters for the components using the following providers (in case of collision for any specific key):

  1. Command-line arguments

  2. Environment variables

Environment variables

To configure specific parameters using host or container environment variable, you must replace all occurrences of : with __ in the configuration parameter key, this is because the : separator doesn't work with environment variable hierarchical keys on all platforms. __, the double underscore, is:

For example, to set the value of the configuration parameter OEML:ExchangeId to BITSTAMP you would need to set the environment variable named OMS__ExchangeId to BITSTAMP.

Command-line arguments

You can set the configuration parameters by providing the arguments to the application executable.

The following example sets keys and values using the =: OEML:ExchangeId=BITSTAMP The following example sets keys and values using the /: /OEML:ExchangeId=BITSTAMP The following example sets keys and values using the --: --OEML:ExchangeId=BITSTAMP or --OEML:ExchangeId BITSTAMP

The key value:

Within the same command, don't mix command-line argument key-value pairs that use = with key-value pairs that use a space.

Configuration parameters

Key Type Description Is Required? Default value
OEML:ServiceDiscoveryMode string Type of backend used for service discovery. Supported values: COINAPI or CONSUL No COINAPI
OEML:LocalAddress string Override the local IP address advertised to other components. The value of this parameter is used in the CoinAPI Service Discovery mode. The API is listening to all the IP addresses available. However, the software still needs a valid single IP address accessible to other components, we will use this address for advertising in the CoinAPI Service Discovery mode only. No IP of the first IPv4 network interface.
OEML:Port int Set the TCP Port for REST and WebSocket API. No Randomly selected free port.
OEML:FIX:SocketAcceptPort int FIX Acceptor/Server Port No 3401
OEML:ExchangeId string Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70
BITSTAMP/2574. Allowed separators between the exchange identifier and the tag: ~/.,:;\[email protected]#$%^&*-_+=.
Yes
CoinAPI:ApiKey string CoinAPI API Key Yes
CoinAPI:UrlRest string CoinAPI REST API Endpoint No https://rest.coinapi.io/
CoinAPI:RatesUpdateIntervalSeconds int Update interval of the exchange rates in seconds from CoinAPI (using /v1/exchangerate/USD endpoint). 0 mean that rates will be pulled just on startup once, and -1 mean that they will not be downloaded at all. No 3600
OD:PublicApiKey string Customer Public Key for the Exchange Conditionally
OD:PrivateApiKey string Customer Private Key for the Exchange Conditionally
OD:PassPhrase string Customer passphrase for the Exchange Conditionally
OD:CustomerId string CustomerId of customer exchange account Conditionally
OD:Username string Exchange client username Conditionally
OD:Password string Exchange client password Conditionally
OD:Host string Exchange API endpoint host Conditionally
OD:Port int Exchange API endpoint port Conditionally
OD:RestApiUrl string Exchange REST API Url Conditionally

Exchange conditional parameters

The table below explains the conditional parameters by the OEML:ExchangeId value. For example when OEML:ExchangeId == "BITSTAMP" then OEML:Exchanges:BITSTAMP:CustomerId is required.

OEML:ExchangeId Required parameters Optional parameters
BINANCE OD:PublicApiKey OD:PrivateApiKey
BINANCEJE OD:PublicApiKey OD:PrivateApiKey
BINANCEUS OD:PublicApiKey OD:PrivateApiKey
BINANCEUAT OD:PublicApiKey OD:PrivateApiKey
BINANCEFTS OD:PublicApiKey OD:PrivateApiKey
BINANCEFTSUAT OD:PublicApiKey OD:PrivateApiKey
BINANCEFTSC OD:PublicApiKey OD:PrivateApiKey
BINANCEFTSCUAT OD:PublicApiKey OD:PrivateApiKey
BINANCEOPTV OD:PublicApiKey OD:PrivateApiKey
BINANCEOPTVUAT OD:PublicApiKey OD:PrivateApiKey
BITFINEX OD:PublicApiKey OD:PrivateApiKey
BITMEX OD:PublicApiKey OD:PrivateApiKey
BITMEXUAT OD:PublicApiKey OD:PrivateApiKey
BITSTAMP OD:PublicApiKey OD:PrivateApiKey OD:CustomerId
BLOCKCHAINEXCHANGE OD:PublicApiKey OD:PrivateApiKey
COINBASE OD:PublicApiKey OD:PrivateApiKey OD:PassPhrase OD:Host OD:RestApiUrl
GEMINI OD:PublicApiKey OD:PrivateApiKey
HITBTC OD:PublicApiKey OD:PrivateApiKey
KRAKENFTS OD:PublicApiKey OD:PrivateApiKey
KRAKEN OD:PublicApiKey OD:PrivateApiKey
POLONIEX OD:PublicApiKey OD:PrivateApiKey
LMAXDIGITAL OD:Username OD:Password OD:Host OD:Port
LMAXDIGITALUAT OD:Username OD:Password OD:Host OD:Port
FTX OD:PublicApiKey OD:PrivateApiKey OD:Host OD:Port OD:RestApiUrl
FTXUS OD:PublicApiKey OD:PrivateApiKey OD:Host OD:Port OD:RestApiUrl
DERIBIT OD:ClientId OD:ClientSecret OD:Host OD:Port
DERIBITUAT OD:ClientId OD:ClientSecret OD:Host OD:Port

Exchange specific recommendations

Kraken Futures KRAKENFTS

Whitelist your IP addresses

Whitelisting your IP addresses will give you the lowest possible latency and most stable connection to exchange servers in AWS EU-West 1. Whitelisting works by allowing you to skip CloudFlare. Here is an article on how to whitelist your IP addresses.

Consul Configuration (optional)

The end result should look like this:

{
  "datacenter": "hq",
  "data_dir": "C:\\consul\\data-hq",
  "log_level": "INFO",
  "server": false,
  "retry_join": [ "server-a", "server-b", "server-c" ],
  "ui": true,
  "http_config": {
    "response_headers": {
      "Access-Control-Allow-Origin": "*"
    }
  }
}

If your deployment including optional Consul Cluster for the Service Discovery layer then it's required to change CORS settings of the local Consul client on the hosts where the EMS WebUI will be used. This step is necessary as we need to discover the address of the EMS API component.

"http_config": { "response_headers": { "Access-Control-Allow-Origin": "*" } }

Installation Manual

This section will provide the necessary information how to install the CoinAPI EMS software.

Service discovery

The CoinAPI EMS API is capable of automaticaly detecting all your instances of CoinAPI EMS Edge service. This service discovery works by the one of the following methods:

  1. Using the CoinAPI EMS Central Cloud, every time you start CoinAPI EMS Edge, it will register automatically in our central cloud infrastructure.

  2. Using the HashiCorp Consul Cluster.

Using the CoinAPI EMS Central Cloud is a default, simple, and straightforward method. Only one disadvantage of using the CoinAPI EMS Central Cloud over Consul Cluster is that we do not measure the latencies if one order destination is registered more than one time in the cluster for failover scenarios. Then CoinAPI EMS Central Cloud will connect to the last started exchange; however, when using the Consul Cluster, it will connect to the order destination in the closest proximity data center to the datacenter where CoinAPI EMS API is run.

Running using an executable

To install the precompiled binary, download the latest version of the executable matching your system architecture from http://coinapi-releases.s3-website-us-east-1.amazonaws.com/

Our software is currently packaged as a zip file, and we currently do not plan to distribute it another way. Once the zip is downloaded, unzip it into any directory. The self-contained binary inside is necessary to run EMS, and any additional files are not required to run the software.

If you intend to access it from the command-line, make sure to place the binary somewhere on your PATH. You may require to add the executable to the system startup with all necessary parameters if you want the software to be started automatically after restart.

Running on Docker

#  example using only command line parameters
docker run -d --name=HITBTC --restart=always --net=host coinapi/oeml-api --OEML:ExchangeId HITBTC \
    --OD:PublicApiKey _public_api_key_ --OD:PrivateApiKey _private_api_key_ \
    --CoinAPI:ApiKey _coinapi_api_key_ 
docker run -d --restart=always --net=host coinapi/oeml-webui
docker run --net=host coinapi/oeml-cli

# example with enviroment variables file
cat > oeml.env << EOF
CoinAPI__ApiKey=_coinapi_api_key_

OD__PublicApiKey=_public_api_key_
OD__PrivateApiKey=_private_api_key_
EOF

docker run -d --name=HITBTC --restart=always --net=host coinapi/oeml-api --env-file oeml.env --OEML:ExchangeId HITBTC
docker run -d --name=BITFINEX --restart=always --net=host coinapi/oeml-api --env-file oeml.env --OEML:ExchangeId BITFINEX
docker run -d --name=OEML_EDGE --restart=always --net=host coinapi/oeml-api --env-file oeml.env

Our software is listed in public docker repository. To run the software on docker, use the following images:

To pass the configuration parameters using the environment variables (more information about this feature is available in the Configuration Manual section of this documentation), the environment variables must be provided into the container and not set on the host machine.

It's a good practice to lock itself into the specific version. To do that you can supply the version after image name and : separator, e.g. coinapi/oeml-api:1.1255

Running on Kubernetes Cluster

Our software is compatible with Kubernetes, and you can quickly run it on the cluster using our (Helm Charts)[https://github.com/coinapi/helm-charts]. Follow steps below to perform quickstart deployment.

Add the Repository to Helm

$ helm repo add coinapi-charts https://coinapi.github.io/helm-charts/
$ helm repo update

Helm chart configuration

The example config below will create two api pods, a composite pod, and a webui pod. One exchange account corresponds to one entry in the values.yaml file. That means, for multiple exchange accounts, please add one config entry with the matching API keys for each account i.e. binance-01, binance-02, kraken-01, kraken-02, etc. A complete list of all supported exchanges can be found in the API documentation.

cat > values.yaml << EOF

# Using WebUI (oeml-api/values.yaml)
webUI:
  enabled: true

# Using composite (oeml-api/values.yaml)
oemlCompositeAPI:
  enabled: true

# Setting the CoinAPI key (oeml-api/values.yaml)
extraEnv:
  - name: CoinAPI__ApiKey
    value: "YOUR_COINAPI_APIKEY"

# Specify listing of the accounts that EMS should manage (oeml-api/acct-dev.yaml)
accounts:
  # Binance spot market 
  - name: "binance"
    env:
      - name: OEML__ExchangeId
        value: "BINANCE"
      - name: OD__PublicApiKey
        value: "XXX"
      - name: OD__PrivateApiKey
        value: "YYY"

  # Binance spot testnet
  - name: "binanceuat"
    env:
      - name: OEML__ExchangeId
        value: "BINANCEUAT"
      - name: OD__PublicApiKey
        value: "XXX"
      - name: OD__PrivateApiKey
        value: "YYY"

EOF

Install ems-api latest version

$ helm install oeml-api coinapi-charts/oeml-api -f values.yaml

Install ems-api custom version

Version listing available here.

$ helm install oeml-api coinapi-charts/oeml-api -f values.yaml --set oemlAPI.tag={version}

Verify installation

kubectl get pods | grep oeml

Expected output:

oeml-api-binance-7754fc95cc-x2gkk        1/1     Running
oeml-api-binance-test-757c8bbd95-2mxd5   1/1     Running
oeml-api-composite-d5688f8f6-csbwh       1/1     Running
oeml-webui-685cd94d77-hq68j              1/1     Running 

Inspect

Inspect binance api pod:

kubectl logs oeml-api-binance-7754fc95cc-x2gkk

Inspect testnet api pod:

kubectl logs oeml-api-binance-test-757c8bbd95-2mxd5

Expected output for both api pods:

[02:22:04 WRN] Overriding address(es) 'http://+:80'. Binding
to endpoints defined in UseKestrel() instead.
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.

List services

kubectl get svc | grep oeml

Expected output:

oeml-api-binance        ClusterIP   10.112.9.119    <none>        80/TCP
oeml-api-binance-test   ClusterIP   10.112.15.239   <none>        80/TCP
oeml-api-composite      NodePort    10.112.8.159    <none>        80:30578/TCP
oeml-webui              NodePort    10.112.4.195    <none>        80:30857/TCP              

Connect to EMS API

The composite pod gives unified access to all connected exchanges & accounts. Therefore, the oeml-api-composite is the only pod required to connect to the EMS system.

Connect from within the cluster

Deploy a pod with a shell

kubectl apply -f https://k8s.io/examples/application/shell-demo.yaml

Verify the shell pod is online

kubectl get pod shell-demo

Get api-composite IP address:

kubectl get svc | grep oeml-api-composite
>oeml-api-composite      NodePort    10.112.8.159  

Exec into the pod

kubectl exec --stdin --tty shell-demo -- /bin/bash

CURL IP of the composite pod.

curl 10.112.8.159/v1/balances --header 'Accept: application/json'

CURL DNS of the composite pod.

DNS name may vary depending on cloud provider.

curl oeml-api-composite.default.svc.cluster.local/v1/balances --header 'Accept: application/json'

Expected output:

[
  {
    "type": "BALANCE_SNAPSHOT",
    "exchange_id": "BINANCE",
  },
  {
    "type": "BALANCE_SNAPSHOT",
    "exchange_id": "BINANCEUAT",
    "data": [
      {
        "id": "XRP",
        "asset_id_exchange": "XRP",
        "asset_id_coinapi": null,
        "balance": 50000.00000000,
        "available": 50000.00000000,
        "locked": 0.00000000,
        "traded": 0.0,
        "last_updated_by": "EXCHANGE",
        "rate_usd": null
      },
      // more entries
      ]
  }
]

Exit the shell pod

exit 

Delete shell pod

kubectl delete pod shell-demo

Connect cluster to localhost

Port-forward from cluster port 80 to localhost port 8080

 kubectl port-forward service/oeml-api-composite 8080:80

Expected output:

Forwarding from 127.0.0.1:8080 -> 80
Forwarding from [::1]:8080 -> 80

CURL account balance.

curl localhost:8080/v1/balances --header 'Accept: application/json'

Expected output:

[
  {
    "type": "BALANCE_SNAPSHOT",
    "exchange_id": "BINANCE",
  },
  {
    "type": "BALANCE_SNAPSHOT",
    "exchange_id": "BINANCEUAT",
    "data": [
      {
      // more entries
      },
      ]
  }
]

Management Guide

This section will provide the necessary information on how to manage the CoinAPI EMS software.

To run the EMS cluster, you will need to:

  1. (optional) Deploy the HashiCorp Consul Cluster for Service Discovery, if you don't want or can't use our included free of charge discovery service.

  2. Run the CoinAPI EMS Edge software instance per each managed exchange account.

  3. Run single or multiple instances of the CoinAPI EMS API software.

If the lowest latency is required, start the instance per location or server where the API will is used to minimize latency between API client and the EMS API Server.

  1. (optional) Run the CoinAPI EMS WebUI to have GUI to the cluster.

  2. Done! All the exchange accounts can be managed using the single API.

Installation

CoinAPI EMS can be installed using several approaches:

Our software is compiled for the following architectures:

Take a look at the Starter Guide of this documentation for more information how to run the software in the specific conditions.

Upgrading

Currently, all components are stateless. Upgrading stateless components is limited to replacing the binaries or running the new docker image.

Versioning & Compatibility

Our software is versioned using the Major.Minor(+branch) pattern. Major version number is incremented manually on our side, and its scope is for the EMS project. The Minor version number is incremented on every release automatically separately for every component.

You can assume that our software components will work together when their Major version numbers are the same.

Time synchronization

EMS highly depends on the current time to perform actions and correctly timestamp the data for real-time trading, risk management, compliance, or reporting.

For the time synchronization we strongly recommending:

If you can't use any of the programs above for reasons like:

Then it's worth trying solutions below (ordered from the best to worst options):

  1. ntp (Linux, FreeBSD, NetBSD, OpenBSD, Solaris, macOS, Windows)

  2. openntpd (Linux, FreeBSD, NetBSD, OpenBSD, Solaris, macOS)

If need the sub-millisecond or sub-nanosecond accuracy take a look there:

  1. Meinberg Radio Clocks

  2. White Rabbit

Limits

This section will list all known software limitations.

Limit description Limit value
Maximum number of managed exchange accounts in a single cluster Unlimited
Maximum number of managed exchange accounts per cluster host when running an executable 65,535
Maximum number of managed exchange accounts per cluster node when running on Docker or Docker Swarm 1024
Maximum number of managed exchange accounts per cluster node when running on Kubernetes 250
Maximum number of managed exchange accounts per cluster node when running on Amazon Elastic Kubernetes Service (EKS) from 4 to 737
Maximum number of managed exchange accounts per cluster node when running on Google Kubernetes Engine (GKE) 100
Maximum number of managed exchange accounts per cluster node when running on Azure Kubernetes Service (AKS) 250

Changelog

It's a log of: BREAKING CHANGES, FEATURES, IMPROVEMENTS, BUG FIXES or other NOTES per public version.

2.0.12829 (March 18, 2022)

BUG FIXES:

2.0.12813 (March 17, 2022)

FEATURES:

2.0.12808 (March 17, 2022)

BUG FIXES:

2.0.12782 (March 16, 2022)

BUG FIXES:

2.0.12325 (February 25, 2022)

BUG FIXES:

2.0.12316 (February 25, 2022)

FEATURES:

IMPROVEMENTS:

BUG FIXES:

1.9281 (September 16, 2021)

FEATURES:

BUG FIXES:

1.9136 (September 09, 2021)

BUG FIXES:

1.9066 (August 27, 2021)

FEATURES:

1.8931 (August 11, 2021)

FEATURES:

1.8893 (August 06, 2021)

IMPROVEMENTS:

1.8889 (August 06, 2021)

BUG FIXES:

1.8877 (August 05, 2021)

FEATURES:

1.8821 (July 29, 2021)

FEATURES:

1.8797 (July 23, 2021)

IMPROVEMENTS:

1.8787 (July 22, 2021)

BREAKING CHANGES:

IMPROVEMENTS:

1.8781 (July 22, 2021)

FEATURES:

1.8713 (July 14, 2021)

BUG FIXES:

1.8707 (July 13, 2021)

FEATURES:

IMPROVEMENTS:

Integrations & Plugins

This section is reserved for Integrations, plugins or other external tools or modules that make it easier to work with EMS API.

Prometheus metrics

In this section, we will describe the metrics exposed by the software on the /metrics endpoint.

If you are using our Helm chart then ServiceMonitor objects required by Prometheus to pull data are automatically installed by default version of the values file (helm-charts/charts/oeml-api/values.yaml).

Published metrics:

Metric name Parameters Description
coinapi_oeml_total_open_order ExchangeId Number of all orders placed since the start of oeml
coinapi_oeml_open_order ExchangeId The current number of open orders
coinapi_oeml_open_order_by_status ExchangeId, Status Current number of order statuses
coinapi_oeml_total_order_per_symbol ExchangeId, Symbol Number of orders per symbol since start oeml
coinapi_oeml_open_position ExchangeId The current number of open posiotions
coinapi_oeml_balance_total ExchangeId, Symbol Current balance - total per symbol
coinapi_oeml_balance_free ExchangeId, Symbol Current balance - free per symbol
coinapi_oeml_balance_locked ExchangeId, Symbol Current balance - locked per symbol
coinapi_oeml_total_error ExchangeId, ErrorText Total error by type
coinapi_oeml_actual_balance_total_usd_by_symbol ExchangeId, Symbol Actual total balance usd by symbol
coinapi_oeml_total_balance_value_in_usd ExchangeId Total balance value in dollars
coinapi_oeml_orders_change_status_time ExchangeId, Status1, Status2 Orders change status time (time in miliseconds)

Deployment

In this section we are listing tools that could be used to deploy or manage our software.

EMS - Managed Cloud REST API

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

This section will provide necessary information about the CoinAPI EMS Managed Cloud REST API protocol.

This API is used to manage the overall deployment of Execution Management System API (EMS API) software, which means that in this API, you define the accounts, credentials, and configurations for the order destinations or identify the CoinAPI endpoints where you need to connect to access the EMS API.

Implemented Standards:

Endpoints

Environment Url
Production https://ems-mgmt.coinapi.io/
Sandbox https://ems-mgmt-sandbox.coinapi.io/

Authentication

To use resources that require authorized access, you will need to provide an API key to us when making HTTP requests.

There are 2 methods for passing the API key to us, you only need to use one:

  1. Custom authorization header named X-CoinAPI-Key
  2. Query string parameter named apikey

Custom authorization header

You can authorize by providing additional custom header named X-CoinAPI-Key and API key as its value.

Assuming that your API key is 73034021-THIS-IS-SAMPLE-KEY, then the authorization header you should send to us will look like:

X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY

Query string authorization parameter

You can authorize by providing an additional parameter named apikey with a value equal to your API key in the query string of your HTTP request.

Assuming that your API key is 73034021-THIS-IS-SAMPLE-KEY and that you want to request all accounts, then your query string should look like this:

GET /v1/accounts?apikey=73034021-THIS-IS-SAMPLE-KEY

Account

In the account section you can manage the accounts on the exchanges (order destinations).

Get accounts GET

Code samples

curl --request GET \
  --url https://ems-mgmt-sandbox.coinapi.io/v1/accounts \
  --header 'Accept: application/json' \
  --header 'X-CoinAPI-Key: API_KEY'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/accounts");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
request.AddHeader("X-CoinAPI-Key", "API_KEY");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/accounts"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")
    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-mgmt-sandbox.coinapi.io/v1/accounts");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/accounts",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

headers = {
    'Accept': "application/json",
    'X-CoinAPI-Key': "API_KEY"
    }

conn.request("GET", "/v1/accounts", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/accounts")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'
request["X-CoinAPI-Key"] = 'API_KEY'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-mgmt-sandbox.coinapi.io/v1/accounts")
  .header("Accept", "application/json")
  .header("X-CoinAPI-Key", "API_KEY")
  .asString();

GET /v1/accounts

Get all accounts maintained for your subscription in the EMS API.

Parameters
Parameter In Type Required Description
filter_exchange_id query array[string] false Exchange id of the specific account to provide single account instead of the list of all accounts

Example responses

200 Response

[
  {
    "exchange_id": "string",
    "parameters": [
      {
        "key": "PublicApiKey",
        "value": "36279b02-d24f-40be-a61b-e9fd7de46dd6"
      }
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline

Response Schema

Status Code 200

Name Type Required Description
» exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
» parameters [KeyValue] false Exchange specific configuration parameters
»» key string false No description
»» value string false No description

Add or update account POST

Code samples

curl --request POST \
  --url https://ems-mgmt-sandbox.coinapi.io/v1/accounts \
  --header 'Content-Type: application/json' \
  --header 'X-CoinAPI-Key: API_KEY' \
  --data '{"exchange_id":"string","parameters":[{"key":"PublicApiKey","value":"36279b02-d24f-40be-a61b-e9fd7de46dd6"}]}'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/accounts");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("X-CoinAPI-Key", "API_KEY");
request.AddParameter("application/json", "{\"exchange_id\":\"string\",\"parameters\":[{\"key\":\"PublicApiKey\",\"value\":\"36279b02-d24f-40be-a61b-e9fd7de46dd6\"}]}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "strings"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/accounts"

    payload := strings.NewReader("{\"exchange_id\":\"string\",\"parameters\":[{\"key\":\"PublicApiKey\",\"value\":\"36279b02-d24f-40be-a61b-e9fd7de46dd6\"}]}")

    req, _ := http.NewRequest("POST", url, payload)

    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = JSON.stringify({
  "exchange_id": "string",
  "parameters": [
    {
      "key": "PublicApiKey",
      "value": "36279b02-d24f-40be-a61b-e9fd7de46dd6"
    }
  ]
});

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://ems-mgmt-sandbox.coinapi.io/v1/accounts");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/accounts",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"exchange_id\":\"string\",\"parameters\":[{\"key\":\"PublicApiKey\",\"value\":\"36279b02-d24f-40be-a61b-e9fd7de46dd6\"}]}",
  CURLOPT_HTTPHEADER => [
    "Content-Type: application/json",
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

payload = "{\"exchange_id\":\"string\",\"parameters\":[{\"key\":\"PublicApiKey\",\"value\":\"36279b02-d24f-40be-a61b-e9fd7de46dd6\"}]}"

headers = {
    'Content-Type': "application/json",
    'X-CoinAPI-Key': "API_KEY"
    }

conn.request("POST", "/v1/accounts", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/accounts")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request["X-CoinAPI-Key"] = 'API_KEY'
request.body = "{\"exchange_id\":\"string\",\"parameters\":[{\"key\":\"PublicApiKey\",\"value\":\"36279b02-d24f-40be-a61b-e9fd7de46dd6\"}]}"

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.post("https://ems-mgmt-sandbox.coinapi.io/v1/accounts")
  .header("Content-Type", "application/json")
  .header("X-CoinAPI-Key", "API_KEY")
  .body("{\"exchange_id\":\"string\",\"parameters\":[{\"key\":\"PublicApiKey\",\"value\":\"36279b02-d24f-40be-a61b-e9fd7de46dd6\"}]}")
  .asString();

POST /v1/accounts

Add new or update existing exchange account for your subscription in the EMS API.

Body parameter

{
  "exchange_id": "string",
  "parameters": [
    {
      "key": "PublicApiKey",
      "value": "36279b02-d24f-40be-a61b-e9fd7de46dd6"
    }
  ]
}
Parameters
Parameter In Type Required Description
body body AccountData true Exchange account object that needs to be add/update to the EMS
» exchange_id body string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
» parameters body [KeyValue] false Parameters required to log into the exchange
»» key body string false No description
»» value body string false No description
Detailed descriptions

» exchange_id: Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg: BITSTAMP BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70` BITSTAMP/2574 Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.

Responses

Status Meaning Description Schema
400 Bad Request Invalid exchange id None
405 Method Not Allowed Validation exception None

Delete account DELETE

Code samples

curl --request DELETE \
  --url 'https://ems-mgmt-sandbox.coinapi.io/v1/accounts?exchange_id=string' \
  --header 'X-CoinAPI-Key: API_KEY'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/accounts?exchange_id=string");
var request = new RestRequest(Method.DELETE);
request.AddHeader("X-CoinAPI-Key", "API_KEY");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/accounts?exchange_id=string"

    req, _ := http.NewRequest("DELETE", url, nil)

    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://ems-mgmt-sandbox.coinapi.io/v1/accounts?exchange_id=string");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/accounts?exchange_id=string",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => [
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

headers = { 'X-CoinAPI-Key': "API_KEY" }

conn.request("DELETE", "/v1/accounts?exchange_id=string", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/accounts?exchange_id=string")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["X-CoinAPI-Key"] = 'API_KEY'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.delete("https://ems-mgmt-sandbox.coinapi.io/v1/accounts?exchange_id=string")
  .header("X-CoinAPI-Key", "API_KEY")
  .asString();

DELETE /v1/accounts

Delete specific exchange account maintained by the EMS API for your subscription.

Parameters
Parameter In Type Required Description
exchange_id query array[string] true Exchange identifier of the account to delete

Responses

Status Meaning Description Schema
404 Not Found Exchange account not found None

Delete all accounts DELETE

Code samples

curl --request DELETE \
  --url https://ems-mgmt-sandbox.coinapi.io/v1/accounts/all \
  --header 'X-CoinAPI-Key: API_KEY'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/accounts/all");
var request = new RestRequest(Method.DELETE);
request.AddHeader("X-CoinAPI-Key", "API_KEY");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/accounts/all"

    req, _ := http.NewRequest("DELETE", url, nil)

    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("DELETE", "https://ems-mgmt-sandbox.coinapi.io/v1/accounts/all");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/accounts/all",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "DELETE",
  CURLOPT_HTTPHEADER => [
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

headers = { 'X-CoinAPI-Key': "API_KEY" }

conn.request("DELETE", "/v1/accounts/all", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/accounts/all")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Delete.new(url)
request["X-CoinAPI-Key"] = 'API_KEY'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.delete("https://ems-mgmt-sandbox.coinapi.io/v1/accounts/all")
  .header("X-CoinAPI-Key", "API_KEY")
  .asString();

DELETE /v1/accounts/all

Delete all exchange accounts maintained by the EMS API for your subscription.

Responses

Status Meaning Description Schema
200 OK OK None

Exchange

In the exchange section we provide information about the exchanges supported in the EMS API.

Get exchange configuration GET

Code samples

curl --request GET \
  --url https://ems-mgmt-sandbox.coinapi.io/v1/exchanges \
  --header 'Accept: application/json' \
  --header 'X-CoinAPI-Key: API_KEY'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/exchanges");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
request.AddHeader("X-CoinAPI-Key", "API_KEY");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/exchanges"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")
    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-mgmt-sandbox.coinapi.io/v1/exchanges");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/exchanges",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

headers = {
    'Accept': "application/json",
    'X-CoinAPI-Key': "API_KEY"
    }

conn.request("GET", "/v1/exchanges", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/exchanges")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'
request["X-CoinAPI-Key"] = 'API_KEY'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-mgmt-sandbox.coinapi.io/v1/exchanges")
  .header("Accept", "application/json")
  .header("X-CoinAPI-Key", "API_KEY")
  .asString();

GET /v1/exchanges

Get information about the required parameters or server site location of the exchanges supported in the EMS API.

Example responses

200 Response

[
  {
    "exchange_id": "string",
    "location_id": "string",
    "required_parameters": [
      "string"
    ]
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline

Response Schema

Status Code 200

Name Type Required Description
anonymous [ExchangeLoginRequire] false No description
» exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
» location_id string false Location identifier
» required_parameters [string] false Parameters required to log into the exchange

Location

In the location section we provide information about the server sites used in the EMS API.

Get site locations GET

Code samples

curl --request GET \
  --url https://ems-mgmt-sandbox.coinapi.io/v1/locations \
  --header 'Accept: application/json' \
  --header 'X-CoinAPI-Key: API_KEY'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/locations");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
request.AddHeader("X-CoinAPI-Key", "API_KEY");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/locations"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")
    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-mgmt-sandbox.coinapi.io/v1/locations");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/locations",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

headers = {
    'Accept': "application/json",
    'X-CoinAPI-Key': "API_KEY"
    }

conn.request("GET", "/v1/locations", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/locations")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'
request["X-CoinAPI-Key"] = 'API_KEY'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-mgmt-sandbox.coinapi.io/v1/locations")
  .header("Accept", "application/json")
  .header("X-CoinAPI-Key", "API_KEY")
  .asString();

GET /v1/locations

This endpoint providing information about the server site locations supported in the EMS API.

Example responses

200 Response

[
  {
    "location_id": "aws-us-east-1",
    "region_name": "us-east-1",
    "provider_name": "aws"
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline

Response Schema

Status Code 200

Name Type Required Description
anonymous [Locations] false No description
» location_id string false CoinAPI location identifier
» region_name string false Identifier of the region by the location provider
» provider_name string false Identifier of the location provider

Endpoints

In the endpoint section we provide information about the EMS API endpoints to the server sites used in the EMS API deployment for your API Key.

Get API endpoints GET

Code samples

curl --request GET \
  --url https://ems-mgmt-sandbox.coinapi.io/v1/endpoints \
  --header 'Accept: application/json' \
  --header 'X-CoinAPI-Key: API_KEY'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/endpoints");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
request.AddHeader("X-CoinAPI-Key", "API_KEY");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/endpoints"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")
    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-mgmt-sandbox.coinapi.io/v1/endpoints");
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/endpoints",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

headers = {
    'Accept': "application/json",
    'X-CoinAPI-Key': "API_KEY"
    }

conn.request("GET", "/v1/endpoints", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/endpoints")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'
request["X-CoinAPI-Key"] = 'API_KEY'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-mgmt-sandbox.coinapi.io/v1/endpoints")
  .header("Accept", "application/json")
  .header("X-CoinAPI-Key", "API_KEY")
  .asString();

GET /v1/endpoints

Get all API endpoints that the EMS API expose for your subscription.

Parameters
Parameter In Type Required Description
filter_exchange_id query array[string] false Exchange id

Example responses

200 Response

[
  {
    "exchange_id": "KRAKEN",
    "location_id": "aws-us-east-2",
    "endpoint_schema": "https",
    "endpoint_host": "1314.51253.51.ec2.eu-west-1.amazonaws.com",
    "endpoint_url": "https://1314.51253.51.ec2.eu-west-1.amazonaws.com/"
  }
]

Responses

Status Meaning Description Schema
200 OK OK Inline

Response Schema

Status Code 200

Name Type Required Description
anonymous [AccountEndpoint] false No description
» exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
» location_id string false Location identifier
» endpoint_schema string false Endpoint schema
» endpoint_host string false Endpoint host
» endpoint_url string false Endpoint URL

Certificate

In the certificate section we generate TLS certificates that can be used as method of authenticating to the EMS API.

Get authentication certificate GET

Code samples

curl --request GET \
  --url https://ems-mgmt-sandbox.coinapi.io/v1/certificate/pem \
  --header 'Accept: text/plain' \
  --header 'X-CoinAPI-Key: API_KEY'
var client = new RestClient("https://ems-mgmt-sandbox.coinapi.io/v1/certificate/pem");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "text/plain");
request.AddHeader("X-CoinAPI-Key", "API_KEY");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-mgmt-sandbox.coinapi.io/v1/certificate/pem"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "text/plain")
    req.Header.Add("X-CoinAPI-Key", "API_KEY")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-mgmt-sandbox.coinapi.io/v1/certificate/pem");
xhr.setRequestHeader("Accept", "text/plain");
xhr.setRequestHeader("X-CoinAPI-Key", "API_KEY");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-mgmt-sandbox.coinapi.io/v1/certificate/pem",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: text/plain",
    "X-CoinAPI-Key: API_KEY"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-mgmt-sandbox.coinapi.io")

headers = {
    'Accept': "text/plain",
    'X-CoinAPI-Key': "API_KEY"
    }

conn.request("GET", "/v1/certificate/pem", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-mgmt-sandbox.coinapi.io/v1/certificate/pem")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'text/plain'
request["X-CoinAPI-Key"] = 'API_KEY'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-mgmt-sandbox.coinapi.io/v1/certificate/pem")
  .header("Accept", "text/plain")
  .header("X-CoinAPI-Key", "API_KEY")
  .asString();

GET /v1/certificate/pem

Providing PEM file with the Private Key, Public Key and the Certificate to authenticate to the EMS API.

Example responses

200 Response

"-----BEGIN PUBLIC KEY-----\nMIIBIjANB.......\n-----END PUBLIC KEY-----\n-----BEGIN PRIVATE KEY-----\nMIIEvwIAA.......\n-----END PRIVATE KEY-----\n-----BEGIN CERTIFICATE-----\nMIIDEjCCA.......\n-----END CERTIFICATE-----\n"

Responses

Status Meaning Description Schema
200 OK OK string

Schemas

AccountInfo

{
  "exchange_id": "string"
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.

AccountData

{
  "exchange_id": "string",
  "parameters": [
    {
      "key": "PublicApiKey",
      "value": "36279b02-d24f-40be-a61b-e9fd7de46dd6"
    }
  ]
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
parameters [KeyValue] false Parameters required to log into the exchange

UpdateAccount

{
  "exchange_id": "string",
  "parameters": [
    {
      "key": "PublicApiKey",
      "value": "36279b02-d24f-40be-a61b-e9fd7de46dd6"
    }
  ]
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
parameters [KeyValue] false Parameters required to log into the exchange

GetAccount

{
  "exchange_id": "string",
  "parameters": [
    {
      "key": "PublicApiKey",
      "value": "36279b02-d24f-40be-a61b-e9fd7de46dd6"
    }
  ]
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
parameters [KeyValue] false Exchange specific configuration parameters

ExchangeLoginRequire

{
  "exchange_id": "string",
  "location_id": "string",
  "required_parameters": [
    "string"
  ]
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
location_id string false Location identifier
required_parameters [string] false Parameters required to log into the exchange

Locations

{
  "location_id": "aws-us-east-1",
  "region_name": "us-east-1",
  "provider_name": "aws"
}

Properties

Name Type Required Description
location_id string false CoinAPI location identifier
region_name string false Identifier of the region by the location provider
provider_name string false Identifier of the location provider

KeyValue

{
  "key": "PublicApiKey",
  "value": "36279b02-d24f-40be-a61b-e9fd7de46dd6"
}

Properties

Key Value pair used to configure exchange accounts.

Name Type Required Description
key string false No description
value string false No description

AccountEndpoint

{
  "exchange_id": "KRAKEN",
  "location_id": "aws-us-east-2",
  "endpoint_schema": "https",
  "endpoint_host": "1314.51253.51.ec2.eu-west-1.amazonaws.com",
  "endpoint_url": "https://1314.51253.51.ec2.eu-west-1.amazonaws.com/"
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier and optional tag identifying specific account configured when the software will be managing multiple accounts on the same exchange; for eg:
BITSTAMP
BITSTAMP/7c177641-74bd-4dbe-9b01-2497c12a5f70`
BITSTAMP/2574
Allowed separators between the exchange identifier and the tag: ~/.,:;[email protected]#$%^&*-_+=.
location_id string false Location identifier
endpoint_schema string false Endpoint schema
endpoint_host string false Endpoint host
endpoint_url string false Endpoint URL

EMS - REST API

Scroll down for code samples, example requests and responses. Select a language for code samples from the tabs above or the mobile navigation menu.

This section will provide necessary information about the CoinAPI EMS REST API protocol.
This API is also available in the Postman application: https://postman.coinapi.io/


Implemented Standards:

Endpoints

Deployment method Environment Url
Managed Cloud Production Use Managed Cloud REST API /v1/locations to get specific endpoints to each server site where your deployments span
Managed Cloud Sandbox https://ems-gateway-aws-eu-central-1-dev.coinapi.io/
Self Hosted Production IP Address of the ems-gateway container/excecutable in the closest server site to the caller location
Self Hosted Sandbox IP Address of the ems-gateway container/excecutable in the closest server site to the caller location

Authentication

If the software is deployed as Self-Hosted then API do not require authentication as inside your infrastructure, your company is responsible for the security and access controls.

If the software is deployed in our Managed Cloud, there are 2 methods for authenticating with us, you only need to use one:

  1. Custom authorization header named X-CoinAPI-Key with the API Key
  2. Query string parameter named apikey with the API Key
  3. TLS Client Certificate from the Managed Cloud REST API (/v1/certificate/pem endpoint) while establishing a TLS session with us.

Custom authorization header

You can authorize by providing additional custom header named X-CoinAPI-Key and API key as its value. Assuming that your API key is 73034021-THIS-IS-SAMPLE-KEY, then the authorization header you should send to us will look like:

X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY

Query string authorization parameter

You can authorize by providing an additional parameter named apikey with a value equal to your API key in the query string of your HTTP request. Assuming that your API key is 73034021-THIS-IS-SAMPLE-KEY and that you want to request all balances, then your query string should look like this:

GET /v1/balances?apikey=73034021-THIS-IS-SAMPLE-KEY

Orders

Order statuses and the lifecycle are documented in the separate section: EMS / Starter Guide / Order Lifecycle

Get open orders GET

Code samples

curl --request GET \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders \
  --header 'Accept: application/json'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

headers = { 'Accept': "application/json" }

conn.request("GET", "/v1/orders", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders")
  .header("Accept", "application/json")
  .asString();

GET /v1/orders

Get last execution reports for open orders across all or single exchange.

Parameters
Parameter In Type Required Description
exchange_id query string false Filter the open orders to the specific exchange.

Example responses

200 Response

[
  {
    "exchange_id": "KRAKEN",
    "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "symbol_id_exchange": "XBT/USDT",
    "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
    "amount_order": 0.045,
    "price": 0.0783,
    "side": "BUY",
    "order_type": "LIMIT",
    "time_in_force": "GOOD_TILL_CANCEL",
    "expire_time": "2020-01-01T10:45:20.1677709Z",
    "exec_inst": [
      "MAKER_OR_CANCEL"
    ],
    "client_order_id_format_exchange": "f81211e2-27c4-b86a-8143-01088ba9222c",
    "exchange_order_id": 3456456754,
    "amount_open": 0.22,
    "amount_filled": 0,
    "avg_px": 0.0783,
    "status": "RECEIVED",
    "status_history": [
      [
        [
          [
            "RECEIVED",
            "2020-05-27T11:16:20.1677709Z"
          ],
          [
            "REJECTED",
            "2020-05-27T11:16:20.1677710Z"
          ]
        ]
      ]
    ],
    "error_message": "{\"result\":\"error\",\"reason\":\"InsufficientFunds\",\"message\":\"Failed to place buy order on symbol 'BTCUSD' for price $7,000.00 and quantity 0.22 BTC due to insufficient funds\"}",
    "fills": [
      {
        "time": "2020-01-01T10:45:20.1677709Z",
        "price": 10799.2,
        "amount": 0.002
      }
    ]
  }
]

490 Response

Responses

Status Meaning Description Schema
200 OK Collection of order execution reports. OrderExecutionReports
490 Not Applicable Filtered exchange is unreachable. MessageReject

Send new order POST

Code samples

curl --request POST \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"exchange_id":"KRAKEN","client_order_id":"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b","symbol_id_exchange":"XBT/USDT","symbol_id_coinapi":"KRAKEN_SPOT_BTC_USDT","amount_order":0.045,"price":0.0783,"side":"BUY","order_type":"LIMIT","time_in_force":"GOOD_TILL_CANCEL","expire_time":"2020-01-01T10:45:20.1677709Z","exec_inst":["MAKER_OR_CANCEL"]}'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddParameter("application/json", "{\"exchange_id\":\"KRAKEN\",\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\",\"symbol_id_exchange\":\"XBT/USDT\",\"symbol_id_coinapi\":\"KRAKEN_SPOT_BTC_USDT\",\"amount_order\":0.045,\"price\":0.0783,\"side\":\"BUY\",\"order_type\":\"LIMIT\",\"time_in_force\":\"GOOD_TILL_CANCEL\",\"expire_time\":\"2020-01-01T10:45:20.1677709Z\",\"exec_inst\":[\"MAKER_OR_CANCEL\"]}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "strings"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders"

    payload := strings.NewReader("{\"exchange_id\":\"KRAKEN\",\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\",\"symbol_id_exchange\":\"XBT/USDT\",\"symbol_id_coinapi\":\"KRAKEN_SPOT_BTC_USDT\",\"amount_order\":0.045,\"price\":0.0783,\"side\":\"BUY\",\"order_type\":\"LIMIT\",\"time_in_force\":\"GOOD_TILL_CANCEL\",\"expire_time\":\"2020-01-01T10:45:20.1677709Z\",\"exec_inst\":[\"MAKER_OR_CANCEL\"]}")

    req, _ := http.NewRequest("POST", url, payload)

    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = JSON.stringify({
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": [
    "MAKER_OR_CANCEL"
  ]
});

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"exchange_id\":\"KRAKEN\",\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\",\"symbol_id_exchange\":\"XBT/USDT\",\"symbol_id_coinapi\":\"KRAKEN_SPOT_BTC_USDT\",\"amount_order\":0.045,\"price\":0.0783,\"side\":\"BUY\",\"order_type\":\"LIMIT\",\"time_in_force\":\"GOOD_TILL_CANCEL\",\"expire_time\":\"2020-01-01T10:45:20.1677709Z\",\"exec_inst\":[\"MAKER_OR_CANCEL\"]}",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "Content-Type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

payload = "{\"exchange_id\":\"KRAKEN\",\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\",\"symbol_id_exchange\":\"XBT/USDT\",\"symbol_id_coinapi\":\"KRAKEN_SPOT_BTC_USDT\",\"amount_order\":0.045,\"price\":0.0783,\"side\":\"BUY\",\"order_type\":\"LIMIT\",\"time_in_force\":\"GOOD_TILL_CANCEL\",\"expire_time\":\"2020-01-01T10:45:20.1677709Z\",\"exec_inst\":[\"MAKER_OR_CANCEL\"]}"

headers = {
    'Content-Type': "application/json",
    'Accept': "application/json"
    }

conn.request("POST", "/v1/orders", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request["Accept"] = 'application/json'
request.body = "{\"exchange_id\":\"KRAKEN\",\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\",\"symbol_id_exchange\":\"XBT/USDT\",\"symbol_id_coinapi\":\"KRAKEN_SPOT_BTC_USDT\",\"amount_order\":0.045,\"price\":0.0783,\"side\":\"BUY\",\"order_type\":\"LIMIT\",\"time_in_force\":\"GOOD_TILL_CANCEL\",\"expire_time\":\"2020-01-01T10:45:20.1677709Z\",\"exec_inst\":[\"MAKER_OR_CANCEL\"]}"

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.post("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders")
  .header("Content-Type", "application/json")
  .header("Accept", "application/json")
  .body("{\"exchange_id\":\"KRAKEN\",\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\",\"symbol_id_exchange\":\"XBT/USDT\",\"symbol_id_coinapi\":\"KRAKEN_SPOT_BTC_USDT\",\"amount_order\":0.045,\"price\":0.0783,\"side\":\"BUY\",\"order_type\":\"LIMIT\",\"time_in_force\":\"GOOD_TILL_CANCEL\",\"expire_time\":\"2020-01-01T10:45:20.1677709Z\",\"exec_inst\":[\"MAKER_OR_CANCEL\"]}")
  .asString();

POST /v1/orders

This request creating new order for the specific exchange.

Body parameter

{
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": [
    "MAKER_OR_CANCEL"
  ]
}
Parameters
Parameter In Type Required Description
body body OrderNewSingleRequest true OrderNewSingleRequest object.
» exchange_id body string true Exchange identifier used to identify the routing destination.
» client_order_id body string true The unique identifier of the order assigned by the client.
» symbol_id_exchange body string false Exchange symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
» symbol_id_coinapi body string false CoinAPI symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
» amount_order body number true Order quantity.
» price body number true Order price.
» side body OrdSide true Side of order.
» order_type body OrdType true Order types are documented in the separate section: EMS / Starter Guide / Order parameters / Order type
» time_in_force body TimeInForce true Order time in force options are documented in the separate section: EMS / Starter Guide / Order parameters / Time in force
» expire_time body date false Expiration time. Conditionaly required for orders with time_in_force = GOOD_TILL_TIME_EXCHANGE or GOOD_TILL_TIME_OEML.
» exec_inst body [string] false Order execution instructions are documented in the separate section: EMS / Starter Guide / Order parameters / Execution instructions
Enumerated Values
Parameter Value
» side BUY
» side SELL
» order_type LIMIT
» time_in_force GOOD_TILL_CANCEL
» time_in_force GOOD_TILL_TIME_EXCHANGE
» time_in_force GOOD_TILL_TIME_OMS
» time_in_force FILL_OR_KILL
» time_in_force IMMEDIATE_OR_CANCEL
» exec_inst MAKER_OR_CANCEL
» exec_inst AUCTION_ONLY
» exec_inst INDICATION_OF_INTEREST

Example responses

200 Response

{
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": [
    "MAKER_OR_CANCEL"
  ],
  "client_order_id_format_exchange": "f81211e2-27c4-b86a-8143-01088ba9222c",
  "exchange_order_id": 3456456754,
  "amount_open": 0.22,
  "amount_filled": 0,
  "avg_px": 0.0783,
  "status": "RECEIVED",
  "status_history": [
    [
      [
        [
          "RECEIVED",
          "2020-05-27T11:16:20.1677709Z"
        ],
        [
          "REJECTED",
          "2020-05-27T11:16:20.1677710Z"
        ]
      ]
    ]
  ],
  "error_message": "{\"result\":\"error\",\"reason\":\"InsufficientFunds\",\"message\":\"Failed to place buy order on symbol 'BTCUSD' for price $7,000.00 and quantity 0.22 BTC due to insufficient funds\"}",
  "fills": [
    {
      "time": "2020-01-01T10:45:20.1677709Z",
      "price": 10799.2,
      "amount": 0.002
    }
  ]
}

490 Response

Responses

Status Meaning Description Schema
200 OK Created OrderExecutionReport
400 Bad Request Input model validation errors. ValidationError
490 Not Applicable Exchange is unreachable. MessageReject
504 Gateway Time-out Exchange didn't responded in the defined timeout. MessageReject

Get order execution report GET

Code samples

curl --request GET \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b \
  --header 'Accept: application/json'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

headers = { 'Accept': "application/json" }

conn.request("GET", "/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/status/6ab36bc1-344d-432e-ac6d-0bf44ee64c2b")
  .header("Accept", "application/json")
  .asString();

GET /v1/orders/status/{client_order_id}

Get the last order execution report for the specified order. The requested order does not need to be active or opened.

Parameters
Parameter In Type Required Description
client_order_id path string true The unique identifier of the order assigned by the client.

Example responses

200 Response

{
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": [
    "MAKER_OR_CANCEL"
  ],
  "client_order_id_format_exchange": "f81211e2-27c4-b86a-8143-01088ba9222c",
  "exchange_order_id": 3456456754,
  "amount_open": 0.22,
  "amount_filled": 0,
  "avg_px": 0.0783,
  "status": "RECEIVED",
  "status_history": [
    [
      [
        [
          "RECEIVED",
          "2020-05-27T11:16:20.1677709Z"
        ],
        [
          "REJECTED",
          "2020-05-27T11:16:20.1677710Z"
        ]
      ]
    ]
  ],
  "error_message": "{\"result\":\"error\",\"reason\":\"InsufficientFunds\",\"message\":\"Failed to place buy order on symbol 'BTCUSD' for price $7,000.00 and quantity 0.22 BTC due to insufficient funds\"}",
  "fills": [
    {
      "time": "2020-01-01T10:45:20.1677709Z",
      "price": 10799.2,
      "amount": 0.002
    }
  ]
}

Responses

Status Meaning Description Schema
200 OK The last execution report of the requested order. OrderExecutionReport
404 Not Found The requested order was not found. MessageReject

Cancel order request POST

Code samples

curl --request POST \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"exchange_id":"KRAKEN","exchange_order_id":3456456754,"client_order_id":"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b"}'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddParameter("application/json", "{\"exchange_id\":\"KRAKEN\",\"exchange_order_id\":3456456754,\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "strings"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel"

    payload := strings.NewReader("{\"exchange_id\":\"KRAKEN\",\"exchange_order_id\":3456456754,\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\"}")

    req, _ := http.NewRequest("POST", url, payload)

    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = JSON.stringify({
  "exchange_id": "KRAKEN",
  "exchange_order_id": 3456456754,
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b"
});

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"exchange_id\":\"KRAKEN\",\"exchange_order_id\":3456456754,\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\"}",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "Content-Type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

payload = "{\"exchange_id\":\"KRAKEN\",\"exchange_order_id\":3456456754,\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\"}"

headers = {
    'Content-Type': "application/json",
    'Accept': "application/json"
    }

conn.request("POST", "/v1/orders/cancel", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request["Accept"] = 'application/json'
request.body = "{\"exchange_id\":\"KRAKEN\",\"exchange_order_id\":3456456754,\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\"}"

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.post("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel")
  .header("Content-Type", "application/json")
  .header("Accept", "application/json")
  .body("{\"exchange_id\":\"KRAKEN\",\"exchange_order_id\":3456456754,\"client_order_id\":\"6ab36bc1-344d-432e-ac6d-0bf44ee64c2b\"}")
  .asString();

POST /v1/orders/cancel

Request cancel for an existing order. The order can be canceled using the client_order_id or exchange_order_id.

Body parameter

{
  "exchange_id": "KRAKEN",
  "exchange_order_id": 3456456754,
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b"
}
Parameters
Parameter In Type Required Description
body body OrderCancelSingleRequest true OrderCancelSingleRequest object.
» exchange_id body string true Exchange identifier used to identify the routing destination.
» exchange_order_id body string false Unique identifier of the order assigned by the exchange or executing system. One of the properties (exchange_order_id, client_order_id) is required to identify the new order.
» client_order_id body string false The unique identifier of the order assigned by the client. One of the properties (exchange_order_id, client_order_id) is required to identify the new order.

Example responses

200 Response

{
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": [
    "MAKER_OR_CANCEL"
  ],
  "client_order_id_format_exchange": "f81211e2-27c4-b86a-8143-01088ba9222c",
  "exchange_order_id": 3456456754,
  "amount_open": 0.22,
  "amount_filled": 0,
  "avg_px": 0.0783,
  "status": "RECEIVED",
  "status_history": [
    [
      [
        [
          "RECEIVED",
          "2020-05-27T11:16:20.1677709Z"
        ],
        [
          "REJECTED",
          "2020-05-27T11:16:20.1677710Z"
        ]
      ]
    ]
  ],
  "error_message": "{\"result\":\"error\",\"reason\":\"InsufficientFunds\",\"message\":\"Failed to place buy order on symbol 'BTCUSD' for price $7,000.00 and quantity 0.22 BTC due to insufficient funds\"}",
  "fills": [
    {
      "time": "2020-01-01T10:45:20.1677709Z",
      "price": 10799.2,
      "amount": 0.002
    }
  ]
}

490 Response

Responses

Status Meaning Description Schema
200 OK The last execution report for the order for which cancelation was requested. OrderExecutionReport
400 Bad Request Input model validation errors. ValidationError
490 Not Applicable Exchange is unreachable. MessageReject

Cancel all orders request POST

Code samples

curl --request POST \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel/all \
  --header 'Accept: application/json' \
  --header 'Content-Type: application/json' \
  --data '{"exchange_id":"KRAKEN"}'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel/all");
var request = new RestRequest(Method.POST);
request.AddHeader("Content-Type", "application/json");
request.AddHeader("Accept", "application/json");
request.AddParameter("application/json", "{\"exchange_id\":\"KRAKEN\"}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "strings"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel/all"

    payload := strings.NewReader("{\"exchange_id\":\"KRAKEN\"}")

    req, _ := http.NewRequest("POST", url, payload)

    req.Header.Add("Content-Type", "application/json")
    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = JSON.stringify({
  "exchange_id": "KRAKEN"
});

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("POST", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel/all");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel/all",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "POST",
  CURLOPT_POSTFIELDS => "{\"exchange_id\":\"KRAKEN\"}",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json",
    "Content-Type: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

payload = "{\"exchange_id\":\"KRAKEN\"}"

headers = {
    'Content-Type': "application/json",
    'Accept': "application/json"
    }

conn.request("POST", "/v1/orders/cancel/all", payload, headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel/all")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request["Accept"] = 'application/json'
request.body = "{\"exchange_id\":\"KRAKEN\"}"

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.post("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/cancel/all")
  .header("Content-Type", "application/json")
  .header("Accept", "application/json")
  .body("{\"exchange_id\":\"KRAKEN\"}")
  .asString();

POST /v1/orders/cancel/all

This request cancels all open orders on single specified exchange.

Body parameter

{
  "exchange_id": "KRAKEN"
}
Parameters
Parameter In Type Required Description
body body OrderCancelAllRequest true OrderCancelAllRequest object.
» exchange_id body string true Identifier of the exchange from which active orders should be canceled.

Example responses

200 Response

{
  "type": "MESSAGE_REJECT",
  "reject_reason": "ORDER_ID_NOT_FOUND",
  "exchange_id": "BINANCE",
  "message": "Order with ID: BINANCE-7d8a-4888 not found",
  "rejected_message": "{\"client_order_id\":\"BINANCE-7d8a-4888\",\"exchange_id\":\"BINANCE\",\"type\":\"ORDER_CANCEL_SINGLE_REQUEST\"}"
}

490 Response

Responses

Status Meaning Description Schema
200 OK Result MessageReject
400 Bad Request Input model validation errors. ValidationError
490 Not Applicable Exchange is unreachable. MessageReject

History of order changes GET

Code samples

curl --request GET \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00 \
  --header 'Accept: application/json'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

headers = { 'Accept': "application/json" }

conn.request("GET", "/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/orders/history/2022-05-01T00%3A00%3A00/2022-05-01T12%3A00%3A00")
  .header("Accept", "application/json")
  .asString();

GET /v1/orders/history/{time_start}/{time_end}

Based on the date range, all changes registered in the orderbook.

Parameters
Parameter In Type Required Description
time_start path string true Start date
time_end path string true End date

Example responses

200 Response

[
  {
    "apikey": "9a55567a-b5ff-4b78-b6aa-xxxx",
    "exchangeId": "BINANCE",
    "clientOrderId": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "symbolIdExchange": "BTCUSDT",
    "symbolIdCoinapi": "BINANCE_SPOT_BTC_USDT",
    "amountOrder": 0.00034,
    "price": 31939.47,
    "side": 2,
    "orderType": "LIMIT",
    "timeInForce": "GOOD_TILL_CANCEL",
    "expireTime": "2022-05-01T00:00:00",
    "execInst": [
      [
        "MAKER_OR_CANCEL"
      ]
    ],
    "clientOrderIdFormatExchange": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "exchangeOrderId": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "amountOpen": 0.00034,
    "amountFilled": 0,
    "avgPx": 0,
    "status": "REJECTED",
    "statusHistoryStatus": [
      [
        "RECEIVED",
        "ROUTING",
        "REJECTED"
      ]
    ],
    "statusHistoryTime": [
      [
        "2022-05-27T13:06:34.5122626Z",
        "2022-05-27T13:06:37.3410216Z",
        "2022-05-27T13:06:40.1342877Z"
      ]
    ],
    "errorMessageResult": "string",
    "errorMessageReason": "string",
    "errorMessageMessage": "-2015 Invalid API-key, IP, or permissions for action. https://api.binance.com/api/v3/order?newOrderRespType",
    "fillsTime": [
      [
        "2022-05-27T13:06:34.5122626Z",
        "2022-05-27T13:06:37.3410216Z",
        "2022-05-27T13:06:40.1342877Z"
      ]
    ],
    "fillsPrice": [
      [
        31939.47,
        31939.67
      ]
    ],
    "fillsAmount": [
      [
        0.0032,
        0.0009
      ]
    ],
    "createdTime": "2022-06-27T07:02:33.1977903Z"
  }
]

Responses

Status Meaning Description Schema
200 OK The last execution report of the requested order. OrderHistoryArray
400 Bad Request Orders log is not configured. MessageError

Balances

Get balances GET

Code samples

curl --request GET \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/balances \
  --header 'Accept: application/json'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/balances");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/balances"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/balances");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/balances",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

headers = { 'Accept': "application/json" }

conn.request("GET", "/v1/balances", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/balances")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/balances")
  .header("Accept", "application/json")
  .asString();

GET /v1/balances

Get current currency balance from all or single exchange.

Parameters
Parameter In Type Required Description
exchange_id query string false Filter the balances to the specific exchange.

Example responses

200 Response

[
  {
    "exchange_id": "KRAKEN",
    "data": [
      {
        "asset_id_exchange": "XBT",
        "asset_id_coinapi": "BTC",
        "balance": 0.00134444,
        "available": 0.00134444,
        "locked": 0,
        "last_updated_by": "EXCHANGE",
        "rate_usd": 1355.12,
        "traded": 0.007
      }
    ]
  }
]

490 Response

Responses

Status Meaning Description Schema
200 OK Collection of balances. Balances
490 Not Applicable Exchange is unreachable. MessageReject

Positions

Get open positions GET

Code samples

curl --request GET \
  --url https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/positions \
  --header 'Accept: application/json'
var client = new RestClient("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/positions");
var request = new RestRequest(Method.GET);
request.AddHeader("Accept", "application/json");
IRestResponse response = client.Execute(request);
package main

import (
    "fmt"
    "net/http"
    "io/ioutil"
)

func main() {

    url := "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/positions"

    req, _ := http.NewRequest("GET", url, nil)

    req.Header.Add("Accept", "application/json")

    res, _ := http.DefaultClient.Do(req)

    defer res.Body.Close()
    body, _ := ioutil.ReadAll(res.Body)

    fmt.Println(res)
    fmt.Println(string(body))

}
const data = null;

const xhr = new XMLHttpRequest();
xhr.withCredentials = true;

xhr.addEventListener("readystatechange", function () {
  if (this.readyState === this.DONE) {
    console.log(this.responseText);
  }
});

xhr.open("GET", "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/positions");
xhr.setRequestHeader("Accept", "application/json");

xhr.send(data);
<?php

$curl = curl_init();

curl_setopt_array($curl, [
  CURLOPT_URL => "https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/positions",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  CURLOPT_HTTPHEADER => [
    "Accept: application/json"
  ],
]);

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
  echo "cURL Error #:" . $err;
} else {
  echo $response;
}
import http.client

conn = http.client.HTTPSConnection("ems-gateway-aws-eu-central-1-dev.coinapi.io")

headers = { 'Accept': "application/json" }

conn.request("GET", "/v1/positions", headers=headers)

res = conn.getresponse()
data = res.read()

print(data.decode("utf-8"))
require 'uri'
require 'net/http'
require 'openssl'

url = URI("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/positions")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE

request = Net::HTTP::Get.new(url)
request["Accept"] = 'application/json'

response = http.request(request)
puts response.read_body
HttpResponse<String> response = Unirest.get("https://ems-gateway-aws-eu-central-1-dev.coinapi.io/v1/positions")
  .header("Accept", "application/json")
  .asString();

GET /v1/positions

Get current open positions across all or single exchange.

Parameters
Parameter In Type Required Description
exchange_id query string false Filter the balances to the specific exchange.

Example responses

200 Response

[
  {
    "exchange_id": "KRAKEN",
    "data": [
      {
        "symbol_id_exchange": "XBTUSD",
        "symbol_id_coinapi": "BITMEX_PERP_BTC_USD",
        "avg_entry_price": 0.00134444,
        "quantity": 7,
        "side": "BUY",
        "unrealized_pnl": 0,
        "leverage": 0,
        "cross_margin": true,
        "liquidation_price": 0.072323,
        "raw_data": "Other information provided by the exchange on this position."
      }
    ]
  }
]

490 Response

Responses

Status Meaning Description Schema
200 OK Collection of positons. Positions
490 Not Applicable Exchange is unreachable. MessageReject

Schemas

OrderNewSingleRequest

{
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": [
    "MAKER_OR_CANCEL"
  ]
}

Properties

The new order message.

Name Type Required Description
exchange_id string true Exchange identifier used to identify the routing destination.
client_order_id string true The unique identifier of the order assigned by the client.
symbol_id_exchange string false Exchange symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
symbol_id_coinapi string false CoinAPI symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
amount_order number true Order quantity.
price number true Order price.
side OrdSide true Side of order.
order_type OrdType true Order types are documented in the separate section: EMS / Starter Guide / Order parameters / Order type
time_in_force TimeInForce true Order time in force options are documented in the separate section: EMS / Starter Guide / Order parameters / Time in force
expire_time date false Expiration time. Conditionaly required for orders with time_in_force = GOOD_TILL_TIME_EXCHANGE or GOOD_TILL_TIME_OEML.
exec_inst ExecInst false Order execution instructions are documented in the separate section: EMS / Starter Guide / Order parameters / Execution instructions

OrderCancelSingleRequest

{
  "exchange_id": "KRAKEN",
  "exchange_order_id": 3456456754,
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b"
}

Properties

Cancel single order request object.

Name Type Required Description
exchange_id string true Exchange identifier used to identify the routing destination.
exchange_order_id string false Unique identifier of the order assigned by the exchange or executing system. One of the properties (exchange_order_id, client_order_id) is required to identify the new order.
client_order_id string false The unique identifier of the order assigned by the client. One of the properties (exchange_order_id, client_order_id) is required to identify the new order.

OrderCancelAllRequest

{
  "exchange_id": "KRAKEN"
}

Properties

Cancel all orders request object.

Name Type Required Description
exchange_id string true Identifier of the exchange from which active orders should be canceled.

OrderExecutionReports

[
  {
    "exchange_id": "KRAKEN",
    "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "symbol_id_exchange": "XBT/USDT",
    "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
    "amount_order": 0.045,
    "price": 0.0783,
    "side": "BUY",
    "order_type": "LIMIT",
    "time_in_force": "GOOD_TILL_CANCEL",
    "expire_time": "2020-01-01T10:45:20.1677709Z",
    "exec_inst": [
      "MAKER_OR_CANCEL"
    ],
    "client_order_id_format_exchange": "f81211e2-27c4-b86a-8143-01088ba9222c",
    "exchange_order_id": 3456456754,
    "amount_open": 0.22,
    "amount_filled": 0,
    "avg_px": 0.0783,
    "status": "RECEIVED",
    "status_history": [
      [
        [
          [
            "RECEIVED",
            "2020-05-27T11:16:20.1677709Z"
          ],
          [
            "REJECTED",
            "2020-05-27T11:16:20.1677710Z"
          ]
        ]
      ]
    ],
    "error_message": "{\"result\":\"error\",\"reason\":\"InsufficientFunds\",\"message\":\"Failed to place buy order on symbol 'BTCUSD' for price $7,000.00 and quantity 0.22 BTC due to insufficient funds\"}",
    "fills": [
      {
        "time": "2020-01-01T10:45:20.1677709Z",
        "price": 10799.2,
        "amount": 0.002
      }
    ]
  }
]

Properties

Collection of order execution reports for currently opened orders.

Name Type Required Description
anonymous [OrderExecutionReport] false Collection of order execution reports for currently opened orders.

OrderExecutionReport

{
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": [
    "MAKER_OR_CANCEL"
  ],
  "client_order_id_format_exchange": "f81211e2-27c4-b86a-8143-01088ba9222c",
  "exchange_order_id": 3456456754,
  "amount_open": 0.22,
  "amount_filled": 0,
  "avg_px": 0.0783,
  "status": "RECEIVED",
  "status_history": [
    [
      [
        [
          "RECEIVED",
          "2020-05-27T11:16:20.1677709Z"
        ],
        [
          "REJECTED",
          "2020-05-27T11:16:20.1677710Z"
        ]
      ]
    ]
  ],
  "error_message": "{\"result\":\"error\",\"reason\":\"InsufficientFunds\",\"message\":\"Failed to place buy order on symbol 'BTCUSD' for price $7,000.00 and quantity 0.22 BTC due to insufficient funds\"}",
  "fills": [
    {
      "time": "2020-01-01T10:45:20.1677709Z",
      "price": 10799.2,
      "amount": 0.002
    }
  ]
}

Properties

The order execution report object.

allOf

Name Type Required Description
anonymous OrderNewSingleRequest false The new order message.

and

Name Type Required Description
anonymous object false The order execution report message.
» client_order_id_format_exchange string true The unique identifier of the order assigned by the client converted to the exchange order tag format for the purpose of tracking it.
» exchange_order_id string false Unique identifier of the order assigned by the exchange or executing system.
» amount_open number true Quantity open for further execution. amount_open = amount_order - amount_filled
» amount_filled number true Total quantity filled.
» avg_px number false Calculated average price of all fills on this order.
» status OrdStatus true Order statuses and the lifecycle are documented in the separate section: EMS / Starter Guide / Order Lifecycle
» status_history [array] false Timestamped history of order status changes.
» error_message string false Error message.
» fills [Fills] false Relay fill information on working orders.

None

Balances

[
  {
    "exchange_id": "KRAKEN",
    "data": [
      {
        "asset_id_exchange": "XBT",
        "asset_id_coinapi": "BTC",
        "balance": 0.00134444,
        "available": 0.00134444,
        "locked": 0,
        "last_updated_by": "EXCHANGE",
        "rate_usd": 1355.12,
        "traded": 0.007
      }
    ]
  }
]

Properties

Collection of the balances.

Name Type Required Description
anonymous [Balance] false Collection of the balances.

Balance

{
  "exchange_id": "KRAKEN",
  "data": [
    {
      "asset_id_exchange": "XBT",
      "asset_id_coinapi": "BTC",
      "balance": 0.00134444,
      "available": 0.00134444,
      "locked": 0,
      "last_updated_by": "EXCHANGE",
      "rate_usd": 1355.12,
      "traded": 0.007
    }
  ]
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier used to identify the routing destination.
data [object] false No description
» asset_id_exchange string false Exchange currency code.
» asset_id_coinapi string false CoinAPI currency code.
» balance number(double) false Value of the current total currency balance on the exchange.
» available number(double) false Value of the current available currency balance on the exchange that can be used as collateral.
» locked number(double) false Value of the current locked currency balance by the exchange.
» last_updated_by string false Source of the last modification.
» rate_usd number(double) false Current exchange rate to the USD for the single unit of the currency.
» traded number(double) false Value of the current total traded.
Enumerated Values
Property Value
last_updated_by INITIALIZATION
last_updated_by BALANCE_MANAGER
last_updated_by EXCHANGE

Positions

[
  {
    "exchange_id": "KRAKEN",
    "data": [
      {
        "symbol_id_exchange": "XBTUSD",
        "symbol_id_coinapi": "BITMEX_PERP_BTC_USD",
        "avg_entry_price": 0.00134444,
        "quantity": 7,
        "side": "BUY",
        "unrealized_pnl": 0,
        "leverage": 0,
        "cross_margin": true,
        "liquidation_price": 0.072323,
        "raw_data": "Other information provided by the exchange on this position."
      }
    ]
  }
]

Properties

Collection of the positions.

Name Type Required Description
anonymous [Position] false Collection of the positions.

Position

{
  "exchange_id": "KRAKEN",
  "data": [
    {
      "symbol_id_exchange": "XBTUSD",
      "symbol_id_coinapi": "BITMEX_PERP_BTC_USD",
      "avg_entry_price": 0.00134444,
      "quantity": 7,
      "side": "BUY",
      "unrealized_pnl": 0,
      "leverage": 0,
      "cross_margin": true,
      "liquidation_price": 0.072323,
      "raw_data": "Other information provided by the exchange on this position."
    }
  ]
}

Properties

Name Type Required Description
exchange_id string false Exchange identifier used to identify the routing destination.
data [object] false No description
» symbol_id_exchange string false Exchange symbol.
» symbol_id_coinapi string false CoinAPI symbol.
» avg_entry_price number false Calculated average price of all fills on this position.
» quantity number false The current position quantity.
» side OrdSide false Side of order.
» unrealized_pnl number false Unrealised profit or loss (PNL) of this position.
» leverage number false Leverage for this position reported by the exchange.
» cross_margin boolean false Is cross margin mode enable for this position?
» liquidation_price number false Liquidation price. If mark price will reach this value, the position will be liquidated.
» raw_data object false No description

OrdStatus

"RECEIVED"

Properties

Order statuses and the lifecycle are documented in the separate section: EMS / Starter Guide / Order Lifecycle

OrdSide

"BUY"

Properties

Side of order.

OrdType

"LIMIT"

Properties

Order types are documented in the separate section: EMS / Starter Guide / Order parameters / Order type

TimeInForce

"GOOD_TILL_CANCEL"

Properties

Order time in force options are documented in the separate section: EMS / Starter Guide / Order parameters / Time in force

ExecInst

[
  "MAKER_OR_CANCEL"
]

Properties

Order execution instructions are documented in the separate section: EMS / Starter Guide / Order parameters / Execution instructions

None

ValidationError

{
  "type": "https://tools.ietf.org/html/rfc7231#section-6.5.1",
  "title": "One or more validation errors occurred.",
  "status": 400,
  "traceId": "d200e8b5-4271a5461ce5342f",
  "errors": "string"
}

Properties

JSON validation error.

Name Type Required Description
type string false No description
title string false No description
status number false No description
traceId string false No description
errors string false No description

MessageReject

{
  "type": "MESSAGE_REJECT",
  "reject_reason": "ORDER_ID_NOT_FOUND",
  "exchange_id": "BINANCE",
  "message": "Order with ID: BINANCE-7d8a-4888 not found",
  "rejected_message": "{\"client_order_id\":\"BINANCE-7d8a-4888\",\"exchange_id\":\"BINANCE\",\"type\":\"ORDER_CANCEL_SINGLE_REQUEST\"}"
}

Properties

MessageReject object.

Name Type Required Description
type string false Message type, constant.
reject_reason RejectReason false Cause of rejection.
exchange_id string false If the message related to exchange, then the identifier of the exchange will be provided.
message string false Message text.
rejected_message string false Value of rejected request, if available.

RejectReason

"ORDER_ID_NOT_FOUND"

Properties

Cause of rejection.

Fills

{
  "time": "2020-01-01T10:45:20.1677709Z",
  "price": 10799.2,
  "amount": 0.002
}

Properties

Relay fill information on working orders.

Name Type Required Description
time date false Execution time.
price number false Execution price.
amount number false Executed quantity.

OrderHistoryArray

[
  {
    "apikey": "9a55567a-b5ff-4b78-b6aa-xxxx",
    "exchangeId": "BINANCE",
    "clientOrderId": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "symbolIdExchange": "BTCUSDT",
    "symbolIdCoinapi": "BINANCE_SPOT_BTC_USDT",
    "amountOrder": 0.00034,
    "price": 31939.47,
    "side": 2,
    "orderType": "LIMIT",
    "timeInForce": "GOOD_TILL_CANCEL",
    "expireTime": "2022-05-01T00:00:00",
    "execInst": [
      [
        "MAKER_OR_CANCEL"
      ]
    ],
    "clientOrderIdFormatExchange": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "exchangeOrderId": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
    "amountOpen": 0.00034,
    "amountFilled": 0,
    "avgPx": 0,
    "status": "REJECTED",
    "statusHistoryStatus": [
      [
        "RECEIVED",
        "ROUTING",
        "REJECTED"
      ]
    ],
    "statusHistoryTime": [
      [
        "2022-05-27T13:06:34.5122626Z",
        "2022-05-27T13:06:37.3410216Z",
        "2022-05-27T13:06:40.1342877Z"
      ]
    ],
    "errorMessageResult": "string",
    "errorMessageReason": "string",
    "errorMessageMessage": "-2015 Invalid API-key, IP, or permissions for action. https://api.binance.com/api/v3/order?newOrderRespType",
    "fillsTime": [
      [
        "2022-05-27T13:06:34.5122626Z",
        "2022-05-27T13:06:37.3410216Z",
        "2022-05-27T13:06:40.1342877Z"
      ]
    ],
    "fillsPrice": [
      [
        31939.47,
        31939.67
      ]
    ],
    "fillsAmount": [
      [
        0.0032,
        0.0009
      ]
    ],
    "createdTime": "2022-06-27T07:02:33.1977903Z"
  }
]

Properties

Collection of the order history.

Name Type Required Description
anonymous [OrderHistory] false Collection of the order history.

OrderHistory

{
  "apikey": "9a55567a-b5ff-4b78-b6aa-xxxx",
  "exchangeId": "BINANCE",
  "clientOrderId": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbolIdExchange": "BTCUSDT",
  "symbolIdCoinapi": "BINANCE_SPOT_BTC_USDT",
  "amountOrder": 0.00034,
  "price": 31939.47,
  "side": 2,
  "orderType": "LIMIT",
  "timeInForce": "GOOD_TILL_CANCEL",
  "expireTime": "2022-05-01T00:00:00",
  "execInst": [
    [
      "MAKER_OR_CANCEL"
    ]
  ],
  "clientOrderIdFormatExchange": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "exchangeOrderId": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "amountOpen": 0.00034,
  "amountFilled": 0,
  "avgPx": 0,
  "status": "REJECTED",
  "statusHistoryStatus": [
    [
      "RECEIVED",
      "ROUTING",
      "REJECTED"
    ]
  ],
  "statusHistoryTime": [
    [
      "2022-05-27T13:06:34.5122626Z",
      "2022-05-27T13:06:37.3410216Z",
      "2022-05-27T13:06:40.1342877Z"
    ]
  ],
  "errorMessageResult": "string",
  "errorMessageReason": "string",
  "errorMessageMessage": "-2015 Invalid API-key, IP, or permissions for action. https://api.binance.com/api/v3/order?newOrderRespType",
  "fillsTime": [
    [
      "2022-05-27T13:06:34.5122626Z",
      "2022-05-27T13:06:37.3410216Z",
      "2022-05-27T13:06:40.1342877Z"
    ]
  ],
  "fillsPrice": [
    [
      31939.47,
      31939.67
    ]
  ],
  "fillsAmount": [
    [
      0.0032,
      0.0009
    ]
  ],
  "createdTime": "2022-06-27T07:02:33.1977903Z"
}

Properties

Order history

Name Type Required Description
apikey string false Apikey
exchangeId string false Exchange id
clientOrderId string false Client order id
symbolIdExchange string false Symbol id exchange
symbolIdCoinapi string false Symbol id in coinapi
amountOrder number false Amount
price number false Price
side number false 1-buy, 2-sell
orderType string false Order type
timeInForce string false Time in force
expireTime date false Expire time
execInst [string] false Exec inst
clientOrderIdFormatExchange string false Client order id format
exchangeOrderId string false Exchange order id
amountOpen number false Amount open
amountFilled number false Amount filled
avgPx number false Average price
status string false Status
statusHistoryStatus [string] false History status
statusHistoryTime [date] false History status time
errorMessageResult string false Error message
errorMessageReason string false Error message reason
errorMessageMessage string false Error message
fillsTime [date] false Fills time
fillsPrice [number] false Fills price
fillsAmount [number] false Fills amount
createdTime date false Created time

MessageError

{
  "message": "string"
}

Properties

MessageError object.

Name Type Required Description
message string false Message text.

EMS - WebSocket API

This section will provide necessary information about the CoinAPI EMS WebSocket API protocol.

WebSocket API provides real-time communication capacity for order management, execution reports, balances and the positions.

Implemented Standards:

Endpoints

Deployment method Environment Url
Managed Cloud Production Use Managed Cloud REST API /v1/locations to get specific endpoints to each server site where your deployments span
Managed Cloud Sandbox https://ems-gateway-aws-eu-central-1-dev.coinapi.io/
Self Hosted Production IP Address of the ems-gateway container/excecutable in the closest server site to the caller location
Self Hosted Sandbox IP Address of the ems-gateway container/excecutable in the closest server site to the caller location

Authentication

If the software is deployed as Self-Hosted then API do not require authentication as inside your infrastructure, your company is responsible for the security and access controls.

If the software is deployed in our Managed Cloud, there are 2 methods for authenticating with us, you only need to use one:

  1. Custom authorization header named X-CoinAPI-Key with the API Key
  2. Query string parameter named apikey with the API Key
  3. TLS Client Certificate from the Managed Cloud REST API (/v1/certificate/pem endpoint) while establishing a TLS session with us.

Custom authorization header

You can authorize by providing additional custom header named X-CoinAPI-Key and API key as its value.

Assuming that your API key is 73034021-THIS-IS-SAMPLE-KEY, then the authorization header you should send to us will look like:

X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY

Query string authorization parameter

You can authorize by providing an additional parameter named apikey with a value equal to your API key in the query string of your HTTP request.

Assuming that your API key is 73034021-THIS-IS-SAMPLE-KEY and that you want to request all exchange rates from BTC asset, then your query string should look like this:

GET /v1/exchangerate/BTC?apikey=73034021-THIS-IS-SAMPLE-KEY

Messages

This section will provide necessary documentation for the WebSocket protocol messages.

The message type is identified by the type property of the JSON object. This document is organized into sections, each per specific message type.

Message type Trigger Description
SERVER_INFO On connection open
Every 1 second
On update
Heartbeat and server information.
ORDER_NEW_SINGLE_REQUEST On new order Submit new order.
ORDER_CANCEL_SINGLE_REQUEST On order cancel Cancel single order.
ORDER_CANCEL_ALL_REQUEST On order cancel Cancel all orders.
ORDER_EXEC_REPORT_SNAPSHOT On connection open Snapshot of all order execution reports.
ORDER_EXEC_REPORT_UPDATE On update Update of the order execution report.
BALANCE_SNAPSHOT On connection open Snapshot of all balances.
BALANCE_UPDATE On update Update of the balance.
POSITION_SNAPSHOT On connection open Snapshot of all positions.
POSITION_UPDATE On update Update of the position.
SYMBOLS_SNAPSHOT On connection open Snapshot of markets symbols.
MESSAGE_REJECT On order placing/cancelling rejection. Text message.

SERVER_INFO IN

Example of the SERVER_INFO message.

{
    "type": "SERVER_INFO",
    "time": "2020-02-07T12:37:46.6967101Z",
    "instance_guid": "16bab28c-8c7c-4af7-815b-923ea8ecbf4a",
    "exchange_id": "BINANCEJE",
    "server_version": "1.3521",
    "server_name": "HDC2-ENC-06-BAY-05",
    "dns_name": "HDC2-ENC-06-BAY-05.us-east-1.corpintra.net",
    "is_running": true,
    "time_server_start": "2020-02-07T10:25:22.3022141Z"
}

This message is used internally to measure the real-time latency of the link and acts as a heartbeat.

Delivery triggers:

Properties

Name Type Description
type string Message type, constant SERVER_INFO.
time datetime Time message sent time to measure the link latency.
instance_guid string The server process randomly generated GUID. It will change on each software restart.
exchange_id string Exchange identifier.
server_version string Server software version.
server_name string Server name.
dns_name string DNS name.
is_running boolean Is the server on the other side running? Update with the false value will be sent before the shutdown.
time_server_start datetime Time of server software start.

ORDER_NEW_SINGLE_REQUEST OUT

Example of the ORDER_NEW_SINGLE_REQUEST message creating order on the KRAKEN exchange by the symbol_id_exchange.

{
  "type": "ORDER_NEW_SINGLE_REQUEST",
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_exchange": "XBT/USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": ["MAKER_OR_CANCEL"]
}

Another example of the ORDER_NEW_SINGLE_REQUEST message creating order on the same market by the symbol_id_coinapi.

{
  "type": "ORDER_NEW_SINGLE_REQUEST",
  "exchange_id": "KRAKEN",
  "client_order_id": "6ab36bc1-344d-432e-ac6d-0bf44ee64c2b",
  "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
  "amount_order": 0.045,
  "price": 0.0783,
  "side": "BUY",
  "order_type": "LIMIT",
  "time_in_force": "GOOD_TILL_CANCEL",
  "expire_time": "2020-01-01T10:45:20.1677709Z",
  "exec_inst": ["MAKER_OR_CANCEL"]
}

This message is used to send a new order to the exchange.

Properties

Parameter Type Required Description
type string true Message type, constant ORDER_NEW_SINGLE_REQUEST.
exchange_id string true Exchange identifier.
client_order_id string true The unique identifier of the order assigned by the client.
symbol_id_exchange string false Exchange symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
symbol_id_coinapi string false CoinAPI symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
amount_order number true Order quantity.
price number true Order price.
side string true Side of order. Allowed values: BUY or SELL.
order_type string true Order types are documented in the separate section: EMS / Starter Guide / Order parameters / Order type
time_in_force string true Order time in force options are documented in the separate section: EMS / Starter Guide / Order parameters / Time in force
expire_time date false Expiration time. Conditionaly required for orders with time_in_force = GOOD_TILL_TIME_EXCHANGE or GOOD_TILL_TIME_OEML.
exec_inst [string] false Order execution instructions are documented in the separate section: EMS / Starter Guide / Order parameters / Execution instructions

ORDER_CANCEL_SINGLE_REQUEST OUT

Example of the ORDER_CANCEL_SINGLE_REQUEST message to cancel a single order identified by the exchange_order_id on the BITSTAMP exchange.

{
  "type": "ORDER_CANCEL_SINGLE_REQUEST",
  "exchange_id": "BITSTAMP",
  "exchange_order_id": "1234567"
}

Another example of the ORDER_CANCEL_SINGLE_REQUEST message to cancel a single order identified by the client_order_id on the BITSTAMP exchange.

{
  "type": "ORDER_CANCEL_SINGLE_REQUEST",
  "exchange_id": "BITSTAMP",
  "client_order_id": "d8574207d9e3b16a4a5511753eeef1751"
}

Request cancel for an existing order. The order can be canceled using the client_order_id or exchange_order_id.

Properties

Parameter Type Required Description
type string true Message type, constant ORDER_CANCEL_SINGLE_REQUEST.
exchange_id string true Exchange identifier.
exchange_order_id string false Unique identifier of the order assigned by the exchange or executing system. One of the properties (exchange_order_id, client_order_id) is required to identify the order.
client_order_id string false The unique identifier of the order assigned by the client. One of the properties (exchange_order_id, client_order_id) is required to identify the order.

ORDER_CANCEL_ALL_REQUEST OUT

Example of the ORDER_CANCEL_ALL_REQUEST message to cancel all open orders on the KRAKEN exchange.

{
    "type": "ORDER_CANCEL_ALL_REQUEST",
    "exchange_id": "KRAKEN"
}

This request cancels all open orders on a single specified exchange.

Properties

Parameter Type Required Description
type string true Message type, constant ORDER_CANCEL_ALL_REQUEST.
exchange_id body string true

ORDER_EXEC_REPORT_SNAPSHOT IN

Example of the ORDER_EXEC_REPORT_SNAPSHOT message delivering all open orders from the KRAKEN exchange.

{
    "type": "ORDER_EXEC_REPORT_SNAPSHOT",
    "exchange_id": "KRAKEN",
    "data": 
    [
        {
            "exchange_id": "KRAKEN",
            "client_order_id": "KPP-222389382-AQ",
            "exchange_order_id": "90832ASASAS89789-1112",
            "symbol_id_exchange": "XBT/USDT",
            "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
            "amount_order": 0.045,
            "amount_filled": 0,
            "amount_open": 0.22,
            "status": "NEW",
            "price": 0.0783,
            "avg_px": 0.0783,
            "side": "BUY",
            "order_type": "LIMIT",
            "time_in_force": "GOOD_TILL_CANCEL",
            "expire_time": "2020-01-01T10:45:20.1677709Z",
            "exec_inst": "MAKER_OR_CANCEL"
            "status_history": [
                [
                    "RECEIVED",
                    "2020-05-27T11:16:20.1677709Z"
                ],
                [
                    "ROUTING",
                    "2020-05-27T11:16:20.1677710Z"
                ],
                [
                    "ROUTED",
                    "2020-05-27T11:16:20.1677800Z"
                ],
                [
                    "NEW",
                    "2020-05-27T11:16:20.1677951Z"
                ]
            ],
            "fills": [
                {
                    "time": "2020-01-01T10:45:20.1677709Z",
                    "price": 10799.2,
                    "amount": 0.002
                }
            ]
        }
    ]
}

This message provides all open orders from the single exchange and will be sent separately for all interconnected exchanges.

When this message is received, then the client must discard all open orders from this exchange and apply the snapshot, which later will be modified by the ORDER_EXEC_REPORT_UPDATE messages.

Delivery triggers:

Properties

Parameter In Type Required Description
type string true Message type, constant ORDER_EXEC_REPORT_SNAPSHOT.
data array object true No description
» exchange_id body string true Exchange identifier used to identify the routing destination.
» client_order_id body string true The unique identifier of the order assigned by the client.
» client_order_id_format_exchange body string true The unique identifier of the order assigned by the client converted to the exchange order tag format for the purpose of tracking it.
» exchange_order_id body string true Unique identifier of the order assigned by the exchange or executing system.
» symbol_id_exchange body string false Exchange symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
» symbol_id_coinapi body string false CoinAPI symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
» amount_order body number true Order quantity.
» amount_filled body number true Total quantity filled.
» amount_open body number true Quantity open for further execution. amount_open = amount_order - amount_filled
» status body string true Order statuses and the lifecycle are documented in the separate section: EMS / Starter Guide / Order Lifecycle
» status_history body array true Timestamped history of order status changes.
» price body number true Order price.
» avg_px body number true Calculated average price of all fills on this order.
» side body string true Side of order.
» order_type body string true Order types are documented in the separate section: EMS / Starter Guide / Order parameters / Order type
» time_in_force body string true Order time in force options are documented in the separate section: EMS / Starter Guide / Order parameters / Time in force
» expire_time body date false Expiration time. Conditionaly required for orders with time_in_force = GOOD_TILL_TIME_EXCHANGE or GOOD_TILL_TIME_OEML.
» exec_inst body [string] false Order execution instructions are documented in the separate section: EMS / Starter Guide / Order parameters / Execution instructions
» error_message body number true Error message
» fills body array true Relay fill information on working orders

Enumerated Values

Parameter Value
» side BUY
» side SELL
» order_type LIMIT
» time_in_force GOOD_TILL_CANCEL
» time_in_force GOOD_TILL_TIME_EXCHANGE
» time_in_force GOOD_TILL_TIME_OMS
» time_in_force FILL_OR_KILL
» time_in_force IMMEDIATE_OR_CANCEL
» exec_inst MAKER_OR_CANCEL
» exec_inst AUCTION_ONLY
» exec_inst INDICATION_OF_INTEREST

ORDER_EXEC_REPORT_UPDATE IN

Example of the ORDER_EXEC_REPORT_UPDATE message notifying that an execution report for the order is changed. In this case, one order changed status, and it's filled.

{
    "exchange_id": "KRAKEN",
    "client_order_id": "KPP-222389382-AQ",
    "client_order_id_format_exchange": "f81211e2-27c4-b86a-8143-01088ba9222c",
    "exchange_order_id": "90832ASASAS89789-1112",
    "symbol_id_exchange": "XBT/USDT",
    "symbol_id_coinapi": "KRAKEN_SPOT_BTC_USDT",
    "amount_order": 0.045,
    "amount_open": 0,
    "amount_filled": 0.045,
    "status": "FILLED",
    "price": 0.0783,
    "avg_px": 0.0783,
    "side": "BUY",
    "order_type": "LIMIT",
    "time_in_force": "GOOD_TILL_CANCEL",
    "expire_time": "2020-01-01T10:45:20.1677709Z",
    "exec_inst": "MAKER_OR_CANCEL"
    "status_history": [
        [
            "RECEIVED",
            "2020-05-27T11:16:20.1677709Z"
        ],
        [
            "ROUTING",
            "2020-05-27T11:16:20.1677710Z"
        ],
        [
            "ROUTED",
            "2020-05-27T11:16:20.1677800Z"
        ],
        [
            "NEW",
            "2020-05-27T11:16:20.1677951Z"
        ],
        [
            "FILLED",
            "2020-05-27T11:16:30.6456457Z"
        ]
    ],
    "fills": [
        {
            "time": "2020-01-01T10:45:20.1677709Z",
            "price": 10799.2,
            "amount": 0.002
        }
    ]   
}

This message is sent to notify the client that the order execution report changed.

When this message is received, then the client must update the execution report in the memory to maintain the current state of execution reports for all open orders.

The initial state of the collection is delivered via the snapshot message ORDER_EXEC_REPORT_SNAPSHOT.

Delivery triggers:

Properties

Parameter In Type Required Description
type string true Message type, constant ORDER_EXEC_REPORT_UPDATE.
exchange_id body string true Exchange identifier used to identify the routing destination.
client_order_id body string true The unique identifier of the order assigned by the client.
client_order_id_format_exchange body string true The unique identifier of the order assigned by the client converted to the exchange order tag format for the purpose of tracking it.
exchange_order_id body string true Unique identifier of the order assigned by the exchange or executing system.
symbol_id_exchange body string false Exchange symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
symbol_id_coinapi body string false CoinAPI symbol. One of the properties (symbol_id_exchange, symbol_id_coinapi) is required to identify the market for the new order.
amount_order body number true Order quantity.
amount_filled body number true Total quantity filled.
amount_open body number true Quantity open for further execution. amount_open = amount_order - amount_filled
status body string true Order statuses and the lifecycle are documented in the separate section: EMS / Starter Guide / Order Lifecycle
status_history body array true Timestamped history of order status changes.
price body number true Order price.
avg_px body number false Calculated average price of all fills on this order.
side body string true Side of order.
order_type body string true Order types are documented in the separate section: EMS / Starter Guide / Order parameters / Order type
time_in_force body string true Order time in force options are documented in the separate section: EMS / Starter Guide / Order parameters / Time in force
expire_time body date false Expiration time. Conditionaly required for orders with time_in_force = GOOD_TILL_TIME_EXCHANGE or GOOD_TILL_TIME_OEML.
exec_inst body [string] false Order execution instructions are documented in the separate section: EMS / Starter Guide / Order parameters / Execution instructions
error_message body number true Error message
fills body array true Relay fill information on working orders

Enumerated Values

Parameter Value
» side BUY
» side SELL
» order_type LIMIT
» time_in_force GOOD_TILL_CANCEL
» time_in_force GOOD_TILL_TIME_EXCHANGE
» time_in_force GOOD_TILL_TIME_OMS
» time_in_force FILL_OR_KILL
» time_in_force IMMEDIATE_OR_CANCEL
» exec_inst MAKER_OR_CANCEL
» exec_inst AUCTION_ONLY
» exec_inst INDICATION_OF_INTEREST

BALANCE_SNAPSHOT IN

Example of the BALANCE_SNAPSHOT message from the KRAKEN exchange.

{
    "type": "BALANCE_SNAPSHOT",
    "exchange_id": "KRAKEN",
    "data": [
        {
            "asset_id_exchange": "XBT",
            "asset_id_coinapi": "BTC",
            "balance": 0.00134444,
            "available": 0.00134444,
            "locked": 0,
            "last_updated_by": "EXCHANGE",
            "rate_usd": 9544.21
        },
        {
            "asset_id_exchange": "BCH",
            "asset_id_coinapi": "BCHABC",
            "balance": 1234,
            "available": 1000,
            "locked": 234,
            "last_updated_by": "BALANCE_MANAGER",
            "rate_usd": 228.12
        }
    ]
}

This message provides all balances from the single exchange and will be sent separately for all interconnected exchanges.

When this message is received, then the client must discard all balances from this exchange and apply the snapshot, which later will be modified by the BALANCE_UPDATE messages.

Delivery triggers:

Properties

Name Type Required Description
type string true Message type, constant BALANCE_SNAPSHOT.
exchange_id string false Exchange identifier.
exchange_id string false Exchange identifier.
data [object] false No description
» asset_id_exchange string false Exchange currency code.
» asset_id_coinapi string false CoinAPI currency code.
» balance number(float) false Value of the current total currency balance on the exchange.
» available number(float) false Value of the current available currency balance on the exchange that can be used as collateral.
» locked number(float) false Value of the current locked currency balance by the exchange.
» last_updated_by string false Source of the last modification.
» rate_usd number(float) false Current exchange rate to the USD for the single unit of the currency.

Enumerated Values

Property Value
last_updated_by INITIALIZATION
last_updated_by BALANCE_MANAGER
last_updated_by EXCHANGE

BALANCE_UPDATE IN

Example of the BALANCE_UPDATE message from the KRAKEN exchange.

{
    "type": "BALANCE_UPDATE",
    "exchange_id": "KRAKEN",
    "asset_id_exchange": "XBT",
    "asset_id_coinapi": "BTC",
    "balance": 0.00134444,
    "available": 0,
    "locked": 0.00134444,
    "last_updated_by": "EXCHANGE",
    "rate_usd": 9544.21
}

This message is sent to notify the client that the balance for the specific exchange currency pair changed.

When this message is received, the client must update the balance in the memory to maintain the current state of balance across all exchanges and currencies.

The initial state of the collection is delivered via the snapshot message BALANCE_SNAPSHOT.

Delivery triggers:

Properties

Name Type Required Description
type string true Message type, constant BALANCE_SNAPSHOT.
exchange_id string false Exchange identifier.
exchange_id string false Exchange identifier.
asset_id_exchange string false Exchange currency code.
asset_id_coinapi string false CoinAPI currency code.
balance number(float) false Value of the current total currency balance on the exchange.
available number(float) false Value of the current available currency balance on the exchange that can be used as collateral.
locked number(float) false Value of the current locked currency balance by the exchange.
last_updated_by string false Source of the last modification.
rate_usd number(float) false Current exchange rate to the USD for the single unit of the currency.

Enumerated Values

Property Value
last_updated_by INITIALIZATION
last_updated_by BALANCE_MANAGER
last_updated_by EXCHANGE

POSITION_SNAPSHOT IN

Example of the POSITION_SNAPSHOT message from the KRAKENFTS exchange.

{
    "type": "POSITION_SNAPSHOT",
    "exchange_id": "KRAKENFTS",
    "data": 
    [
        {
            "symbol_id_exchange": "XBT/USDT",
            "symbol_id_coinapi": "KRAKENFTS_PERP_BTC_USDT",
            "avg_entry_price": 0.00134444,
            "quantity": 0.00134444,
            "side": "BUY",
            "unrealised_pnl": 0,
            "leverage": 0,
            "cross_margin": true,
            "liquidation_price": 0.072323
        }
    ]
}

This message provides all positions from the single exchange and will be sent separately for all interconnected exchanges.

When this message is received, then the client must discard al positions from this exchange and apply the snapshot, which later will be modified by the POSITION_UPDATE messages.

Delivery triggers:

Properties

Name Type Required Description
type string true Message type, constant POSITION_SNAPSHOT.
exchange_id string false Exchange identifier.
data [object] false No description
» symbol_id_exchange string false Exchange symbol.
» symbol_id_coinapi string false CoinAPI symbol.
» avg_entry_price number false Calculated average price of all fills on this position.
» quantity number false The current position quantity.
» side string false Side of order.
» unrealized_pnl number false Unrealised profit or loss (PNL) of this position.
» leverage number false Leverage for this position reported by the exchange.
» cross_margin boolean false Is cross margin mode enable for this position?
» liquidation_price number false Liquidation price. If mark price will reach this value, the position will be liquidated.

POSITION_UPDATE IN

Example of the POSITION_UPDATE message from the KRAKENFTS exchange.

{
    "type": "POSITION_UPDATE",
    "exchange_id": "KRAKENFTS",
    "symbol_id_exchange": "XBT/USDT",
    "symbol_id_coinapi": "KRAKENFTS_PERP_BTC_USDT",
    "avg_entry_price": 0.00134444,
    "quantity": 0.00134444,
    "side": "BUY",
    "unrealised_pnl": 0,
    "leverage": 0,
    "cross_margin": true,
    "liquidation_price": 0.072323
}

This message is sent to notify the client that the position changed.

When this message is received, then the client must update the position in the memory to maintain the current state of all positions across all symbols and exchanges.

The initial state of the collection is delivered via the snapshot message POSITION_SNPASHOT.

Delivery triggers:

Properties

Name Type Required Description
type string true Message type, constant POSITION_SNAPSHOT.
exchange_id string false Exchange identifier.
symbol_id_exchange string false Exchange symbol.
symbol_id_coinapi string false CoinAPI symbol.
avg_entry_price number false Calculated average price of all fills on this position.
quantity number false The current position quantity.
side string false Side of order.
unrealized_pnl number false Unrealised profit or loss (PNL) of this position.
leverage number false Leverage for this position reported by the exchange.
cross_margin boolean false Is cross margin mode enable for this position?
liquidation_price number false Liquidation price. If mark price will reach this value, the position will be liquidated.

SYMBOLS_SNAPSHOT IN

Example of the SYMBOLS_SNAPSHOT message.

{
    "type": "SYMBOLS_SNAPSHOT",
    "exchange_id": "BITMEX",
    "data": [
      {
        "symbol_id_coinapi": "BITMEX_FTS_ETH_USD_200925",
        "symbol_id_exchange": "ETHUSDU20",
        "asset_id_base_exchange": "ETH",
        "asset_id_quote_exchange": "USD",
        "asset_id_base_coinapi": "ETH",
        "asset_id_quote_coinapi": "USD",
        "price_precision": 0.010000000,
        "size_precision": 1.000000000
      },
      {
        "symbol_id_coinapi": "BITMEX_FTS_LTC_BTC_200925",
        "symbol_id_exchange": "LTCU20",
        "asset_id_base_exchange": "LTC",
        "asset_id_quote_exchange": "XBT",
        "asset_id_base_coinapi": "LTC",
        "asset_id_quote_coinapi": "BTC",
        "price_precision": 0.000001000,
        "size_precision": 1.000000000
      }
    ]
}

This message provides all market symbols from the single exchange and will be sent separately for all interconnected exchanges.

When this message is received, then the client must discard all market symbols from this exchange and apply the snapshot.

Delivery triggers:

Properties

Name Type Required Description
type string true Message type, constant SYMBOLS_SNAPSHOT.
exchange_id string false Exchange identifier.
data [object] false No description
» symbol_id_exchange string false Exchange symbol identifier.
» symbol_id_coinapi string false CoinAPI symbol identifier.
» asset_id_base_exchange string false Base asset exchange identifier.
» asset_id_quote_exchange string false Quote asset exchange identifier.
» asset_id_base_coinapi string false Base asset CoinAPI identifier.
» asset_id_quote_coinapi string false Quote asset CoinAPI identifier.
» price_precision number false Price precision for the symbol.
» size_precision number false Size precision for the symbol.

MESSAGE_REJECT IN

Example of the MESSAGE_REJECT object.

{
  "type": "MESSAGE_REJECT",
  "reject_reason": "ORDER_ID_NOT_FOUND",
  "exchange_id": "BINANCE",
  "message": "Order with ID: BINANCE-7d8a-4888 not found",
  "rejected_message": "{\"client_order_id\":\"BINANCE-7d8a-4888\",\"exchange_id\":\"BINANCE\",\"type\":\"ORDER_CANCEL_SINGLE_REQUEST\"}"
}

Object is used to communicate rejection of user order request.

Properties

MessageReject object.

Name Type Required Description
type string true Message type, constant MESSAGE_REJECT.
reject_reason string true Cause of rejection. Allowed values: OTHER, EXCHANGE_UNREACHABLE, EXCHANGE_RESPONSE_TIMEOUT, ORDER_ID_NOT_FOUND, INVALID_TYPE, METHOD_NOT_SUPPORTED, JSON_ERROR,
exchange_id string false If the message related to exchange, then the identifier of the exchange will be provided.
message string true Message text.
rejected_message string false Value of rejected request, if available

EMS - FIX API

Financial Information eXchange (FIX) protocol is an electronic communications protocol initiated in 1992 for international real-time exchange of information related to securities transactions and markets.

You can use it for real-time order management and receiving execution reports from us, and it's an alternative to WebSocket protocol.

Implemented Standards:

Endpoints

Default session configuration:

[DEFAULT]
DefaultApplVerID=FIX.5.0
TransportDataDictionary=FIX/FIXT11.xml
AppDataDictionary=FIX/FIX50.xml
ConnectionType=initiator
ReconnectInterval=1
ResetOnLogon=Y
ResetOnLogout=Y
ResetOnDisconnect=Y
SenderCompID=OMS.FIX.CLIENT
SocketConnectPort=3401
SocketConnectHost=127.0.0.1

FIX 4.4 session configuration:

[SESSION]
BeginString=FIX.4.4
StartTime=00:00:00
EndTime=00:00:00
TargetCompID=CoinAPI.OEML.FIX
DataDictionary=FIX/FIX44.xml
HeartBtInt=1
FileStorePath=store

FIX 5.0 / FIXT 1.1 session configuration:

[SESSION]
BeginString=FIXT.1.1
StartTime=00:00:00
EndTime=00:00:00
TargetCompID=CoinAPI.OEML.FIX
DataDictionary=FIX/FIX50.xml
HeartBtInt=1
FileStorePath=store
Deployment Environment Hostname Port Authentication
Managed Cloud Production Use Managed Cloud REST API /v1/locations to get specific endpoints to each server site where your deployments span 3301 TLS Client Certificate
Managed Cloud Sandbox ems-gateway-aws-eu-central-1-dev.coinapi.io 3301 TLS Client Certificate
Self Hosted Production IP Address of the ems-gateway container/excecutable in the closest server site to the caller location 3401 No
Self Hosted Sandbox IP Address of the ems-gateway container/excecutable in the closest server site to the caller location 3401 No

Our sesssion configuration parameters:

Parameter Value
Hostname look at the table above
Port look at the table above
Specifications FIX 4.4: FIX44.xml
FIX 5.0: FIX50.xml
FIXT 1.1: FIXT11.xml
Gateway timezone UTC
ReconnectInterval 1
ResetOnLogon Y
ResetOnLogout Y
ResetOnDisconnect Y
SenderCompID OMS.FIX.CLIENT
TargetCompID CoinAPI.OEML.FIX
SocketConnectPort look at the table above
StartTime 00:00:00
EndTime 00:00:00
HeartBtInt 1

Authentication

As you can observe in the documentation below in the Logon FIX Message, do not contain any authentication data. This is by design.

If the software is deployed as Self-Hosted then API do not require authentication as inside your infrastructure, your company is responsible for the security and access controls.

If the software is deployed in our Managed Cloud, then we need your client to provide us the certificate from the Managed Cloud REST API, while establishing a TLS session with us. We are using the that client certificate provided on the TLS layer, to authenticaticate your FIX session.

Messages

This section will provide necessary documentation for the FIX protocol messages.

New Order Single 35=D

FIX Field Name WebSocket Field Name Description
ClOrdID client_order_id The unique identifier of the order assigned by the client.
ClOrdLinkID client_order_id The same value as for ClOrdID.
ExDestination exchange_id Exchange identifier used to identify the routing destination.
SecurityID symbol_coinapi or
symbol_exchange
CoinAPI or Exchange symbol, depends on the value of SecurityIDSource <22> type
SecurityIDSource N/A Identifies source of the SecurityID <48> value. 8 = EXCHANGE, 101 = COINAPI
Symbol The same value as for SecurityID.
TransactTime N/A Time this order request was initiated/released by the trader, trading system, or intermediary.
OrdType order_type Order types are documented in the separate section: EMS / Starter Guide / Order parameters / Order type
Side side Side of order.
Price price Order price.
OrderQty amount_order Order quantity.
TimeInForce time_in_force Order time in force options are documented in the separate section: EMS / Starter Guide / Order parameters / Time in force
ExpireTime expire_time Expiration time. Conditionaly required if TimeInForce <59> = GTD
ExecInst exec_inst Order execution instructions are documented in the separate section: EMS / Starter Guide / Order parameters / Execution instructions

Order Cancel Request 35=F

FIX Field Name WebSocket Field Name Description
ClOrdID N/A Unique ID of cancel request as assigned by the client.
OrigClOrdID client_order_id The unique identifier of the order assigned by the client. One of the properties (OrigClOrdID, OrderID) is required to identify the order.
OrderID exchange_order_id Unique identifier of the order assigned by the exchange or executing system. One of the properties (OrigClOrdID, OrderID) is required to identify the order.
SecurityExchange exchange_id Exchange identifier used to identify the routing destination.
TransactTime N/A Time this order request was initiated/released by the trader, trading system, or intermediary.
Side N/A This value is ignored.
Symbol N/A This value is ignored.

Order Mass Cancel Request 35=q

FIX Field Name WebSocket Field Name Description
ClOrdID N/A Unique ID of Order Mass Cancel Request <q> as assigned by the client.
MassCancelRequestType N/A 7 = Cancel all orders
SecurityExchange exchange_id Exchange identifier used to identify routing destination.

Execution Report 35=8

FIX Field Name WebSocket Field Name Description
OrderID client_order_id Unique identifier of the order as assigned by client.
SecondaryOrderID exchange_order_id Unique identifier of the order assigned by the exchange or executing system.
ExecID N/A Unique identifier of execution message as assigned by sell-side.
ExecType N/A I = Order Status. Describes the purpose of the execution report.
OrdStatus status Order statuses and the lifecycle are documented in the separate section: EMS / Starter Guide / Order Lifecycle
SecurityID symbol_coinapi or
symbol_exchange
CoinAPI or Exchange symbol, depends on the value of SecurityIDSource <22> type
SecurityIDSource N/A Identifies source of the SecurityID <48> value. 8 = EXCHANGE, 101 = COINAPI
Symbol The same value as for SecurityID.
SecurityExchange exchange_id Exchange identifier used to identify the routing destination.
Side side Side of order.
OrderQty amount_order Quantity ordered.
CumQty amount_filled Total quantity filled.
LeavesQty amount_open Quantity open for further execution. LeavesQty <151> = OrderQty <38> - CumQty <14>.
Was this section helpful?
StatusPage: