API Documentation
Everything you need to integrate PriceFeed Pro into your application.
Getting Started
1. Create an account and get your API key.
2. Include your API key in every request via the X-API-Key header.
3. Base URL: https://your-domain.com
Authentication
All API requests require an API key. Pass it as a header:
GET /api/v1/market/symbols HTTP/1.1
Host: api.example.com
X-API-Key: $PRICEFEED_API_KEYKeep your API key on the server side only. Never expose it in client-side JavaScript or public repositories.
API keys start with pf_ and are 67 characters long.
REST API
/api/v1/market/symbols?search=§or=&page=1&limit=50List available symbols, optionally filtered by search term and sector. Paginated.
// Response
{
"success": true,
"data": {
"symbols": [
{ "symbol": "XAUUSD", "display_name": "Gold", "sector": "metals", "digits": 2 },
{ "symbol": "EURUSD", "display_name": "EUR/USD", "sector": "forex", "digits": 5 }
],
"total": 150,
"page": 1,
"limit": 50
}
}/api/v1/market/history/{symbol}?tf=60&limit=500&from=&to=Get OHLC historical bars. Timeframes (in minutes): 1, 5, 15, 30, 60, 240, 1440, 10080, 43200. Requires Pro or Enterprise plan.
// GET /api/v1/market/history/XAUUSD?tf=60&limit=5
{
"success": true,
"data": {
"symbol": "XAUUSD",
"source_id": "source-1",
"timeframe": 60,
"bars": [
{ "time": "2025-01-15T14:00:00Z", "open": 2650.5, "high": 2655.0, "low": 2648.0, "close": 2652.0 }
],
"count": 1
}
}/api/v1/market/tick/{symbol}Get the latest tick for a single symbol. Also available: /api/v1/market/ticks?symbols=EURUSD,GBPUSD for multiple symbols.
/api/v1/account/profileGet your subscriber profile, subscription details, and usage stats. Requires JWT Bearer token (not API key).
WebSocket Streaming
Connect via native WebSocket to receive real-time price ticks and OHLC bars.
Connection URL: wss://your-host/ws/v1/stream?api_key=YOUR_API_KEY
Authentication is done via the api_key query parameter during the initial connection.
JavaScript (Node.js / Browser)
// Load API key from environment variable — never hardcode it
const ws = new WebSocket(
"wss://api.example.com/ws/v1/stream?api_key=" + process.env.PRICEFEED_API_KEY
);
ws.onopen = () => {
// Subscribe to tick data
ws.send(JSON.stringify({
action: "subscribe",
symbols: ["XAUUSD", "EURUSD"]
}));
// Subscribe to OHLC bars (optional)
ws.send(JSON.stringify({
action: "subscribe_bars",
symbols: ["XAUUSD"],
timeframes: [1, 5, 60]
}));
};
ws.onmessage = (event) => {
const msg = JSON.parse(event.data);
switch (msg.type) {
case "connected":
console.log("Plan:", msg.plan, "Sources:", msg.sources);
break;
case "tick":
console.log(msg.symbol, msg.bid, msg.ask, "spread:", msg.spread);
break;
case "error":
console.error(msg.code + ":", msg.message);
break;
}
};
// Unsubscribe
ws.send(JSON.stringify({
action: "unsubscribe",
symbols: ["EURUSD"]
}));Python
import os
import asyncio
import websockets
import json
async def connect():
# Load API key from environment variable — never hardcode it
api_key = os.environ["PRICEFEED_API_KEY"]
uri = f"wss://api.example.com/ws/v1/stream?api_key={api_key}"
async with websockets.connect(uri) as ws:
# Subscribe to tick data
await ws.send(json.dumps({
"action": "subscribe",
"symbols": ["XAUUSD", "EURUSD"]
}))
# Listen for messages
async for message in ws:
data = json.loads(message)
if data["type"] == "connected":
print(f"Connected - Plan: {data['plan']}")
elif data["type"] == "tick":
print(f"{data['symbol']}: {data['bid']}/{data['ask']} spread={data['spread']}")
elif data["type"] == "error":
print(f"Error [{data['code']}]: {data['message']}")
asyncio.run(connect())Rate Limits
| Tier | Requests/min | Max Symbols |
|---|---|---|
| Free | 10 | 5 |
| Basic | 60 | 20 |
| Pro | 300 | 100 |
| Enterprise | 9,999 | Unlimited |
Exceeding limits returns 429 Too Many Requests with a Retry-After header.
Error Codes
| Code | Status | Description |
|---|---|---|
| MISSING_API_KEY | 401 | No API key provided |
| INVALID_API_KEY | 401 | API key is invalid or inactive |
| API_KEY_REVOKED | 401 | API key has been revoked |
| ACCOUNT_INACTIVE | 403 | Subscriber account is inactive |
| TRIAL_EXPIRED | 403 | Free trial has expired, please upgrade |
| CONNECTION_LIMIT | 429 | Maximum WebSocket connections exceeded for your plan |
| SYMBOL_LIMIT | WS | Maximum symbol subscriptions exceeded for your plan |
| RATE_LIMIT_EXCEEDED | 429 | Too many requests for your plan |
| RATE_LIMITED | 429 | Too many failed auth attempts (15 min lockout) |