curl --request GET \
--url https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount} \
--header 'x-api-key: <api-key>' \
--header 'x-request-id: <x-request-id>' \
--header 'x-user-key: <api-key>'import requests
url = "https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}"
headers = {
"x-request-id": "<x-request-id>",
"x-api-key": "<api-key>",
"x-user-key": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'x-request-id': '<x-request-id>',
'x-api-key': '<api-key>',
'x-user-key': '<api-key>'
}
};
fetch('https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}', 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://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}",
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>",
"x-request-id: <x-request-id>",
"x-user-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://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-request-id", "<x-request-id>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-user-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://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}")
.header("x-request-id", "<x-request-id>")
.header("x-api-key", "<api-key>")
.header("x-user-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-request-id"] = '<x-request-id>'
request["x-api-key"] = '<api-key>'
request["x-user-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"interval": "OneMinute",
"candles": [
{
"instrumentId": 12,
"candles": [
{
"instrumentID": 12,
"fromDate": "2025-03-05T10:34:00Z",
"open": 1.70227,
"high": 1.70277,
"low": 1.70221,
"close": 1.70253,
"volume": 0
},
{
"instrumentID": 12,
"fromDate": "2025-03-05T10:35:00Z",
"open": 1.70252,
"high": 1.70276,
"low": 1.70244,
"close": 1.70276,
"volume": 0
}
],
"rangeOpen": 1.70227,
"rangeClose": 1.70276,
"rangeHigh": 1.70277,
"rangeLow": 1.70221,
"volume": 0
}
]
}Get instrument candle history
Rate limit: 120 requests per 60 seconds. This is a shared quota — the same budget is consumed by a group of related endpoints, so calling any of them reduces what is left for the others (you cannot call each at the full rate independently). Endpoints sharing this quota:
GET /api/v1/market-data/exchangesGET /api/v1/market-data/instrument-typesGET /api/v1/market-data/instrumentsGET /api/v1/market-data/instruments/history/closing-priceGET /api/v1/market-data/instruments/ratesGET /api/v1/market-data/searchGET /api/v1/market-data/stocks-industriesGET /api/v2/market-data/instrumentsGET /api/v2/market-data/instruments/searchGET /api/v2/market-data/rates
Retrieves historical price data in OHLCV (Open, High, Low, Close, Volume) format for a specified instrument. The data is organized into time-based candles of various intervals, from one minute to one week.
curl --request GET \
--url https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount} \
--header 'x-api-key: <api-key>' \
--header 'x-request-id: <x-request-id>' \
--header 'x-user-key: <api-key>'import requests
url = "https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}"
headers = {
"x-request-id": "<x-request-id>",
"x-api-key": "<api-key>",
"x-user-key": "<api-key>"
}
response = requests.get(url, headers=headers)
print(response.text)const options = {
method: 'GET',
headers: {
'x-request-id': '<x-request-id>',
'x-api-key': '<api-key>',
'x-user-key': '<api-key>'
}
};
fetch('https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}', 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://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}",
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>",
"x-request-id: <x-request-id>",
"x-user-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://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("x-request-id", "<x-request-id>")
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("x-user-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://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}")
.header("x-request-id", "<x-request-id>")
.header("x-api-key", "<api-key>")
.header("x-user-key", "<api-key>")
.asString();require 'uri'
require 'net/http'
url = URI("https://public-api.etoro.com/api/v1/market-data/instruments/{instrumentId}/history/candles/{direction}/{interval}/{candlesCount}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["x-request-id"] = '<x-request-id>'
request["x-api-key"] = '<api-key>'
request["x-user-key"] = '<api-key>'
response = http.request(request)
puts response.read_body{
"interval": "OneMinute",
"candles": [
{
"instrumentId": 12,
"candles": [
{
"instrumentID": 12,
"fromDate": "2025-03-05T10:34:00Z",
"open": 1.70227,
"high": 1.70277,
"low": 1.70221,
"close": 1.70253,
"volume": 0
},
{
"instrumentID": 12,
"fromDate": "2025-03-05T10:35:00Z",
"open": 1.70252,
"high": 1.70276,
"low": 1.70244,
"close": 1.70276,
"volume": 0
}
],
"rangeOpen": 1.70227,
"rangeClose": 1.70276,
"rangeHigh": 1.70277,
"rangeLow": 1.70221,
"volume": 0
}
]
}Authorizations
API key of the application. Only valid together with the x-user-key header — the pair is an alternative to OAuth bearer authentication, never sent alongside it. The pair is granted the same permissions the operation's OAuth scopes describe.
Demo credential for trying the API from these docs: lhgfaslk21490FAScVPkdsb53F9dNkfHG4faZSG5vfjndfcfgdssdgsdHF4663
User-specific authentication key. Only valid together with the x-api-key header — the pair is an alternative to OAuth bearer authentication, never sent alongside it.
Demo credential for trying the API from these docs: eyJlYW4iOiJVbnJlZ2lzdGVyZWRBcHBsaWNhdGlvbiIsImVrIjoiOE5sZ2cwcW5EUVdROUFNWGpXT2lmOWktZnpidG5KcUlqWGJ3WHJZZkpZcldrbG90ZEhvLVBjSWhQaU8xU1ZtMW84aU1WZGZqN2xWNzFjLXFxLmcybXE1dnh4Q1hUT25xaWRUaTFlcEhmVk1fIn0_
Headers
A unique request identifier.
"352a5adc-96aa-44f1-b3d8-4c66c624c9f9"
Path Parameters
Sorting direction of the candles data. Use 'asc' for oldest to newest, or 'desc' for newest to oldest.
asc, desc Time interval for each candle. Determines the granularity of the price data. Shorter intervals provide more detailed price action but require more data points.
OneMinute, FiveMinutes, TenMinutes, FifteenMinutes, ThirtyMinutes, OneHour, FourHours, OneDay, OneWeek Number of candles to retrieve. Maximum value is 1000. For longer historical periods, consider using a larger time interval or making multiple requests.
x <= 1000Unique identifier of the financial instrument to retrieve candles for. This ID is consistent across all eToro systems.
Response
Successful retrieval of candles data
Response containing historical price data in candlestick format
Time interval of the returned candles. Matches the interval parameter from the request.
OneMinute, FiveMinutes, TenMinutes, FifteenMinutes, ThirtyMinutes, OneHour, FourHours, OneDay, OneWeek List of candle data grouped by instrument
Show child attributes
Show child attributes