Market Data - Starter Guide
Welcome to the CoinAPI developer documentation. This document should contain all the information required to properly implement applications using our API.
There are 3 main interfaces that can be used to access CoinAPI:
API | Communication | Description |
---|---|---|
RESTful | Request-response | Stateless API providing the widest range of data, not capable of streaming, only pooling. |
WebSocket | Publish-subscribe | Stateful API providing streaming of realtime market data. |
FIX | Publish-subscribe | Stateful API providing streaming of realtime market data, widely adopted by the finance industry. |
SDK
Our Software Development Kit (SDK) is available on GitHub at https://github.com/coinapi/coinapi-sdk. If possible then we are strongly recommending using our tested libraries available on GitHub, rather than creating new ones. However, if you decide to create your own implementation or to change existing one, then we encourage you to create Pull Request to our main repository with proposed changes, then we will able to include your code in our official repository for use by other users, effectively creating collaboration.
In repository you can find libraries or examples for languages or enviroments like:
- Python
- R
- Matlab
- C#
- C++
- .NET
- Java
- Ruby
- Go
- JavaScript
- TypeScript
- Node.js
- PHP
- Haskell
- Objective-C
- Swift
Security
The use of the encryption is optional, and the decision to use it is on you. On the encrypted endpoints, we are using protocols that are considered the best security practices.
Standards and conventions
This section represents used standards and conventions across all documents and API's.
Variables naming
All variables are named using the Snake case (or snake_case
) naming convention.
This means that words are separated by a single underscore _
character, no spaces are used, and letters are lowercase.
Asset codes
ISO 4217 currency code standard is used for fiat money identifications. Cryptocurrency assets are identified using codes used by the general public or adopted by the majority of exchanges.
Exchange codes
Exchange on our platform is identified by the specific exchange API and the matching engine behind it. When the example exchange has multiple separate APIs, e.g., for different products SPOT, OPTIONS, or to cover other regions, we will expose these symbols from these respective APIs on different exchange identifiers. Below are examples of BINANCE (multiple APIs, multiple regions) and DERIBIT (single API, single region). Full listing of exchanges can be queried using the Market Data REST API.
BINANCE Exchange Ids | Website | Description |
---|---|---|
BINANCE | https://www.binance.com/ | Binance |
BINANCEDEX | https://www.binance.org/ | Binance DEX |
BINANCEFTS | https://www.binance.com/ | Binance Futures (USDT/dapi) |
BINANCEFTSC | https://www.binance.com/ | Binance Futures (Coin/fapi) |
BINANCEFTSCUAT | https://www.binance.com/ | Binance Futures Testnet (Coin/fapi) |
BINANCEFTSUAT | https://www.binance.com/ | Binance Futures Testnet (USDT/dapi) |
BINANCEJE | https://www.binance.je/ | Binance Jersey |
BINANCEJEX | https://www.jex.com/en | Binance JEX |
BINANCEKR | https://www.binance.kr/ | Binance Korea |
BINANCEOPTV | https://www.binance.com/ | Binance Options Vanilla (vapi) |
BINANCEOPTVUAT | https://www.binance.com/ | Binance Options Vanilla Testnet (vapi) |
BINANCEUAT | https://www.binance.com/ | Binance Testnet |
BINANCEUG | https://www.binance.co.ug/ | Binance Uganda |
BINANCEUS | https://www.binance.us/ | Binance US |
DERIBIT Exchange Ids | Website | Description |
---|---|---|
DERIBIT | https://www.deribit.com/ | Deribit |
Numbers precision
Numbers in our platform can have maximum 19 digits overall, but no more than 9 decimal places. In cases when number representing aggregate value then we allowing 38 digits overall, but still no more than 9 decimal places.
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:
yyyy-MM-ddTHH:mm:ss.fffffff
yyyy-MM-ddTHH:mm:ss.fff
yyyy-MM-ddTHH:mm:ss
yyyy-MM-ddTHH:mm
yyyy-MM-ddTHH
yyyy-MM-dd
yyyyMMddTHHmmssfffffff
yyyyMMddTHHmmssfff
yyyyMMddTHHmmss
yyyyMMddTHHmm
yyyyMMddTHH
yyyyMMdd
Output time values are formatted using the following patterns:
yyyy-MM-ddTHH:mm:ss.fffffffZ
yyyy-MM-dd
Market Data - REST API
RESTful endpoint provides the widest range of data, based on HTTP protocol which works in Request-Reply scheme.
Implemented Standards:
Endpoints
Enviroment | Encryption | Value |
---|---|---|
Production | Yes | https://rest.coinapi.io/ |
Production | No | http://rest.coinapi.io/ |
Sandbox | Yes | https://rest-sandbox.coinapi.io/ |
Sandbox | No | http://rest-sandbox.coinapi.io/ |
Sandbox
The sandbox environment is provided for development and non-production use-cases, it has few differences in comparison to the production one:
- You still need active API Key to access the sandbox; it can be a free one.
- We do not provide any support or SLA for this environment.
- Real-time and historical data is limited to specific data sources: COINBASE, GEMINI, testnets, UAT environments and ECB (European Central Bank).
- Data could be invalid/fake or delayed.
- API changes could be visible faster on the sandbox than in the production environment.
General
Authorization
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:
- Custom authorization header named
X-CoinAPI-Key
- 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 exchange rates from BTC
asset, then your query string should look like this:
GET /v1/exchangerate/BTC?apikey=73034021-THIS-IS-SAMPLE-KEY
HTTP Requests
Each HTTP request must contain the header Accept: application/json
as all our responses are in JSON format.
We encourage you to use the HTTP request header Accept-Encoding: deflate, gzip
for all requests.
This will indicate to us that we can deliver compressed data to you which on your side should be decompressed transparently.
HTTP Success
Successful HTTP responses have the status code 200
and the body in a format according to documentation of the requested resource.
HTTP Errors
Error message is returned in JSON structured like this:
{
"message": "Invalid API key"
}
All HTTP requests with response status codes different to 200
must be considered as failed
and you should expect additional JSON inside the body of the response with the error message encapsulated inside it as shown in the example.
We use the following error codes:
Error Code | Meaning |
---|---|
400 | Bad Request -- There is something wrong with your request |
401 | Unauthorized -- Your API key is wrong |
403 | Forbidden -- Your API key doesnt't have enough privileges to access this resource |
429 | Too many requests -- You have exceeded your API key rate limits |
550 | No data -- You requested specific single item that we don't have at this moment. |
Limits
Any authenticated endpoint is providing (in HTTP response headers) information about the current state of the limits associated with API Key. In this section we will describe each limit.
Request limit / APIKey
X-RateLimit-Limit: 1000000
X-RateLimit-Remaining: 999989
X-RateLimit-Request-Cost: 1
X-RateLimit-Reset: 2018-01-22T15:25:15.1234567Z
The request limit define number of maximum requests that could be executed in the 24 hours period (sliding/rollowing window - always last 24 hours from specific moment) for your subscription.
We define request as data request credits and this is not always equal to the number of API calls executed against the API. A request is deemed to be a single one if the limit query parameter on the endpoint isn’t available, isn’t used or it's stated otherwise in the API documentation. Otherwise — if the limit query parameter is available and is used — then each of the 100 data points returned in the response is counted as one request.
For example at the 2019-08-22 13:00 UTC value of the requests remaining (X-RateLimit-Remaining) will be equal to the allocated quota (X-RateLimit-Limit) decreased by the sum of the request costs (SUM(X-RateLimit-Request-Cost)) executed in the period 2019-08-21 13:00 UTC - 2019-08-22 13:00 UTC (last 24 hours).
HTTP Header | Type | Description |
---|---|---|
X-RateLimit-Used | int | Request limit used (in the last 24-hours period). |
X-RateLimit-Limit | int | Request limit allocated (in the last 24-hours period). |
X-RateLimit-Remaining | int | The number of requests left at the moment based on the last 24-hour usage. |
X-RateLimit-Request-Cost | int | The number of requests used to generate current HTTP response. |
X-RateLimit-Reset | timestring | The time when all provisioned requests are available to execute again if no more requests will be executed. |
X-RateLimit-Overage | string | Status of the overage mode. Allowed values: ENABLED or DISABLED . |
Concurrency limit / APIKey
X-ConcurrencyLimit-Limit: 10
X-ConcurrencyLimit-Remaining: 5
The concurrency limit defines the number of maximum concurrent API calls/requests that the API could process for your subscription at the current moment. Every API call/request increases the Concurrency limit against quota, and when it finishes, decreases it.
HTTP Header | Type | Description |
---|---|---|
X-ConcurrencyLimit-Limit | int | Concurrency limit allocated for your API key. |
X-ConcurrencyLimit-Remaining | int | The number of concurrent API calls/requests available to be executed in this moment for your API key. |
Output data format
By default we are using JSON output data format for all of our endpoints, you can control format of data by using output_format
variable in query string parameters.
URL Parameters
Parameter | Type | Description |
---|---|---|
output_format | string | Output data format (optional, default value is json , possible values are json , xml or csv ) |
csv_include_header | bool | Ignore header line in CSV output? (optional, default value is true , true to include CSV header line, false otherwise) |
csv_include_quotes | bool | Encapsulate strings with quotes in CSV output? (optional, default value is false , true to encapsulate all strings with " , false to leave them unquoted) |
csv_exclude_col | string | Comma delimited list of column names to ignore in CSV output (optional, by default all columns are included) |
csv_set_delimiter | string | Character that will be used as column delimiter in CSV output (optional, default value is ; ) |
csv_set_dec_mark | string | Character that will be used as decimal separator in CSV output (optional, default value is . ) |
csv_set_timeformat | string | Format for datetime type in CSV output or unix for unix timestamp (optional, default value is yyyy-MM-ddTHH:mm:ss.fffffffZ ) |
csv_set_newline | string | New line type (optional, default value is unix , possible values win , mac , unix ) |
Excel / G-Sheets
There are several ways to use data from our REST API inside the Excel, Google Sheets, or similar calculation sheet application. This section will do as best as possible to keep all information up to date on how you could load the data into these applications. Feel free to contact support if we are missing an option.
CSV download, import:
- Open the data in the CSV format from the browser eg.
https://rest.coinapi.io/v1/exchangerate/USD?apikey=YOUR_API_KEY&invert=true&output_format=csv
- Save the data to the file with the .csv extension.
- Use the file saved and import it into the software.
- When configuring import, refer to the parameters like delimiter from the Output data format
The platform-independent way described above is based on CSV but could also be used in other formats like JSON and XML as long as the software support it, but the import procedure needs to be adjusted accordingly.
Microsoft Excel
- Use PowerQuery to load the URL directly into the CSV import without saving the file locally.
- Use the =WEBSERVICE function to load the API response directly into the sheet, but this will not parse the data; additional processing is required.
Google Sheets
- Use =IMPORT function to load the REST API endpoint and automatically parse the CSV format data into the cells. eg.
=IMPORTDATA("https://rest.coinapi.io/v1/exchangerate/USD?apikey=YOUR_API_KEY&invert=true&output_format=csv
OpenOffice Calc
- Select the menu Insert -> Sheet From File, 2. In the Insert dialog, put the URL eg.
https://rest.coinapi.io/v1/exchangerate/USD?apikey=YOUR_API_KEY&invert=true&output_format=csv
in the File Name box at the bottom. Set the drop-down list next to that to Web Page Query and click Open. The Text Import dialog opens where you can change the defaults if needed.
Metadata
List all exchanges GET
curl https://rest.coinapi.io/v1/exchanges \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/exchanges");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/exchanges');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/exchanges'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/exchanges",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/exchanges")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/exchanges")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/exchanges")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"exchange_id": "OKCOIN_CNY",
"website": "https://www.okcoin.cn/",
"name": "OKCoin CNY",
"data_start": "2013-06-12",
"data_end": "2018-03-09",
"data_quote_start": "2015-02-15T12:53:50.3430000Z",
"data_quote_end": "2018-03-09T23:34:52.5800000Z",
"data_orderbook_start": "2015-02-15T12:53:50.3430000Z",
"data_orderbook_end": "2018-03-09T23:34:52.5800000Z",
"data_trade_start": "2013-06-12T14:24:24.0000000Z",
"data_trade_end": "2017-11-01T16:30:39.7077259Z",
"data_symbols_count": 2,
"volume_1hrs_usd": 0.0,
"volume_1day_usd": 0.0,
"volume_1mth_usd": 0.0
},
{
"exchange_id": "HUOBI",
"website": "https://www.huobi.com/",
"name": "Huobi (HBUS)",
"data_start": "2015-03-29",
"data_end": "2019-11-03",
"data_quote_start": "2015-03-29T21:46:06.2630000Z",
"data_quote_end": "2019-11-03T18:22:29.1837496Z",
"data_orderbook_start": "2015-03-29T21:46:06.2630000Z",
"data_orderbook_end": "2019-11-03T18:23:53.2859878Z",
"data_trade_start": "2015-03-29T21:46:08.7030000Z",
"data_trade_end": "2019-11-03T18:21:48.2770000Z",
"data_symbols_count": 403,
"volume_1hrs_usd": 1605.80,
"volume_1day_usd": 59957.44,
"volume_1mth_usd": 1259508.43
}
]
Get a detailed list of exchanges provided by the system.
HTTP Request
GET /v1/exchanges
GET /v1/exchanges/{exchange_id}
GET /v1/exchanges?filter_exchange_id={filter_exchange_id}
URL Parameters
Parameter | Type | Description |
---|---|---|
filter_exchange_id | string[] | Comma or semicolon delimited exchange identifiers used to filter response. (optional, eg. BITSTAMP;GEMINI ) |
Output variables
Variable | Description |
---|---|
exchange_id | Our exchange identifier |
website | Exchange website address |
name | Display name of the exchange |
data_start | The date of first data point. |
data_end | The date of last data point. |
data_quote_start | The date and time of first quote. |
data_quote_end | The date and time of last quote. |
data_orderbook_start | The date and time of first order book. |
data_orderbook_end | The date and time of last order book. |
data_trade_start | The date and time of first trade. |
data_trade_end | The date and time of last trade. |
data_symbols_count | The count of all symbols within exchange. |
volume_1hrs_usd | The usd volume of all symbols from last 1 hour rolling period. |
volume_1day_usd | The usd volume of all symbols from last 1 day rolling period. |
volume_1mth_usd | The usd volume of all symbols from last 1 month rolling period. |
List all exchange icons GET
var client = new RestClient("https://rest.coinapi.io/v1/exchanges/icons/32");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
[
{
"exchange_id": "CHAINCE",
"url": "https://s3.eu-central-1.amazonaws.com/bbxt-static-icons/type-id/png_16/204e55dd8dab4a0d823c21f04be6be4b.png"
},
{
"exchange_id": "BILAXY",
"url": "https://s3.eu-central-1.amazonaws.com/bbxt-static-icons/type-id/png_16/4958c92dbddd4936b1f655e5063dc782.png"
},
{
"exchange_id": "BCOINSG",
"url": "https://s3.eu-central-1.amazonaws.com/bbxt-static-icons/type-id/png_16/b7c77041cdef4f359b4044b2d73c7741.png"
}
]
Gets the list of icons (of the given size) for all the exchanges.
HTTP Request
GET /v1/exchanges/icons/{iconSize}
Output variables
Variable | Description |
---|---|
exchange_id | Our exchange identifier. |
url | The url of icon. |
List all assets GET
curl https://rest.coinapi.io/v1/assets \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/assets");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/assets');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/assets'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/assets",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/assets")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/assets")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/assets")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"asset_id": "BTC",
"name": "Bitcoin",
"type_is_crypto": 1,
"data_start": "2010-07-17",
"data_end": "2019-11-03",
"data_quote_start": "2014-02-24T17:43:05.0000000Z",
"data_quote_end": "2019-11-03T17:55:07.6724523Z",
"data_orderbook_start": "2014-02-24T17:43:05.0000000Z",
"data_orderbook_end": "2019-11-03T17:55:17.8592413Z",
"data_trade_start": "2010-07-17T23:09:17.0000000Z",
"data_trade_end": "2019-11-03T17:55:11.8220000Z",
"data_symbols_count": 22711,
"volume_1hrs_usd": 102894431436.49,
"volume_1day_usd": 2086392323256.16,
"volume_1mth_usd": 57929168359984.54,
"price_usd": 9166.207274778093436220194944
},
{
"asset_id": "USD",
"name": "US Dollar",
"type_is_crypto": 0,
"data_start": "2010-07-17",
"data_end": "2019-11-03",
"data_quote_start": "2014-02-24T17:43:05.0000000Z",
"data_quote_end": "2019-11-03T17:54:49.3807706Z",
"data_orderbook_start": "2014-02-24T17:43:05.0000000Z",
"data_orderbook_end": "2019-11-03T17:55:13.1863931Z",
"data_trade_start": "2010-07-17T23:09:17.0000000Z",
"data_trade_end": "2019-11-03T17:55:07.7870000Z",
"data_symbols_count": 10728,
"volume_1hrs_usd": 9466454016.52,
"volume_1day_usd": 221580758173.49,
"volume_1mth_usd": 11816685174661.70,
"price_usd": 1.0
}
]
Get detailed list of assets.
HTTP Request
GET /v1/assets
GET /v1/assets/{asset_id}
GET /v1/assets?filter_asset_id={filter_asset_id}
URL Parameters
Parameter | Type | Description |
---|---|---|
filter_asset_id | string[] | Comma or semicolon delimited asset identifiers used to filter response. (optional, eg. BTC;ETH ) |
Output variables
Variable | Description |
---|---|
asset_id | Our asset identifier. Superset of the ISO 4217 currency codes standard. |
name | Display name of the asset. |
type_is_crypto | Boolean value transported as integer; 1 for cryptocurrency assets, 0 otherwise. |
data_quote_start | The date and time of first quote. |
data_quote_end | The date and time for last quote. |
data_orderbook_start | The date and time for first order book. |
data_orderbook_end | The date and time for last order book. |
data_trade_start | The date and time for first trade. |
data_trade_end | The date and time for last trade. |
data_quote_count | The count of quotes. |
data_trade_count | The count of trades. |
data_symbols_count | The count of symbols for given asset. |
volume_1hrs_usd | The usd volume of all symbols associated with this asset from last 1 hour rolling period. |
volume_1day_usd | The usd volume of all symbols associated with this asset from last 1 day rolling period. |
volume_1mth_usd | The usd volume of all symbols associated with this asset from last 1 month rolling period. |
price_usd | The actual usd price. |
List all asset icons GET
var client = new RestClient("https://rest.coinapi.io/v1/assets/icons/32");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
[
{
"asset_id": "BTC",
"url": "https://s3.eu-central-1.amazonaws.com/bbxt-static-icons/type-id/png_16/f231d7382689406f9a50dde841418c64.png"
},
{
"asset_id": "ETH",
"url": "https://s3.eu-central-1.amazonaws.com/bbxt-static-icons/type-id/png_16/04836ff3bc4d4d95820e0155594dca86.png"
},
{
"asset_id": "USD",
"url": "https://s3.eu-central-1.amazonaws.com/bbxt-static-icons/type-id/png_16/4873707f25fe4de3b4bca6fa5c631011.png"
}
]
Gets the list of icons (of the given size) for all the assets.
HTTP Request
GET /v1/assets/icons/{iconSize}
Output variables
Variable | Description |
---|---|
asset_id | Our asset identifier. |
url | The url of icon. |
List all symbols GET
curl https://rest.coinapi.io/v1/symbols \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/symbols");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/symbols');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/symbols'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/symbols",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/symbols")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/symbols")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/symbols")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"symbol_id": "KRAKENFTS_PERP_BTC_USD",
"exchange_id": "KRAKENFTS",
"symbol_type": "PERPETUAL",
"asset_id_base": "BTC",
"asset_id_quote": "USD",
"asset_id_unit": "USD",
"future_contract_unit": 1.000000000,
"future_contract_unit_asset": "USD",
"data_start": "2019-10-30",
"data_end": "2021-03-03",
"data_quote_start": "2019-10-30T16:53:10.3262317Z",
"data_quote_end": "2021-03-03T13:51:45.6970000Z",
"data_orderbook_start": "2019-10-30T16:53:10.3262317Z",
"data_orderbook_end": "2020-08-05T14:37:32.0080000Z",
"data_trade_start": "2019-10-30T16:38:52.1620000Z",
"data_trade_end": "2021-03-03T13:46:25.7810000Z",
"volume_1hrs": 22897091.000000000,
"volume_1hrs_usd": 22897091.00,
"volume_1day": 459390289.000000000,
"volume_1day_usd": 459390289.00,
"volume_1mth": 12875674995.000000000,
"volume_1mth_usd": 12875674995.00,
"price": 51266,
"symbol_id_exchange": "pi_xbtusd",
"asset_id_base_exchange": "XBT",
"asset_id_quote_exchange": "USD",
"price_precision": 0.100000000,
"size_precision": 1.000000000
},
{
"symbol_id": "POLONIEX_SPOT_LTC_USDC",
"exchange_id": "POLONIEX",
"symbol_type": "SPOT",
"asset_id_base": "LTC",
"asset_id_quote": "USDC",
"data_start": "2018-11-20",
"data_end": "2021-03-01",
"data_quote_start": "2018-11-20T15:24:58.4128803Z",
"data_quote_end": "2021-03-01T16:07:09.3475456Z",
"data_orderbook_start": "2018-11-20T15:24:58.4128803Z",
"data_orderbook_end": "2020-08-05T14:37:20.2695780Z",
"data_trade_start": "2018-11-20T15:25:38.0000000Z",
"data_trade_end": "2021-03-01T16:03:18.0000000Z",
"volume_1hrs": 51.686458990,
"volume_1hrs_usd": 9036.44,
"volume_1day": 465.568863000,
"volume_1day_usd": 81396.28,
"volume_1mth": 22528.276384950,
"volume_1mth_usd": 3938661.00,
"symbol_id_exchange": "USDC_LTC",
"asset_id_base_exchange": "LTC",
"asset_id_quote_exchange": "USDC",
"price_precision": 0.000000010,
"size_precision": 0.000000010
}
]
Get detailed list of all symbols.
HTTP Request
GET /v1/symbols?filter_symbol_id={filter_symbol_id}&filter_exchange_id={filter_exchange_id}&filter_asset_id={filter_asset_id}
GET /v1/symbols/{exchange_id}
URL Parameters
Parameter | Type | Description |
---|---|---|
filter_symbol_id | string[] | Comma or semicolon delimited parts of symbol identifier used to filter response. (optional, eg. BITSTAMP_ or BINANCE_SPOT_ ) |
Common output variables
Variable | Description |
---|---|
symbol_id | Our symbol identifier, see table below for format description. |
exchange_id | Our identifier of the exchange where symbol is traded. |
symbol_type | Type of the symbol. Valid values:
|
asset_id_base | FX Spot base asset identifier, for derivatives it's contact underlying (e.g. BTC for BTC/USD) |
asset_id_quote | FX Spot quote asset identifier, for derivatives it's contract underlying (e.g. USD for BTC/USD) |
asset_id_unit | Identifier of the symbol unit asset used to denominate: transactions and order books volume (optional, if not provided then data is denominated in asset_id_base ) |
data_start | Date of the first data point |
data_end | Date of the last data point |
data_quote_start | The date and time of first quote. |
data_quote_end | The date and time of last quote. |
data_orderbook_start | The date and time of first order book. |
data_orderbook_end | The date and time of last order book. |
data_trade_start | The date and time of first trade. |
data_trade_end | The date and time of last trade. |
volume_1hrs | Volume denominated in symbol unit asset from last 1 hour rolling period. |
volume_1hrs_usd | Volume denominated in USD from last 1 hour rolling period. |
volume_1day | Volume denominated in symbol unit asset from last 1 day rolling period. |
volume_1day_usd | Volume denominated in USD from last 1 day rolling period. |
volume_1mth | Volume denominated in symbol unit asset from last 1 month rolling period. |
volume_1mth_usd | Volume denominated in USD from last 1 month rolling period. |
price | The current price. |
symbol_id_exchange | Exchange symbol identifier. |
asset_id_base_exchange | Exchange FX Spot base asset identifier |
asset_id_quote_exchange | Exchange FX Spot quote asset identifier |
price_precision | Current order price precision observed (a posteriori) from the market data or known (a priori) from the data source metadata. |
size_precision | Current order size precision observed (a posteriori) from the market data or known (a priori) from the data source metadata. |
Symbol identifier
Our symbol identifier is created using a pattern that depends on symbol type.
Type | symbol_id pattern |
---|---|
SPOT | {exchange_id}_SPOT_{asset_id_base}_{asset_id_quote} |
FUTURES | {exchange_id}_FTS_{asset_id_base}_{asset_id_quote}_{YYMMDD of future_delivery_time} |
OPTION | {exchange_id}_OPT_{asset_id_base}_{asset_id_quote}_{YYMMDD of option_expiration_time}_{option_strike_price}_{option_type_is_call as C/P} |
PERPETUAL | {exchange_id}_PERP_{asset_id_base}_{asset_id_quote} |
INDEX | {exchange_id}_IDX_{index_id} |
CREDIT | {exchange_id}_CRE_{asset_id_base} |
CONTACT | {exchange_id}_COT_{contract_id} |
Symbol types list (enumeration of symbol_type
output variable)
Type | Name | Description |
---|---|---|
SPOT | FX Spot | Agreement to exchange one asset for another one (e.g. Buy BTC for USD) |
FUTURES | Futures contract | FX Spot derivative contract where traders agree to trade fx spot at predetermined future time |
OPTION | Option contract | FX Spot derivative contract where traders agree to trade right to require buy or sell of fx spot at agreed price on exercise date |
PERPETUAL | Perpetual contract | FX Spot derivative contract where traders agree to trade fx spot continously without predetermined future delivery time |
INDEX | Index | Statistical composite that measures changes in the economy or markets. |
CREDIT | Credit/Funding | Margin funding contract. Order book displays lending offers and borrow bids. Price represents the daily rate. |
CONTRACT | Contract | Represents other types of financial instruments (e.g. spreads, interest rate swap) |
Additional output variables for symbol_type = INDEX
Variable | Description |
---|---|
index_id | Index identifier |
index_display_name | Human readable name of the index (optional) |
index_display_description | Description of the index (optional) |
Additional output variables for symbol_type = FUTURES
Variable | Description |
---|---|
future_delivery_time | Predetermined time of futures contract delivery date in ISO 8601 |
future_contract_unit | Contact size (eg. 10 BTC if future_contract_unit = 10 and future_contract_unit_asset = BTC ) |
future_contract_unit_asset | Identifier of the asset used to denominate the contract unit |
Additional output variables for symbol_type = PERPETUAL
Variable | Description |
---|---|
future_contract_unit | Contact size (eg. 10 BTC if future_contract_unit = 10 and future_contract_unit_asset = BTC ) |
future_contract_unit_asset | Identifier of the asset used to denominate the contract unit |
Additional output variables for symbol_type = OPTION
Variable | Description |
---|---|
option_type_is_call | Boolean value representing option type. true for Call options, false for Put options |
option_strike_price | Price at which option contract can be exercised |
option_contract_unit | Base asset amount of underlying spot which single option represents |
option_exercise_style | Option exercise style. Can be EUROPEAN or AMERICAN |
option_expiration_time | Option contract expiration time in ISO 8601 |
Additional output variables for symbol_type = CONTRACT
Variable | Description |
---|---|
contract_delivery_time | Predetermined time of contract delivery date in ISO 8601 |
contract_unit | Contact size (eg. 10 BTC if contract_unit = 10 and contract_unit_asset = BTC ) |
contract_unit_asset | Identifier of the asset used to denominate the contract unit |
contract_id | Identifier of contract by the exchange |
Exchange rates
Exchange rate is defined as (VWAP-24H) last 24 hour (rolling window over time) Volume Weighted Average Price across multiple data sources listed on our platform. We are selecting and managing the data sources that are used in the calculation based on multiple factors to provide data of highest quality.
Get specific rate GET
curl https://rest.coinapi.io/v1/exchangerate/BTC/USD \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/exchangerate/BTC/USD");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/exchangerate/BTC/USD');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/exchangerate/BTC/USD'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/exchangerate/BTC/USD",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/exchangerate/BTC/USD")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/exchangerate/BTC/USD")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/exchangerate/BTC/USD")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
{
"time": "2017-08-09T14:31:18.3150000Z",
"asset_id_base": "BTC",
"asset_id_quote": "USD",
"rate": 3260.3514321215056208129867667
}
Get exchange rate between pair of requested assets at specific or current time.
HTTP Request
GET /v1/exchangerate/{asset_id_base}/{asset_id_quote}?time={time}
URL Parameters
Parameter | Type | Description |
---|---|---|
asset_id_base | string | Requested exchange rate base asset identifier. Full list available here |
asset_id_quote | string | Requested exchange rate quote asset identifier. Full list available here |
time | timestring | Time at which exchange rate is calculated (optional, if not supplied then current rate is returned) |
Output variables
Variable | Description |
---|---|
time | Time in ISO 8601 of the market data used to calculate exchange rate |
asset_id_base | Exchange rate base asset identifier |
asset_id_quote | Exchange rate quote asset identifier |
rate | Exchange rate between assets |
Get all current rates GET
HTTP Request
GET /v1/exchangerate/{asset_id_base}?invert={invert}
curl https://rest.coinapi.io/v1/exchangerate/BTC?invert=false \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/exchangerate/BTC?invert=false");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/exchangerate/BTC?invert=false');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/exchangerate/BTC?invert=false'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/exchangerate/BTC?invert=false",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/exchangerate/BTC?invert=false")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/exchangerate/BTC?invert=false")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/exchangerate/BTC?invert=false")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
{
"asset_id_base": "BTC",
"rates" : [
{
"time": "2017-08-09T14:31:37.0520000Z",
"asset_id_quote": "USD",
"rate": 3258.8875417798037784035133948
},
{
"time": "2017-08-09T14:31:36.7570000Z",
"asset_id_quote": "EUR",
"rate": 2782.5255080599273092901331567
},
{
"time": "2017-08-09T14:31:36.7570000Z",
"asset_id_quote": "CNY",
"rate": 21756.295595926054627342411501
},
{
"time": "2017-08-09T14:31:36.7570000Z",
"asset_id_quote": "GBP",
"rate": 2509.6024203799580199765804823
}
]
}
Get the current exchange rate between requested asset and all other assets.
HTTP Request
GET /v1/exchangerate/{asset_id_base}
URL Parameters
Parameter | Type | Description |
---|---|---|
asset_id_base | string | Requested exchange rates base asset identifier. Full list available here |
filter_asset_id | string[] | Comma or semicolon delimited asset identifiers used to filter response. (optional, full list available here) |
invert | bool | True will invert all the rates (optional, if true then rates will be calculated as rate = 1 / actual_rate eg. USD/BTC as BTC/USD ) |
Output variables
Variable | Description |
---|---|
time | Time in ISO 8601 of the market data used to calculate exchange rates |
asset_id_base | Base asset identifier for all rates |
asset_id_quote | Quote asset identifier of specific rate |
rate | Exchange rate between assets |
Timeseries periods GET
curl https://rest.coinapi.io/v1/exchangerate/history/periods \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/exchangerate/history/periods");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/exchangerate/history/periods');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/exchangerate/history/periods'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/exchangerate/history/periods",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/exchangerate/history/periods")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/exchangerate/history/periods")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/exchangerate/history/periods")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
You can also obtain historical exchange rates of any asset pair, grouped into time periods.
Get full list of supported time periods available for requesting exchange rates historical timeseries data.
HTTP Request
GET /v1/exchangerate/history/periods
The above command returns JSON structured like this:
[
{
"period_id": "1SEC",
"length_seconds": 1,
"length_months": 0,
"unit_count": 1,
"unit_name": "second",
"display_name": "1 Second"
},
{
"period_id": "30MIN",
"length_seconds": 1800,
"length_months": 0,
"unit_count": 30,
"unit_name": "minute",
"display_name": "30 Minutes"
},
{
"period_id": "10DAY",
"length_seconds": 864000,
"length_months": 0,
"unit_count": 10,
"unit_name": "day",
"display_name": "10 Days"
}
]
Timeseries periods
Time unit | Period identifiers |
---|---|
Second | 1SEC, 2SEC, 3SEC, 4SEC, 5SEC, 6SEC, 10SEC, 15SEC, 20SEC, 30SEC |
Minute | 1MIN, 2MIN, 3MIN, 4MIN, 5MIN, 6MIN, 10MIN, 15MIN, 20MIN, 30MIN |
Hour | 1HRS, 2HRS, 3HRS, 4HRS, 6HRS, 8HRS, 12HRS |
Day | 1DAY, 2DAY, 3DAY, 5DAY, 7DAY, 10DAY |
Output variables
Variable | Description |
---|---|
period_id | Period identifier, used in other API calls |
length_seconds | Seconds part of period length |
length_months | Months part of period length |
unit_count | Period length in units |
unit_name | Type of unit (second/minute/hour/day) |
display_name | Display name of period length |
Timeseries data GET
curl https://rest.coinapi.io/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00 \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/exchangerate/BTC/USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00&time_end=2016-02-01T00:00:00")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get the historical exchange rates between two assets in the form of the timeseries.
HTTP Request
GET /v1/exchangerate/{asset_id_base}/{asset_id_quote}/history
URL Parameters
Parameter | Type | Description |
---|---|---|
asset_id_base | string | Requested exchange rates base asset identifier. Full list available here |
asset_id_quote | string | Requested exchange rates base asset identifier. Full list available here |
period_id | string | Identifier of requested timeseries period (required, e.g. 5SEC or 1HRS , full list here) |
time_start | timestring | Timeseries starting time in ISO 8601 (required) |
time_end | timestring | Timeseries ending time in ISO 8601 (required) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
The above command returns JSON structured like this:
[
{
"time_period_start": "2021-03-02T00:00:00.0000000Z",
"time_period_end": "2021-03-02T00:01:00.0000000Z",
"time_open": "2021-03-02T00:00:00.0000000Z",
"time_close": "2021-03-02T00:01:00.0000000Z",
"rate_open": 49642.89075974334,
"rate_high": 49642.89075974334,
"rate_low": 49642.89075974334,
"rate_close": 49642.89075974334
},
{
"time_period_start": "2021-03-02T00:01:00.0000000Z",
"time_period_end": "2021-03-02T00:02:00.0000000Z",
"time_open": "2021-03-02T00:01:00.0000000Z",
"time_close": "2021-03-02T00:02:00.0000000Z",
"rate_open": 49649.71537706716,
"rate_high": 49649.71537706716,
"rate_low": 49649.71537706716,
"rate_close": 49649.71537706716
},
...
{
"time_period_start": "2021-03-02T23:59:00.0000000Z",
"time_period_end": "2021-03-03T00:00:00.0000000Z",
"time_open": "2021-03-02T23:59:00.0000000Z",
"time_close": "2021-03-03T00:00:00.0000000Z",
"rate_open": 48348.04226728628,
"rate_high": 48348.04226728628,
"rate_low": 48348.04226728628,
"rate_close": 48348.04226728628
}
]
Output variables
Variable | Description |
---|---|
time_period_start | Period starting time (range left inclusive) |
time_period_end | Period ending time (range right exclusive) |
time_open | Time of first trade inside period range |
time_close | Time of last trade inside period range |
rate_open | First rate inside period range |
rate_high | Highest rate inside period range |
rate_low | Lowest rate inside period range |
rate_close | Last rate inside period range |
OHLCV
API calls described in this section are related to downloading OHLCV (Open, High, Low, Close, Volume) timeseries data. Each data point of this timeseries represents several indicators calculated from transactions activity inside a time range (period).
List all periods GET
curl https://rest.coinapi.io/v1/ohlcv/periods \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/ohlcv/periods");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/ohlcv/periods');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/ohlcv/periods'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/ohlcv/periods",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/ohlcv/periods")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/ohlcv/periods")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/ohlcv/periods")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get full list of supported time periods available for requesting OHLCV timeseries data.
HTTP Request
GET /v1/ohlcv/periods
The above command returns JSON structured like this:
[
{
"period_id": "1SEC",
"length_seconds": 1,
"length_months": 0,
"unit_count": 1,
"unit_name": "second",
"display_name": "1 Second"
},
{
"period_id": "10DAY",
"length_seconds": 864000,
"length_months": 0,
"unit_count": 10,
"unit_name": "day",
"display_name": "10 Days"
},
{
"period_id": "2YRS",
"length_seconds": 0,
"length_months": 24
"unit_count": 2,
"unit_name": "year",
"display_name": "2 Years"
}
]
Available periods
Time unit | Period identifiers |
---|---|
Second | 1SEC, 2SEC, 3SEC, 4SEC, 5SEC, 6SEC, 10SEC, 15SEC, 20SEC, 30SEC |
Minute | 1MIN, 2MIN, 3MIN, 4MIN, 5MIN, 6MIN, 10MIN, 15MIN, 20MIN, 30MIN |
Hour | 1HRS, 2HRS, 3HRS, 4HRS, 6HRS, 8HRS, 12HRS |
Day | 1DAY, 2DAY, 3DAY, 5DAY, 7DAY, 10DAY |
Month | 1MTH, 2MTH, 3MTH, 4MTH, 6MTH |
Year | 1YRS, 2YRS, 3YRS, 4YRS, 5YRS |
Output variables
Variable | Description |
---|---|
period_id | Period identifier, used in other API calls |
length_seconds | Seconds part of period length |
length_months | Months part of period length |
unit_count | Period length in units |
unit_name | Type of unit (second/minute/hour/day/month/year) |
display_name | Display name of period length |
Latest data GET
curl https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/latest?period_id=1MIN")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"time_period_start": "2017-08-09T14:31:00.0000000Z",
"time_period_end": "2017-08-09T14:32:00.0000000Z",
"time_open": "2017-08-09T14:31:01.0000000Z",
"time_close": "2017-08-09T14:31:46.0000000Z",
"price_open": 3255.590000000,
"price_high": 3255.590000000,
"price_low": 3244.740000000,
"price_close": 3244.740000000,
"volume_traded": 16.903274550,
"trades_count": 31
},
{
"time_period_start": "2017-08-09T14:30:00.0000000Z",
"time_period_end": "2017-08-09T14:31:00.0000000Z",
"time_open": "2017-08-09T14:30:05.0000000Z",
"time_close": "2017-08-09T14:30:35.0000000Z",
"price_open": 3256.000000000,
"price_high": 3256.010000000,
"price_low": 3247.000000000,
"price_close": 3255.600000000,
"volume_traded": 58.131397920,
"trades_count": 33
}
]
Get OHLCV latest timeseries data returned in time descending order.
Data can be requested by the period and for the specific symbol eg BITSTAMP_SPOT_BTC_USD
, if you need to query timeseries by asset pairs eg. BTC/USD
, then please reffer to the Exchange Rates Timeseries data
HTTP Request
GET /v1/ohlcv/{symbol_id}/latest?period_id={period_id}&limit={limit}&include_empty_items={include_empty_items}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier of requested timeseries (full list available here) |
period_id | string | Identifier of requested timeseries period (required, e.g. 5SEC or 2MTH , full list here) |
include_empty_items | bool | Include items with no activity? (optional, default value is false , possible values are true or false ) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
Output variables
Variable | Description |
---|---|
time_period_start | Period starting time (range left inclusive) |
time_period_end | Period ending time (range right exclusive) |
time_open | Time of first trade inside period range |
time_close | Time of last trade inside period range |
price_open | First trade price inside period range |
price_high | Highest traded price inside period range |
price_low | Lowest traded price inside period range |
price_close | Last trade price inside period range |
volume_traded | Cumulative base amount traded inside period range |
trades_count | Amount of trades executed inside period range |
Historical data GET
curl https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00 \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/ohlcv/BITSTAMP_SPOT_BTC_USD/history?period_id=1MIN&time_start=2016-01-01T00:00:00")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"time_period_start": "2017-01-01T00:00:00.0000000Z",
"time_period_end": "2017-01-02T00:00:00.0000000Z",
"time_open": "2017-01-01T00:01:08.0000000Z",
"time_close": "2017-01-01T23:59:46.0000000Z",
"price_open": 966.340000000,
"price_high": 1005.000000000,
"price_low": 960.530000000,
"price_close": 997.750000000,
"volume_traded": 6850.593308590,
"trades_count": 7815
},
{
"time_period_start": "2017-01-02T00:00:00.0000000Z",
"time_period_end": "2017-01-03T00:00:00.0000000Z",
"time_open": "2017-01-02T00:00:05.0000000Z",
"time_close": "2017-01-02T23:59:37.0000000Z",
"price_open": 997.750000000,
"price_high": 1032.000000000,
"price_low": 990.010000000,
"price_close": 1012.540000000,
"volume_traded": 8167.381030180,
"trades_count": 7871
}
]
Get OHLCV timeseries data returned in time ascending order.
Data can be requested by the period and for the specific symbol eg BITSTAMP_SPOT_BTC_USD
, if you need to query timeseries by asset pairs eg. BTC/USD
, then please reffer to the Exchange Rates Timeseries data
HTTP Request
GET /v1/ohlcv/{symbol_id}/history?period_id={period_id}&time_start={time_start}&time_end={time_end}&limit={limit}&include_empty_items={include_empty_items}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier of requested timeseries (full list available here) |
period_id | string | Identifier of requested timeseries period (required, e.g. 5SEC or 2MTH , full list here) |
time_start | timestring | Timeseries starting time in ISO 8601 (required) |
time_end | timestring | Timeseries ending time in ISO 8601 (optional, if not supplied then the data is returned to the end or when count of result elements reaches the limit) |
include_empty_items | bool | Include items with no activity? (optional, default value is false , possible values are true or false ) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
Output variables
Variable | Description |
---|---|
time_period_start | Period starting time (range left inclusive) |
time_period_end | Period ending time (range right exclusive) |
time_open | Time of first trade inside period range |
time_close | Time of last trade inside period range |
price_open | First trade price inside period range |
price_high | Highest traded price inside period range |
price_low | Lowest traded price inside period range |
price_close | Last trade price inside period range |
volume_traded | Cumulative base amount traded inside period range |
trades_count | Amount of trades executed inside period range |
Trades
This section describes calls related to executed transactions data, also known as matched orders data or active data.
JSON structure
Trades related commands return JSON structured like this:
[
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"uuid": "770C7A3B-7258-4441-8182-83740F3E2457",
"price": 770.000000000,
"size": 0.050000000,
"taker_side": "BUY"
},
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T23:12:59.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"uuid": "1EA8ADC5-6459-47CA-ADBF-0C3F8C729BB2",
"price": 770.000000000,
"size": 0.050000000,
"taker_side": "SELL"
}
]
Output variables
Variable | Description |
---|---|
symbol_id | Our symbol identifier, format is documented here |
time_exchange | Time of trade reported by exchange |
time_coinapi | Time when coinapi first received trade from exchange |
uuid | Our trade unique identifier in form of UUIDv4 |
price | Price of the transaction |
size | Base asset amount traded in the transaction (if a value is equal to zero, then transaction price just marking a data point eg. in the index time series) |
taker_side | Aggressor side of the transaction (BUY/SELL/BUY_ESTIMATED/SELL_ESTIMATED/UNKNOWN) |
Possible taker_side
values
If exchange has not reported who was aggressor side of transaction, we will classify who most probably was based on current market view.
taker_side |
Description |
---|---|
BUY |
Exchange has reported that transaction aggressor was buying |
SELL |
Exchange has reported that transaction aggressor was selling |
BUY_ESTIMATED |
Exchange has not reported transaction aggressor, we estimated that more likely it was buying |
SELL_ESTIMATED |
Exchange has not reported transaction aggressor, we estimated that more likely it was selling |
UNKNOWN |
Exchange has not reported transaction aggressor and we have not estimated who it was |
Current data
To get current last trade for all symbols, use Quotes current data as it includes last trade information.
Latest data GET
curl https://rest.coinapi.io/v1/trades/latest \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/trades/latest");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/trades/latest');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/trades/latest'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/trades/latest",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/trades/latest")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/trades/latest")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/trades/latest")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get latest trades executed up to 1 minute ago. Latest data is always returned in time descending order.
HTTP Request
GET /v1/trades/latest?limit={limit}&filter_symbol_id={filter_symbol_id}
GET /v1/trades/{symbol_id}/latest?limit={limit}&include_id={include_id}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier for requested timeseries (full list available here) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
filter_symbol_id | string[] | Comma or semicolon delimited parts of symbol identifier used to filter response. (optional, full list available here) |
include_id | bool | Information that additional exchange trade identifier should be included in the id_trade parameter of the trade if exchange providing identifiers. |
Historical data GET
curl https://rest.coinapi.io/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00 \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/trades/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get history transactions from specific symbol, returned in time ascending order.
HTTP Request
GET /v1/trades/{symbol_id}/history?time_start={time_start}&time_end={time_end}&limit={limit}&include_id={include_id}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier for requested timeseries (full list available here) |
time_start | timestring | Starting time in ISO 8601 (required) |
time_end | timestring | Timeseries ending time in ISO 8601 (optional, if not supplied then the data is returned to the end or when result elements count reaches the limit) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
include_id | bool | Information that additional exchange trade identifier should be included in the id_trade parameter of the trade if exchange providing identifiers. |
Quotes
This section describes calls related to quotes data, also known as quotes or passive level 1 data.
Current data GET
curl https://rest.coinapi.io/v1/quotes/current \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/quotes/current");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/quotes/current');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/quotes/current'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/quotes/current",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/quotes/current")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/quotes/current")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/quotes/current")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124,
"last_trade": {
"time_exchange": "2017-03-18T22:42:21.3763342Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"uuid": "1EA8ADC5-6459-47CA-ADBF-0C3F8C729BB2",
"price": 770.000000000,
"size": 0.050000000,
"taker_side": "SELL"
}
},
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124,
"last_trade": {
"time_exchange": "2017-03-18T22:42:21.3763342Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"uuid": "1EA8ADC5-6459-47CA-ADBF-0C3F8C729BB2",
"price": 770.000000000,
"size": 0.050000000,
"taker_side": "SELL"
}
}
]
Get current quotes for all symbols or for a specific symbol.
HTTP Request
GET /v1/quotes/current?filter_symbol_id={filter_symbol_id}
GET /v1/quotes/{symbol_id}/current
URL Parameters
Parameter | Type | Description |
---|---|---|
filter_symbol_id | string[] | Comma or semicolon delimited parts of symbol identifier used to filter response. (optional, full list available here) |
Output variables
Variable | Description |
---|---|
symbol_id | Our symbol identifier, format documented here |
time_exchange | Exchange time of order book |
time_coinapi | CoinAPI time when order book received from exchange |
ask_price | Best asking price |
ask_size | Volume resting on best ask (if a value is equal to zero then size is unknown) |
bid_price | Best bidding price |
bid_size | Volume resting on best bid (if a value is equal to zero then size is unknown) |
last_trade | Last executed transaction, variables described in trades section |
Latest data GET
curl https://rest.coinapi.io/v1/quotes/latest \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/quotes/latest");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/quotes/latest');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/quotes/latest'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/quotes/latest",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/quotes/latest")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/quotes/latest")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/quotes/latest")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
},
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000",
"time_coinapi": "2017-03-18T22:42:21.3763342",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
}
]
Get latest updates of the quotes up to 1 minute ago. Latest data is always returned in time descending order.
HTTP Request
GET /v1/quotes/latest?limit={limit}&filter_symbol_id={filter_symbol_id}
GET /v1/quotes/{symbol_id}/latest?limit={limit}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier of requested timeseries (full list available here) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
filter_symbol_id | string[] | Comma or semicolon delimited parts of symbol identifier used to filter response. (optional, full list available here) |
Output variables
Variable | Description |
---|---|
symbol_id | Our symbol identifier, format documented here. |
time_exchange | Exchange time of order book |
time_coinapi | CoinAPI time when order book received from exchange |
ask_price | Best asking price |
ask_size | Volume resting on best ask (if a value is equal to zero then size is unknown) |
bid_price | Best bidding price |
bid_size | Volume resting on best bid (if a value is equal to zero then size is unknown) |
Historical data GET
curl https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00 \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/quotes/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
The above command returns JSON structured like this:
[
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
},
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000",
"time_coinapi": "2017-03-18T22:42:21.3763342",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
}
]
Get historical quote updates within requested time range, returned in time ascending order.
HTTP Request
GET /v1/quotes/{symbol_id}/history?time_start={time_start}&time_end={time_end}&limit={limit}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier for requested timeseries (full list available here) |
time_start | timestring | Starting time in ISO 8601 (required) |
time_end | timestring | Timeseries ending time in ISO 8601 (optional, if not supplied then the data is returned to the end or when result elements count reaches the limit) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
Output variables
Variable | Description |
---|---|
symbol_id | Our symbol identifier, format documented here. |
time_exchange | Exchange time of order book |
time_coinapi | CoinAPI time when order book received from exchange |
ask_price | Best asking price |
ask_size | Volume resting on best ask (if a value is equal to zero then size is unknown) |
bid_price | Best bidding price |
bid_size | Volume resting on best bid (if a value is equal to zero then size is unknown) |
Order book
This section describes calls related to order book data, also known as books or passive level 2 data.
JSON structure
Order book related commands return JSON structured like this:
[
{
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
]
Output variables
Variable | Description |
---|---|
symbol_id | Our symbol identifier, format documented here. |
time_exchange | Exchange time of order book |
time_coinapi | CoinAPI time when order book received from exchange |
asks | Best 20 ask levels in order from best to worst |
bids | Best 20 bid levels in order from best to worst |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Current data GET
curl https://rest.coinapi.io/v1/orderbooks/current \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/orderbooks/current");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/orderbooks/current');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/orderbooks/current'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/orderbooks/current",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/orderbooks/current")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/orderbooks/current")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/orderbooks/current")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get current order book snapshot for all or a specific symbol.
HTTP Request
GET /v1/orderbooks/current?filter_symbol_id={filter_symbol_id}&limit_levels={limit_levels}
GET /v1/orderbooks/{symbol_id}/current?limit_levels={limit_levels}
URL Parameters
Parameter | Type | Description |
---|---|---|
filter_symbol_id | string[] | Comma or semicolon delimited parts of symbol identifier used to filter response. (optional, full list available here) |
limit_levels | int | Maximum amount of levels from each side of the book to include in response (optional) |
Latest data GET
curl https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/latest")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get latest order book snapshots for a specific symbol, returned in time descending order.
HTTP Request
GET /v1/orderbooks/{symbol_id}/latest?limit={limit}&limit_levels={limit_levels}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier of requested timeseries (full list available here) |
limit_levels | int | Maximum amount of levels from each side of the book to include in response (optional) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
Historical data GET
curl https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00 \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/orderbooks/BITSTAMP_SPOT_BTC_USD/history?time_start=2016-01-01T00:00:00")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get historical order book snapshots for a specific symbol within time range, returned in time ascending order.
HTTP Request
GET /v1/orderbooks/{symbol_id}/history?time_start={time_start}&time_end={time_end}&limit={limit}&limit_levels={limit_levels}
URL Parameters
Parameter | Type | Description |
---|---|---|
symbol_id | string | Symbol identifier for requested timeseries (full list available here) |
time_start | timestring | Starting time in ISO 8601 (required) |
time_end | timestring | Timeseries ending time in ISO 8601 (optional, if not supplied then the data is returned to the end or when result elements count reaches the limit) |
limit_levels | int | Maximum amount of levels from each side of the book to include in response (optional) |
limit | int | Amount of items to return (optional, mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) |
Order book L3
This section describes calls related to order book data, also known as books or passive level 3 data.
JSON structure
Order book L3 related commands return JSON structured like this:
[
{
"symbol_id": "COINBASE_SPOT_BCH_USD",
"time_exchange": "2020-08-27T10:28:35.6111130Z",
"time_coinapi": "2020-08-27T10:28:35.6766461Z",
"asks": [
{
"id": "3c5e789c-4c84-448a-9c5d-50532ea1ccbb",
"price": 272.89,
"size": 1
},
{
"id": "c64a76ba-5107-4c1b-b788-271ee88df318",
"price": 272.9,
"size": 18
},
... cut ...
],
"bids": [
{
"id": "100d5004-f4e0-4e92-a571-392403d5b073",
"price": 272.83,
"size": 18
},
{
"id": "0889cf06-4a9d-4519-98e6-fac5dcb7afbf",
"price": 272.83,
"size": 0.64185083
},
... cut ...
]
}
]
Output variables
Variable | Description |
---|---|
symbol_id | Our symbol identifier, format documented here. |
time_exchange | Exchange time of order book |
time_coinapi | CoinAPI time when order book received from exchange |
asks | All asks made by market makers |
bids | All bids made by market makers |
id | Order identifier |
price | Price of bid/ask |
size | Bid/ask base asset amount |
Current data GET
curl https://rest.coinapi.io/v1/orderbooks3/current \
--request GET
--header "X-CoinAPI-Key: 73034021-THIS-IS-SAMPLE-KEY"
var client = new RestClient("https://rest.coinapi.io/v1/orderbooks3/current");
var request = new RestRequest(Method.GET);
request.AddHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY");
IRestResponse response = client.Execute(request);
<?php
$request = new HttpRequest();
$request->setUrl('https://rest.coinapi.io/v1/orderbooks3/current');
$request->setMethod(HTTP_METH_GET);
$request->setHeaders(array(
'X-CoinAPI-Key' => '73034021-THIS-IS-SAMPLE-KEY'
));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
?>
import requests
url = 'https://rest.coinapi.io/v1/orderbooks3/current'
headers = {'X-CoinAPI-Key' : '73034021-THIS-IS-SAMPLE-KEY'}
response = requests.get(url, headers=headers)
const https = require('https');
var options = {
"method": "GET",
"hostname": "rest.coinapi.io",
"path": "/v1/orderbooks3/current",
"headers": {'X-CoinAPI-Key': '73034021-THIS-IS-SAMPLE-KEY'}
};
var request = https.request(options, function (response) {
var chunks = [];
response.on("data", function (chunk) {
chunks.push(chunk);
});
});
request.end();
import (
"gopkg.in/resty.v0"
)
func main()
{
resp, err := resty.R().
SetHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEY").
Get("https://rest.coinapi.io/v1/orderbooks3/current")
}
require 'uri'
require 'net/http'
url = URI("https://rest.coinapi.io/v1/orderbooks3/current")
http = Net::HTTP.new(url.host, url.port)
request = Net::HTTP::Get.new(url)
request["X-CoinAPI-Key"] = '73034021-THIS-IS-SAMPLE-KEY'
response = http.request(request)
puts response.read_body
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://rest.coinapi.io/v1/orderbooks3/current")
.post(body)
.addHeader("X-CoinAPI-Key", "73034021-THIS-IS-SAMPLE-KEYs")
.build();
Response response = client.newCall(request).execute();
Get current order book snapshot for all or a specific symbol.
HTTP Request
GET /v1/orderbooks3/current?filter_symbol_id={filter_symbol_id}&limit_levels={limit_levels}
GET /v1/orderbooks3/{symbol_id}/current?limit_levels={limit_levels}
URL Parameters
Parameter | Type | Description |
---|---|---|
filter_symbol_id | string[] | Comma or semicolon delimited parts of symbol identifier used to filter response. (optional, full list available here) |
limit_levels | int | Maximum amount of levels from each side of the book to include in response (optional) |
Market Data - WebSocket API
WebSocket endpoint provides real-time market data streaming which works in Subscribe-Publish communication model.
After establishing a WebSocket connection with us, you will need to send a Hello message documented below.
If everything is correct, we will provide you with a continuous stream of real-time market data updates.
Implemented Standards:
Endpoints
Enviroment | Encryption | Value |
---|---|---|
Production | Yes | wss://ws.coinapi.io/v1/ |
Production | No | ws://ws.coinapi.io/v1/ |
Sandbox | Yes | wss://ws-sandbox.coinapi.io/v1/ |
Sandbox | No | ws://ws-sandbox.coinapi.io/v1/ |
For testing, debugging and development purposes we are recommending:
wscat
client from thenpm
package repository: https://github.com/websockets/wscatsandy
standalone WebSocket client with our message templates available at: https://app.gosandy.io/?url=https://raw.githubusercontent.com/coinapi/coinapi-sdk/master/data-api/sandy-ws-v1.json&u=Ar
Sandbox
The sandbox environment is provided for development and non-production use-cases, it has few differences in comparison to the production one:
- You still need active API Key to access the sandbox; it can be a free one.
- We do not provide any support or SLA for this environment.
- Real-time and historical data is limited to specific data sources: COINBASE, GEMINI, testnets, UAT environments and ECB (European Central Bank).
- Data could be invalid/fake or delayed.
- API changes could be visible faster on the sandbox than in the production environment.
General
Hello OUT
Example hello message for trades subscription to all symbols from
COINBASE
andITBIT
exchange and additional for 2 selected symbols fromBITSTAMP
andBITFINEX
exchange:
{
"type": "hello",
"apikey": "73034021-THIS-IS-SAMPLE-KEY",
"heartbeat": false,
"subscribe_data_type": ["trade"],
"subscribe_filter_symbol_id": [
"BITSTAMP_SPOT_BTC_USD$",
"BITFINEX_SPOT_BTC_LTC$",
"COINBASE_",
"ITBIT_"
]
}
Another example of a hello message for subscription to quotes related to the BTC or ETH assets:
{
"type": "hello",
"apikey": "73034021-THIS-IS-SAMPLE-KEY",
"heartbeat": false,
"subscribe_data_type": ["quote"],
"subscribe_filter_asset_id": ["BTC", "ETH"]
}
Another example of a hello message for subscription to quotes related to the BTC/USD asset pair:
{
"type": "hello",
"apikey": "73034021-THIS-IS-SAMPLE-KEY",
"heartbeat": false,
"subscribe_data_type": ["quote"],
"subscribe_filter_asset_id": ["BTC/USD"]
}
Another example of a hello message for subscription of all data types from all exchanges and symbols:
{
"type": "hello",
"apikey": "73034021-THIS-IS-SAMPLE-KEY",
"heartbeat": false,
"subscribe_data_type": ["trade", "quote", "book20"]
}
After your WebSocket connection is established, you must send us a Hello message which contains:
- Stream preferences (Heartbeat and subscription details)
- API key for authorization
If your message will be incorrect, we will send you error message and disconnect connection afterwards.
Hello message can be repeated, each one will cause subscription scope override without interruption of your WebSocket connection.
Hello message parameters
Parameter | Type | Description |
---|---|---|
type | string | Message type, must be equal to hello |
apikey | string | Your API key |
heartbeat | bool | true to receive Heartbeat message every second, otherwise false |
subscribe_data_type | string[] | List of data types you want to receive (required, possible values listed in table below) |
subscribe_filter_symbol_id | string[] | Filter data to symbols whose identifiers match at least one of the listed prefixes. If symbol is ended with $ character then exact match is used instead of prefix match. (optional, if not provided then stream will not filtered by symbols) |
subscribe_filter_asset_id | string[] | Filter data to messages which are related to the at least one of the listed asset identifiers or to specific asset pair (e.g. BTC/USD) (optional, if not provided then stream will not be filtered by assets) |
subscribe_filter_period_id | string[] | Filter data to specific OHLCV periods (optional, if not provided then OHLCV stream will not be filtered by periods) |
subscribe_filter_exchange_id | string[] | Filter data to symbols from the listed exchange identifiers (optional, if not provided then stream will not be filtered by exchanges) |
subscribe_update_limit_ms_quote | int | Minimum delay in milliseconds between quote updates for the same symbol (optional) |
subscribe_update_limit_ms_book_snapshot | int | Minumum delay in milliseconds between book snapshot (book5, book20, book50) updates for the same symbol (optional) |
subscribe_update_limit_ms_exrate | int | Minumum delay in milliseconds between exchange rate updates for the same asset pair (optional) |
Data types
Listed below are all allowed values for subscribe_data_type
variables from hello message.
Data type | Description |
---|---|
trade |
Executed transactions feed (order book matches) |
quote |
Quote updates feed (order book level 1) |
book |
Order book snapshots and updates feed (order book level 2, full order book snapshot and real-time updates) |
book5 |
Order book snapshots feed (order book level 2, 5 best levels from each side of book) |
book20 |
Order book snapshots feed (order book level 2, 20 best levels from each side of book) |
book50 |
Order book snapshots feed (order book level 2, 50 best levels from each side of book) |
ohlcv |
OHLCV updates per symbol on periods between 1SEC and 1MIN |
volume |
Volume updates per symbol on periods 1HRS, 1DAY and 1MTH |
exrate |
Exchange rate updates (VWAP-24H) |
Error handling
Example JSON error message is structured like this:
{
"type": "error",
"message": "Invalid API key"
}
You need to be prepared to receive an error message from us when you send something wrong; all errors are permanent and you should expect that the underlying WebSocket connection will be closed by us after sending an error message.
Limits
API access is subject to limits and n this section we will describe each limit.
Request limit / IP
X-WsRequestsPerIpLimit-Limit: 10
X-WsRequestsPerIpLimit-WindowSizeMs: 10000
X-WsRequestsPerIpLimit-Remaining: 0
X-WsRequestsPerIpLimit-RetryAfterMs: 564
We define WebSocket request as the event when the WebSocket upgrade on the HTTP is happening. The request limit restricts the number of maximum allowed newly initiated WebSocket connections per IP address in a time interval (sliding/rolling window ending at a specific moment) for your subscription. Limit prevents your client application from abusing the API by reconnecting in the loop without exponential backoff.
HTTP Header | Type | Description |
---|---|---|
X-WsRequestsPerIpLimit-Limit | int | Value of the limit quota allocated. |
X-WsRequestsPerIpLimit-Remaining | int | Value of the limit quota left at the moment, counted from last WindowSizeMs milliseconds. |
X-WsRequestsPerIpLimit-WindowSizeMs | int | Window size on which the remaining value was calculated in milliseconds. |
X-WsRequestsPerIpLimit-RetryAfterMs | int | The number of milliseconds after which Remaining > 0. (exist only in case of the error) |
Hello limit / IP
X-WsHelloPerIpLimit-Limit: 10
X-WsHelloPerIpLimit-WindowSizeMs: 10000
X-WsHelloPerIpLimit-Remaining: 0
X-WsHelloPerIpLimit-RetryAfterMs: 564
The hello limit restricts the number of maximum allowed hello messages per IP address in the time interval (sliding/rolling window ending at a specific moment) for your subscription. Limit prevents your client application from abusing the API by changing the scope of the subscription.
HTTP Header | Type | Description |
---|---|---|
X-WsHelloPerIpLimit-Limit | int | Value of the limit quota allocated. |
X-WsHelloPerIpLimit-Remaining | int | Value of the limit quota left at the moment, counted from last WindowSizeMs milliseconds. |
X-WsHelloPerIpLimit-WindowSizeMs | int | Window size on which the remaining value was calculated in milliseconds. |
X-WsHelloPerIpLimit-RetryAfterMs | int | The number of milliseconds after which Remaining > 0. (exist only in case of the error) |
Concurrency limit / APIKey
X-ConcurrencyLimit-Limit: 10
X-ConcurrencyLimit-Remaining: 5
The concurrency limit defines the number of maximum allowed concurrent websocket connections per APIKey at the current moment. Every new WebSocket connection increases the Concurrency limit against quota, and when it's closed, decreases it.
HTTP Header | Type | Description |
---|---|---|
X-ConcurrencyLimit-Limit | int | Concurrency limit allocated for your API key. |
X-ConcurrencyLimit-Remaining | int | The number of concurrent WebSocket connections available to be established in this moment for your API key. |
Data buffering
Data buffering JSON error message is structured like this:
{
"type": "error",
"message": "Reached maximum allowed buffered messages for this connection."
}
The stream will send the data to the client as fast as possible; this can result in a high volume of data in cases where the subscription scope is broad. If our server cannot write data to the stream because of the TCP backpressure most likely caused by your client is not reading the data fast enough, or there is not enough network bandwidth available, we will buffer the messages to allow your client to catch up. However, when the buffer is full, a disconnect will be initiated from the server-side, and the buffered messages are dropped, and they will not be resent to the client.
One way to identify when your client is falling behind is to compare the CoinAPI time of the messages being received with your current time on the client and track this metric over time. Make sure your clock is synchronized correctly and do not have a drift.
The possible causes of the buffering are limited and are related to:
- Bandwidth bottleneck, eg.
- Internet connection instability
- Not enough bandwidth to receive a full stream.
- Network card or link saturation.
- I am not receiving messages fast enough, eg.
- Lack of the thread separation between the (a) receiving thread or (b) parsing or (c) processing operations.
- No CPU affinity on the receiving thread.
- CPU bottleneck on the receiving thread.
- Infrequent collection of the data from the TCP stack.
- Heap allocation per message and Garbage Collector pressure.
If your client is unable to receive messages fast enough because of the issues listed above, then these things will happen:
- Your client TCP stack will be full, and TCP window will be closed to inform us that you can't receive more data and we should not send to you
- Our TCP stack queue will be full because we couldn't send you more data
- We will internally create a limited queue of the messages to deliver when the channel is available again (this could cause the delay on the real-time data before the gaps will appear)
- If the queue is full, then we will disconnect you.
To minimize the occurrence of disconnects:
- Make sure that your client is reading the stream fast enough. Typically you should not do any real processing work as you read the stream. Read the stream and hand the activity to another thread/process/data store to do your processing asynchronously.
- Make sure that your data center has inbound bandwidth sufficient to accomodate large sustained data volumes as well as significantly larger spikes (e.g. 10x normal volume).
The current default queue size per connection is 131 072
messages.
For more information please google: TCP Flow Control
.
Messages
Trades IN
Trade message JSON is structured like this:
{
"type": "trade",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"uuid": "770C7A3B-7258-4441-8182-83740F3E2457",
"price": 770.000000000,
"size": 0.050000000,
"taker_side": "BUY"
}
Trade message is sent for every executed transaction (orderbook match).
Message variables
Variable | Description |
---|---|
type | Message type, always trade |
symbol_id | Our symbol identifier, format documented here |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Time of trade reported by exchange |
time_coinapi | Time when coinapi first received trade from exchange |
uuid | Our unique trade identifier in form of UUIDv4 |
price | Price of the transaction |
size | Base asset amount traded in transaction (if a value is equal to zero, then transaction price just marking a data point eg. in the index time series) |
taker_side | Aggressor side of the transaction (BUY/SELL/BUY_ESTIMATED/SELL_ESTIMATED/UNKNOWN) |
Possible taker_side
values
If exchange has not reported who the aggressor side of the transaction was, then we will classify who it most probably was based on current market view.
taker_side |
Description |
---|---|
BUY |
Exchange has reported that transaction aggressor was buying |
SELL |
Exchange has reported that transaction aggressor was selling |
BUY_ESTIMATED |
Exchange has not reported transaction aggressor, we estimated that more likely it was buying |
SELL_ESTIMATED |
Exchange has not reported transaction aggressor, we estimated that more likely it was selling |
UNKNOWN |
Exchange has not reported transaction aggressor and we have not estimated who it was |
Quotes IN
Quote message JSON is structured like this:
{
"type": "quote",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"ask_price": 770.000000000,
"ask_size": 3252,
"bid_price": 760,
"bid_size": 124
}
Quote message is sent for each update on orderbook first best bid or ask level.
Message variables
Variable | Description |
---|---|
type | Message type, always quote |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
ask_price | Best asking price |
ask_size | Volume resting on best ask (if a value is equal to zero then size is unknown) |
bid_price | Best bidding price |
bid_size | Volume resting on best bid (if a value is equal to zero then size is unknown) |
Orderbook L2 (Full) IN
A Book message is sent for each snapshot or update of the order book. After subscription to this data type is initialized, we immediately start delivering updates to the order book and at least one snapshot will be provided as soon as possible with the nearest update of the book. Book message represents total ammount of bids and asks aggregated by price level.
{
"type": "book",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"is_snapshot": true,
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
is_snapshot | Is message a snapshot? If true then all bid and ask levels are listed, otherwise only changed since the last message. |
asks | All ask levels for snapshot message, otherwise only changed ask levels since the last message. Data will be in order from the best to the worst price. |
bids | All bid levels for snapshot message, otherwise only changed bid levels since the last message. Data will be in order from the best to the worst price. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L2 (max 2x5) IN
A Book5 message contain first 5 best bid or ask levels.
{
"type": "book5",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book5 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
asks | Best 5 ask levels in order from best to worst. |
bids | Best 5 bid levels in order from best to worst. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L2 (max 2x20) IN
A Book20 message contain first 20 best bid or ask levels.
{
"type": "book20",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book20 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
asks | Best 20 ask levels in order from best to worst. |
bids | Best 20 bid levels in order from best to worst. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L2 (max 2x50) IN
A Book50 message contain first 50 best bid or ask levels.
{
"type": "book50",
"symbol_id": "BITSTAMP_SPOT_BTC_USD",
"sequence": 2323346,
"time_exchange": "2013-09-28T22:40:50.0000000Z",
"time_coinapi": "2017-03-18T22:42:21.3763342Z",
"asks": [
{
"price": 456.35,
"size": 123
},
{
"price": 456.36,
"size": 23
},
... cut ...
],
"bids": [
{
"price": 456.10,
"size": 42
},
{
"price": 456.09,
"size": 5
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book50 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
asks | Best 50 ask levels in order from best to worst. |
bids | Best 50 bid levels in order from best to worst. |
price | Price of bid/ask |
size | Volume resting on bid/ask level in base amount |
Orderbook L3 (Full) IN
A book_l3
message is sent for each snapshot or update of the order book in the level 3 format (order-by-order).
After subscription to this data type is initialized, we immediately start delivering updates to the order book and at least one snapshot will be provided as soon as possible with the nearest update of the book.
Book L3 does not aggregate any data. Every ask and bid corresponds to passive order with information on the price and size of that order. The id can identify any order.
{
"type": "book_l3"
"symbol_id": "COINBASE_SPOT_BCH_USD",
"sequence": 2323346,
"time_exchange": "2020-08-26T12:36:04.3464706Z",
"time_coinapi": "2020-08-26T12:36:04.2807750Z",
"is_snapshot": false,
"asks": [
{
"id": "520269d4-c085-47ed-8825-6d787af90800",
"price": 273.01,
"size": 1.81940502,
"update_type":"ADD"
},
{
"id": "0ac891c7-8360-462c-8d9a-d8b217d3fca2",
"price": 273.02,
"size": 1.0,
"update_type":"DELETE"
},
... cut ...
],
"bids": [
{
"id": "6340ec1e-8be8-404e-b9a4-a14120ec179e",
"price": 272.94,
"size": 1.81940502,
"update_type":"UPDATE"
},
{
"id": "7eaaa899-089f-4308-9fa2-e33737ae36ee",
"price": 272.96,
"size": 1.85989855,
"update_type":"DELETE"
},
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always book_l3 |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
time_exchange | Exchange time of orderbook |
time_coinapi | CoinAPI time when orderbook received from exchange |
is_snapshot | Is message a snapshot? If true then all bid and ask levels are listed, otherwise only changed since the last message |
asks | All ask levels for snapshot message, otherwise only changed ask levels since the last message. Data will be in order from the best to the worst price. |
bids | All bid levels for snapshot message, otherwise only changed bid levels since the last message. Data will be in order from the best to the worst price. |
id | Order identifier |
price | Price of bid/ask |
size | Bid/ask base asset amount |
update_type | Type of update message |
Possible update_type
values
The snapshot message represents the initial collection of the orders in the order book. Further updates are modifying this collection.
update_type
determines the type of update for the order.
Please note that the snapshot message has no defined update_type
.
update_type |
Description |
---|---|
ADD |
Add order to the price queue. |
UPDATE |
Update the order size in the price queue. |
SUBTRACT |
Subtract the order size in the price queue. |
DELETE |
Delete the order from the price queue. |
MATCH |
Subtract the order size in the price queue (same as SUBTRACT but caused by the match). |
OHLCV IN
A OHLCV message is sent on the between 1SEC and 1DAY. We are sending message when the ohlcv period is closed (we saw timestamp belonging to the new period) or every 5 seconds if ohlcv period was updated but not yet closed.
{
"type": "ohlcv",
"symbol_id": "BITSTAMP_SPOT_XRP_USD",
"sequence": 511,
"time_period_start": "2019-06-11T15:26:00.0000000Z",
"time_period_end": "2019-06-11T15:27:00.0000000Z",
"time_open": "2019-06-11T15:26:07.0000000Z",
"time_close": "2019-06-11T15:26:36.0000000Z",
"price_open": 0.3865,
"price_high": 0.38706,
"price_low": 0.3865,
"price_close": 0.38706,
"volume_traded": 1500.31419084,
"trades_count": 5
}
Message variables
Variable | Description |
---|---|
type | Message type, always ohlcv |
symbol_id | Our symbol identifier, format documented here. |
sequence | Sequence number per pair (type , symbol_id ) which is valid only for the lifespan of the connection. |
period_id | Identifier of timeseries period full list here |
time_period_start | Period starting time (range left inclusive) |
time_period_end | Period ending time (range right exclusive) |
time_open | Time of first trade inside period range |
time_close | Time of last trade inside period range |
price_open | First trade price inside period range |
price_high | Highest traded price inside period range |
price_low | Lowest traded price inside period range |
price_close | Last trade price inside period range |
volume_traded | Cumulative base amount traded inside period range |
trades_count | Amount of trades executed inside period range |
Volume IN
A Volume message is sent periodically to update last volume information per symbols on periods 1HRS, 1DAY and 1MTH. The 1HRS and 1DAY volumes are updated every minute and 1MTH every 10 minutes. Subscription to this message type triggers redelivery of the last published messages for each period.
{
"type": "volume",
"period_id": "1HRS",
"time_coinapi": "2019-06-11T15:26:00.0000000Z",
"volume_by_symbol":
[
{
"symbol_id": "IDCM_SPOT_BAT_BTC",
"asset_id_base": "BAT",
"asset_id_quote": "BTC",
"volume_base": 663798.780000000,
"volume_quote": 27.567563333400000000
},
{
"symbol_id": "BITFOREX_SPOT_DREP_USDT",
"asset_id_base": "DREP",
"asset_id_quote": "USDT",
"volume_base": 2858275.288400000,
"volume_quote": 8366.171769146800000000
}
... cut ...
]
}
Message variables
Variable | Description |
---|---|
type | Message type, always volume |
period_id | Identifier of timeseries period full list here |
time_coinapi | CoinAPI time of the message generation |
symbol_id | Our symbol identifier, format documented here. |
asset_id_base | Base asset identifier (full list available here) |
asset_id_quote | Quote asset identifier (full list available here) |
volume_base | Last volume from period_id of the symbol_id denominated in asset_id_base asset. |
volume_quote | Last volume from period_id of the symbol_id denominated in asset_id_quote asset. |
Exchange Rate IN
Exchange rate is defined as (VWAP-24H) last 24 hour (rolling window over time) Volume Weighted Average Price across multiple data sources listed on our platform. We are selecting and managing the data sources that are used in the calculation based on multiple factors to provide data of highest quality.
{
"type": "exrate",
"asset_id_base": "BTC",
"asset_id_quote": "USD",
"time": "2019-06-11T15:26:00.0000000Z"
"rate": 10065.0319541
}
Message variables
Variable | Description |
---|---|
type | Message type, always exrate |
asset_id_base | Base asset identifier. Full list available here |
asset_id_quote | Quote asset identifier. Always USD . |
time | Time of the exchange rate |
rate | Exchange rate between pair of assets. |
Reconnect IN
Reconnect message is sent by the server to all connected clients when the server will be restarted or shut down at the defined exact time included in the message content. After the period specified in message passes, the client must expect that the underlying WebSocket connection will be closed from the server-side. A new connection will automatically be established to a different server.
The correct way of handling this event depends on the specific requirements of the integration, but we can define standard ways how to handle it:
- Wait for the connection to be closed and reconnect
- Reconnect immediately after receiving the message
- Upon receiving the message, establish a second connection, and subscribe to the same scope of data. When the first connection is disconnected, do not reconnect it and instead transparently switch the data streams between connections. This method requires more implementation as a transparent switch of the data stream must not break the sequence for streams published using the initial snapshot and update messages. To make sure the sequence is correct, the client must: (a) maintain a state by applying updates to snapshot or (b) buffer the data from the second connection and processing it at the transparent connection switch.
Example JSON reconnect message is structured like this:
{
"type": "reconnect"
"within_seconds": 10,
"before_time": "2020-08-06T19:19:09.7035429Z",
}
Message variables
Variable | Description |
---|---|
type | Message type, always reconnect |
within_seconds | Seconds within which reconnection should be performed. |
before_time | Time before which reconnection should be performed. |
Heartbeat IN
Heartbeat message JSON is structured like this:
{
"type": "hearbeat"
}
Heartbeat message is sent to you every time there is one second of silence in communication between us, if you agreed on this feature in Hello message.
Market Data - FIX API
Financial Information eXchange (FIX) protocol is an electronic communications protocol initiated in 1992 for international real-time exchange of information related to the securities transactions and markets. You can use it to receive real-time market data from us and it's an alternative to WebSocket protocol.
Implemented Standards:
Endpoints
FIX client configuration file for encrypted connection:
[DEFAULT]
ConnectionType=initiator
ReconnectInterval=2
FileStorePath=store
FileLogPath=log
StartTime=00:00:00
EndTime=00:00:00
NonStopSession=Y
UseDataDictionary=Y
ValidateFieldsOutOfOrder=N
DataDictionary=FIX44.xml
SocketConnectHost=fix.coinapi.io
SocketConnectPort=3302
SSLEnable=Y
SSLServerName=fix.coinapi.io
SSLValidateCertificates=Y
SSLCheckCertificateRevocation=Y
LogoutTimeout=5
ResetOnLogon=Y
[SESSION]
BeginString=FIX.4.4
SenderCompID=YOUR_API_KEY
TargetCompID=COINAPI_V2
HeartBtInt=10
FIX client configuration file for unencrypted connection:
[DEFAULT]
ConnectionType=initiator
ReconnectInterval=2
FileStorePath=store
FileLogPath=log
StartTime=00:00:00
EndTime=00:00:00
NonStopSession=Y
UseDataDictionary=Y
ValidateFieldsOutOfOrder=N
DataDictionary=FIX44.xml
SocketConnectHost=fix.coinapi.io
SocketConnectPort=3303
SSLEnable=N
LogoutTimeout=5
ResetOnLogon=Y
[SESSION]
BeginString=FIX.4.4
SenderCompID=YOUR_API_KEY
TargetCompID=COINAPI_V2
HeartBtInt=10
Our sandbox endpoint configuration parameters:
Parameter | Value |
---|---|
Hostname | fix-sandbox.coinapi.io |
Port Unencrypted | 3302 |
Protocol version | FIX.4.4 (XML FIX Specification can be downloaded here: FIX44.xml) |
Gateway timezone | UTC |
Our production endpoint configuration parameters:
Parameter | Value |
---|---|
Hostname | fix.coinapi.io |
Port Unecnrypted | 3302 |
Port TLS | 3303 |
Protocol version | FIX.4.4 (XML FIX Specification can be downloaded here: FIX44.xml) |
Gateway timezone | UTC |
We recommend using our SDK or listed client libraries depending on your language requirements:
Sandbox
The sandbox environment is provided for development and non-production use-cases, it has few differences in comparison to the production one:
- You still need active paid API Key to access FIX sandbox; it can be any paid plan.
- We do not provide any support or SLA for this environment.
- Real-time and historical data is limited to specific data sources: COINBASE, GEMINI, testnets, UAT environments and ECB (European Central Bank).
- Data could be invalid/fake or delayed.
- API changes could be visible faster on the sandbox than in the production environment.
Security
Stunnel configuation:
[COINAPI]
client = yes
accept = 3301
connect = fix.coinapi.io:3302
verify = 2
Communication with our FIX gateway is secured by TLS protocol if you are using the encrypted port. If your FIX protocol implementation does not support establishing a connection over a secure channel, you must use a proxy between your client and our FIX gateway to unbundle encryption or use unencrypted port. We recommend stunnel as a proxy if a secure connection can't be established directly from your client and you can't allow the unencrypted traffic.
oneZero Hub
Our FIX Connector is passing oneZero Conformance Tests. If you need establish session using the FIX with your company oneZero Hub, please contact our support at CoinAPI Support.
Messages
All FIX messages are equipped with Standard Header and Trailer, below we will describe what is required in them in accordance with FIX 4.4, the standard that we use.
Standard Header
Tag | Name | Description |
---|---|---|
8 | BeginString | FIX.4.4 |
9 | BodyLength | Message length, in bytes, forward to the CheckSum <10> field |
35 | MsgType | Defines message type |
49 | SenderCompID | Assigned value used to identify message sender |
56 | TargetCompID | Assigned value used to identify message receiver |
34 | MsgSeqNum | Integer message sequence number. Reset on Logon, Logout and Disconnect. |
52 | SendingTime | Time of message transmission always expressed in UTC (Universal Time Coordinated, also known as "GMT") |
Standard Trailer
Tag | Name | Description |
---|---|---|
10 | CheckSum | Three byte, simple checksum. Always the last field in a message, i.e. serves, with the trailing |
Logon 35=A
8=FIX.4.4|9=97|35=A|34=1|49=COINAPI|52=20170503-22:00:56.743|56=73034021-THIS-IS-SAMPLE-KEY|98=0|108=1|10=245|
First message sent by the client to CoinAPI FIX Gateway after connection to initiate a FIX session. After successful authorization, server will respond with same message type and start delivering market data messages to you.
Tag | Name | Description |
---|---|---|
49 | SenderCompID | Your API key |
56 | TargetCompID | COINAPI_V2 |
108 | HeartBtInt | 1 (seconds) |
98 | EncryptMethod | 0 |
Logout 35x5
Message sent by any side to close established session. If received, should be sent back unchanged to confirm session termination.
Security List Request 35=x
Security List Request message is used to request full symbol list or narrowed to specific criteria.
Message to request all symbols:
Tag | Name | Description |
---|---|---|
320 | SecurityReqID | Unique ID of your request, used to link Security List (y) message to the request. |
559 | SecurityListRequestType | 4 = Request all symbols. |
Message to request all symbols where our symbol identifier starts with specific string eg. all securities from BITSTAMP exchange to USD.
Tag | Name | Description |
---|---|---|
320 | SecurityReqID | Unique ID of your request, used to link Security List (y) message to the request. |
559 | SecurityListRequestType | 0 = Filter symbols by Symbol (55) or SecurityExchange (207) fields. |
55 | Symbol | Exact match or regex for the symbol identifier filtering, eg. ^BITSTAMP_(.*)_USD$ or BITSTAMP_SPOT_BTC_USD , have in mind that regex is enabled only if value string starts with ^ or/and ends with $ . |
Message to request all symbols from specific exchange eg. GEMINI.
Tag | Name | Description |
---|---|---|
320 | SecurityReqID | Unique ID of your request, used to link Security List (y) message to the request. |
559 | SecurityListRequestType | 0 = Filter symbols by Symbol (55) or SecurityExchange (207) fields. |
207 | SecurityExchange | Exchange identifier used to filter the symbols |
Security List 35=y
Response to the Security List Request (x) message.
Tag | Name | Description |
---|---|---|
320 | SecurityReqID | SecurityReqID (320) from Security List Request (x) message. |
322 | SecurityResponseID | Unique ID of the response message. |
560 | SecurityRequestResult | Result of the Security List Request. Valid values:
|
393 | TotNoRelatedSym | Total number of symbols in the response. |
898 | LastFragment | Indicates if this is a last message |
146 | NoRelatedSym | Specifies the number of repeating symbols (instruments) specified. |
=> 55 | Symbol | Our Symbol identifier (full list available here) |
=> 207 | SecurityExchange | Our exchange identifier, eg. BITSTAMP . (full list available here) |
Market Data Request 35=V
Market Data Request (V) message is used to request market data.
Tag | Name | Description |
---|---|---|
262 | MDReqId | Must be unique, or the ID of previous Market Data Request (V) to disable if SubscriptionRequestType (263) = Disable previous Snapshot + Updates Request. |
263 | SubscriptionRequestType | SubcriptionRequestType indicates what type of response is expected. A snapshot request only asks for current information. A subscribe request asks for updates as the status changes. Unsubscribe will cancel any future update messages. Valid values:
|
264 | MarketDepth | Depth of market for Book Snapshot, value ignored for trades. Valid values:
|
265 | MDUpdateType | Required if SubscriptionRequestType (263) = Snapshot + Updates (1) and apply only for the orderbook data. Valid values:
|
267 | NoMDEntryTypes | Number of MDEntryType (269) fields requested. |
=> 269 | MDEntryType | This is a list of all the types of Market Data Type requested. Valid values:
012 (Orderbook and Trades), 01 (Orderbook) and 2 (Trades) , the client is not allowed to ask only for the one-side of the book. |
146 | NoRelatedSym | Number of symbols (instruments) requested. |
=> 55 | Symbol | Exact match or regex for the symbol identifier filtering, eg. ^BITSTAMP_(.*)_USD$ or BITSTAMP_SPOT_BTC_USD , have in mind that regex is enabled only if value string starts with ^ or/and ends with $ . |
Market Data Request Reject 35=Y
Market Data Request Reject (Y) message is used to reject the request for the market data.
Tag | Name | Description |
---|---|---|
262 | MDReqId | MDReqId (262) from Market Data Request (V) message. |
281 | MDReqRejReason | Reason for the rejection of a Market Data request. Valid values:
|
58 | Text | Error message |
Market Data Incremental 35=X
Market Data - Incremental Refresh (X) message, representing new executed transaction or orderbook update.
Tag | Name | Description |
---|---|---|
268 | NoMdEntries | Number of trades in the message |
=> 279 | MDUpdateAction | Type of Market Data update action. Valid values:
|
=> 269 | MDEntryType | Type of Market Data entry. Valid values:
|
=> 278 | MDEntryID | Our unique trade identifier in the form of UUIDv4 |
=> 55 | Symbol | Our Symbol identifier (full list available here) |
=> 270 | MDEntryPx | Entry price |
=> 271 | MDEntrySize | Entry size in base amount |
=> 272 | MDEntryDate | Date of the entry reported by the exchange |
=> 273 | MDEntryTime | Time of the entry reported by the exchange with milliseconds |
=> 282 | MDEntryOriginator | Used only when MDEntryType (269) is Trade. Aggressor side of the transaction. (BUY/SELL/BUY_ESTIMATED/SELL_ESTIMATED/UNKNOWN) |
Possible MDEntryOriginator
values
If exchange has not reported who the aggressor side of the transaction was, we will classify who it most probably was based on current market view.
taker_side |
Description |
---|---|
BUY |
Exchange has reported that transaction aggressor was buying |
SELL |
Exchange has reported that transaction aggressor was selling |
BUY_ESTIMATED |
Exchange has not reported transaction aggressor, we estimated that more likely it was buying |
SELL_ESTIMATED |
Exchange has not reported transaction aggressor, we estimated that more likely it was selling |
UNKNOWN |
Exchange has not reported transaction aggressor and we have not estimated who it was |
Market Data Snapshot 35=W
Market Data - Snapshot/Full Refresh (W) message, representing orderbook snapshot.
8=FIX.4.4|9=2814|35=W|34=7|49=COINAPI|52=20170503-22:35:18.590|56=73034021-THIS-IS-SAMPLE-KEY|55=COINBASE_SPOT_BTC_EUR|268=40|269=1|270=1397.84000000|271=0.25620000|272=20170503|273=22:35:18.408|269=1|270=1397.85000000|271=0.24000000|272=20170503|273=22:35:18.408|269=1|270=1397.86000000|271=0.50000000|272=20170503|273=22:35:18.408|269=1|270=1399.96000000|271=0.08000000|272=20170503|273=22:35:18.408|269=1|270=1399.98000000|271=0.11000000|272=20170503|273=22:35:18.408|269=1|270=1399.99000000|271=0.93340628|272=20170503|273=22:35:18.408|269=1|270=1400.0|271=4.37155883|272=20170503|273=22:35:18.408|269=1|270=1401.22000000|271=0.11000000|272=20170503|273=22:35:18.408|269=1|270=1401.23|271=0.01|272=20170503|273=22:35:18.408|269=1|270=1402.12|271=0.10000000|272=20170503|273=22:35:18.408|269=1|270=1402.60000000|271=5.30086000|272=20170503|273=22:35:18.408|269=1|270=1402.68000000|271=0.11000000|272=20170503|273=22:35:18.408|269=1|270=1402.69|271=0.02000000|272=20170503|273=22:35:18.408|269=1|270=1404.0|271=1.0|272=20170503|273=22:35:18.408|269=1|270=1404.01000000|271=0.47000000|272=20170503|273=22:35:18.408|269=1|270=1405.0|271=0.24577401|272=20170503|273=22:35:18.408|269=1|270=1405.07|271=0.01264284|272=20170503|273=22:35:18.408|269=1|270=1405.11|271=0.01943044|272=20170503|273=22:35:18.408|269=1|270=1405.61000000|271=1.68316924|272=20170503|273=22:35:18.408|269=1|270=1405.67000000|271=4.13101588|272=20170503|273=22:35:18.408|269=0|270=1396.00000000|271=0.73076211|272=20170503|273=22:35:18.408|269=0|270=1395.82000000|271=0.31000000|272=20170503|273=22:35:18.408|269=0|270=1395.81000000|271=4.07759372|272=20170503|273=22:35:18.408|269=0|270=1395.47000000|271=0.40000000|272=20170503|273=22:35:18.408|269=0|270=1395.01000000|271=0.56000000|272=20170503|273=22:35:18.408|269=0|270=1395.00000000|271=0.05000000|272=20170503|273=22:35:18.408|269=0|270=1394.34000000|271=0.50000000|272=20170503|273=22:35:18.408|269=0|270=1393.79000000|271=0.02000000|272=20170503|273=22:35:18.408|269=0|270=1393.78000000|271=0.10000000|272=20170503|273=22:35:18.408|269=0|270=1393.50000000|271=0.10000000|272=20170503|273=22:35:18.408|269=0|270=1393.23000000|271=0.13000000|272=20170503|273=22:35:18.408|269=0|270=1393.11000000|271=1.00000000|272=20170503|273=22:35:18.408|269=0|270=1393.02000000|271=0.33524135|272=20170503|273=22:35:18.408|269=0|270=1393.00000000|271=0.50000000|272=20170503|273=22:35:18.408|269=0|270=1392.52000000|271=0.02000000|272=20170503|273=22:35:18.408|269=0|270=1392.51000000|271=0.11000000|272=20170503|273=22:35:18.408|269=0|270=1392.50000000|271=0.10000000|272=20170503|273=22:35:18.408|269=0|270=1392.36000000|271=2.62000000|272=20170503|273=22:35:18.408|269=0|270=1392.31000000|271=0.02000000|272=20170503|273=22:35:18.408|269=0|270=1392.01000000|271=0.41000000|272=20170503|273=22:35:18.408|10=075|
public void OnMessage(QuickFix.FIX44.MarketDataSnapshotFullRefresh msg, SessionID s)
{
for (int idx = 0; idx < msg.NoMDEntries.getValue(); idx++)
{
var level = new QuickFix.FIX44.MarketDataSnapshotFullRefresh.NoMDEntriesGroup();
msg.GetGroup(idx + 1, level);
Console.WriteLine($"Orderbook {level.MDEntryType} @ {msg.Symbol}:");
Console.WriteLine($" Date: {level.MDEntryDate}");
Console.WriteLine($" Time: {level.MDEntryTime}");
Console.WriteLine($" Px: {level.MDEntryPx}");
Console.WriteLine($" Size: {level.MDEntrySize}");
}
}
Tag | Name | Description |
---|---|---|
55 | Symbol | Our Symbol identifier (full list available here) |
268 | NoMdEntries | Number of levels in the orderbook. |
=> 269 | MDEntryType | Type Market Data entry. Valid values:
|
=> 270 | MDEntryPx | Price level of the orderbook level |
=> 271 | MDEntrySize | Volume resting on this orderbook level |
=> 272 | MDEntryDate | Date of the orderbook reported by the exchange |
=> 273 | MDEntryTime | Time of the orderbook reported by the exchange with milliseconds |
Heartbeat 35=0
8=FIX.4.4|9=87|35=0|34=13|49=COINAPI|52=20170503-22:21:27.545|56=73034021-THIS-IS-SAMPLE-KEY|10=048|
Message sent by any side after defined amount of seconds in communication silence.