curl --request GET \
--url https://api.trysoar.com/v1/markets/{market_id}/candles \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.trysoar.com/v1/markets/{market_id}/candles"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.trysoar.com/v1/markets/{market_id}/candles', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.trysoar.com/v1/markets/{market_id}/candles",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.trysoar.com/v1/markets/{market_id}/candles"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.trysoar.com/v1/markets/{market_id}/candles")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.trysoar.com/v1/markets/{market_id}/candles")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"ticker": "<string>",
"market_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"interval": "1m",
"candles": [
{
"timestamp": "2023-11-07T05:31:56Z",
"open": 50,
"high": 50,
"low": 50,
"close": 50,
"volume": 1,
"trade_count": 1
}
]
}{
"code": "invalid_enum_value",
"error": "side must be one of \"buy\", \"sell\", got \"hold\""
}{
"code": "unauthenticated",
"error": "API key or bearer token required"
}{
"code": "forbidden_scope",
"error": "api key lacks scope: trade"
}{
"code": "invalid_request_body",
"error": "<string>",
"details": "<string>"
}{
"code": "rate_limited",
"error": "rate limited (per-api-key)"
}{
"code": "engine_unavailable",
"error": "market data store not configured"
}Get OHLCV bars for a market
Bars over [from, to], oldest first, defaulting to the last 24 hours.
Built from the trade tape, so prices are in canonical YES terms. Unlike the order book this is not a live view either — it is a rollup of what already printed.
curl --request GET \
--url https://api.trysoar.com/v1/markets/{market_id}/candles \
--header 'X-API-KEY: <api-key>'import requests
url = "https://api.trysoar.com/v1/markets/{market_id}/candles"
headers = {"X-API-KEY": "<api-key>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {'X-API-KEY': '<api-key>'}};
fetch('https://api.trysoar.com/v1/markets/{market_id}/candles', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.trysoar.com/v1/markets/{market_id}/candles",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"X-API-KEY: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.trysoar.com/v1/markets/{market_id}/candles"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("X-API-KEY", "<api-key>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.trysoar.com/v1/markets/{market_id}/candles")
.header("X-API-KEY", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.trysoar.com/v1/markets/{market_id}/candles")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["X-API-KEY"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"ticker": "<string>",
"market_id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"interval": "1m",
"candles": [
{
"timestamp": "2023-11-07T05:31:56Z",
"open": 50,
"high": 50,
"low": 50,
"close": 50,
"volume": 1,
"trade_count": 1
}
]
}{
"code": "invalid_enum_value",
"error": "side must be one of \"buy\", \"sell\", got \"hold\""
}{
"code": "unauthenticated",
"error": "API key or bearer token required"
}{
"code": "forbidden_scope",
"error": "api key lacks scope: trade"
}{
"code": "invalid_request_body",
"error": "<string>",
"details": "<string>"
}{
"code": "rate_limited",
"error": "rate limited (per-api-key)"
}{
"code": "engine_unavailable",
"error": "market data store not configured"
}Authorizations
Per-user API key. Create and revoke keys from your SOAR account settings. A revoked key stops working within 60 seconds.
Path Parameters
The market's ticker or its event_market_id UUID. Tickers are
case-insensitive.
^[A-Za-z0-9.](?:[A-Za-z0-9.-]*[A-Za-z0-9.])?$"ANTHROPIC-VALUATION-26Q3-1.05T"
Query Parameters
Bar width. 30s, 1m, 1h and 1d are stored rollups; 4h and 12h
are re-aggregated from the hourly rollup at query time and cost slightly
more. There is deliberately no other value: an interval with no backing
rollup would return an empty series, and you could not tell that from a
quiet market — so anything else is 400 naming the set.
30s, 1m, 1h, 4h, 12h, 1d RFC3339 start of the window. Defaults to 24 hours ago.
RFC3339 end of the window. Defaults to now. A from after to is
400 invalid_parameter, not an empty series — you cannot tell a
mistyped range from a quiet market, and one of those you can fix.
Response
The bar series.
Bar width. 30s, 1m, 1h and 1d are stored rollups; 4h and 12h
are re-aggregated from the hourly rollup at query time and cost slightly
more. There is deliberately no other value: an interval with no backing
rollup would return an empty series, and you could not tell that from a
quiet market — so anything else is 400 naming the set.
30s, 1m, 1h, 4h, 12h, 1d Oldest first. [] when nothing traded in the window — never null.
Show child attributes
Show child attributes
Was this page helpful?