GET /v1/history
Returns historical OHLCV bars for a given symbol and resolution. The response format is fully compatible with the TradingView UDF protocol.
Request
GET /v1/history
Auth: Required
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
symbol | string | ✅ | Compound key (e.g. WMMARKETS:ZERO:EURUSD) |
resolution | string | ✅ | Bar interval — see table below |
from | integer | — | Range start, Unix epoch seconds on the feed's broker clock (see below) |
to | integer | — | Range end, Unix epoch seconds on the feed's broker clock (see below) |
countback | integer | — | Number of bars to return (max: 10,000) |
Resolution Values
| Value | Timeframe | Bar Duration |
|---|---|---|
1 | M1 | 1 minute |
5 | M5 | 5 minutes |
10 | M10 | 10 minutes |
15 | M15 | 15 minutes |
30 | M30 | 30 minutes |
60 | H1 | 1 hour |
120 | H2 | 2 hours |
240 | H4 | 4 hours |
1D | Daily | 1 day |
1W | Weekly | 1 week |
1M | Monthly | 1 month |
Which clock are from and to on?
from and to are interpreted on the same clock the response uses — the feed's
broker clock, not real UTC. This matters enormously on feeds whose broker clock is far
from UTC.
Two safe approaches:
1. Use countback and omit from/to. The window is then resolved server-side
against the feed's own clock, so it is correct for every feed with no arithmetic on your
side. This is the recommended default.
GET /v1/history?symbol=ISE:TADIL:FMLY&resolution=1D&countback=30
2. If you need an explicit window, shift it by that feed's clock_offset_seconds
from /v1/status:
feed_from = real_utc_from - clock_offset_seconds
feed_to = real_utc_to - clock_offset_seconds
which is the inverse of the rule for reading timestamps back
(real_utc = feed_timestamp + clock_offset_seconds).
Response — Data Available
{
"s": "ok",
"t": [1749556800, 1749560400, 1749564000],
"o": [1.08234, 1.08198, 1.08215],
"h": [1.08267, 1.08241, 1.08259],
"l": [1.08190, 1.08182, 1.08198],
"c": [1.08198, 1.08215, 1.08241],
"v": [1250, 980, 1100],
"meta": {
"symbol": "WMMARKETS:ZERO:EURUSD",
"resolution": "60",
"bar_count": 3
}
}
Response — No Data
{
"s": "no_data"
}
Response — Error
{
"s": "error",
"errmsg": "symbol not found"
}
Response Fields
| Field | Type | Description |
|---|---|---|
s | string | Status: "ok", "no_data", or "error" |
t | integer | Bar open times as Unix epoch seconds (oldest → newest) |
o | float | Open prices |
h | float | High prices |
l | float | Low prices |
c | float | Close prices |
v | integer | Tick volume |
meta.bar_count | integer | Number of bars returned |
All arrays are aligned by index — t[0], o[0], h[0], l[0], c[0], v[0] all describe the same bar.
Examples
Last 1000 H1 bars
curl -H "X-API-Key: fxd_your_key" \
"https://api.pipdata.net/v1/history?symbol=WMMARKETS:ZERO:EURUSD&resolution=60&countback=1000"
Specific date range
import requests
from datetime import datetime, timezone
headers = {"X-API-Key": "fxd_your_key"}
# January 2025
from_ts = int(datetime(2025, 1, 1, tzinfo=timezone.utc).timestamp())
to_ts = int(datetime(2025, 1, 31, 23, 59, 59, tzinfo=timezone.utc).timestamp())
resp = requests.get(
"https://api.pipdata.net/v1/history",
headers=headers,
params={
"symbol": "WMMARKETS:ZERO:EURUSD",
"resolution": "60",
"from": from_ts,
"to": to_ts
}
)
data = resp.json()
if data["s"] == "ok":
first = datetime.fromtimestamp(data["t"][0], tz=timezone.utc)
last = datetime.fromtimestamp(data["t"][-1], tz=timezone.utc)
print(f"{len(data['t'])} bars from {first.date()} to {last.date()}")
Convert to pandas DataFrame
import pandas as pd
if data["s"] == "ok":
df = pd.DataFrame({
"time": pd.to_datetime(data["t"], unit="s", utc=True),
"open": data["o"],
"high": data["h"],
"low": data["l"],
"close": data["c"],
"volume": data["v"]
})
df.set_index("time", inplace=True)
print(df.tail())
Daily bars — last 365 days
curl -H "X-API-Key: fxd_your_key" \
"https://api.pipdata.net/v1/history?symbol=WMMARKETS:ZERO:GBPUSD&resolution=1D&countback=365"
Important Notes
Error Codes
| HTTP Status | Code | Description |
|---|---|---|
| 401 | UNAUTHORIZED | API key missing or invalid |
| 403 | SYMBOL_NOT_PERMITTED | Feed access not allowed for this key |
| 422 | INVALID_PARAMS | Missing or invalid parameters |
| 500 | SERVER_ERROR | Internal error |