PriceFeed API
One REST API for real-time and historical crypto & fiat exchange rates. Base URL: https://pricefeed.online. All responses are JSON over HTTPS.
Make your first request
No signup, no API key — just call the endpoint:
$ curl "https://pricefeed.online/api/v1/rates/latest?base=BTC"es=USD,EUR,UAH"
{ "success": true, "base": "BTC", "rates": { "USD": 104250.12, "EUR": 96480.55, "UAH": 4329815.40 }, "meta": { "source": "aggregated", "source_count": 2, "stale": false, "updated_at": "2026-06-12T10:15:42+00:00" } }
Use it from your stack
const res = await fetch(
'https://pricefeed.online/api/v1/rates/latest?base=BTC"es=USD,EUR,UAH'
);
const data = await res.json();
if (data.success) {
console.log(data.rates.USD, data.meta.stale);
}use Illuminate\Support\Facades\Http;
$response = Http::get('https://pricefeed.online/api/v1/rates/latest', [
'base' => 'BTC',
'quotes' => 'USD,EUR,UAH',
]);
$rates = $response->json('rates'); // ['USD' => 104250.12, ...]USD, EUR, UAH) and ticker codes for crypto (BTC, ETH, USDT). Authentication
The API is public right now — requests need no API key, token, or signature. Fair use is enforced with an IP-based rate limit of 60 requests per minute (see rate limits).
Want a higher quota? Sign in and generate a free API key on the account page — requests with the X-API-Key header get double the limit: 120 requests per minute, counted per key instead of per IP. The open tier stays — existing integrations keep working unchanged.
$ curl -H "X-API-Key: pf_live_..." "https://pricefeed.online/api/v1/rates/latest?base=BTC"es=USD,EUR,UAH"
Rate limits
Without a key, limits apply per IP address: 60 requests per minute across all endpoints. With a free API key (X-API-Key header) the limit doubles to 120 requests per minute, counted per key. Exceeding the limit returns 429 Too Many Requests with a machine-readable body and a Retry-After header:
{ "success": false, "error": { "code": "RATE_LIMIT_EXCEEDED", "message": "Too many requests. Public limit is 60 requests per minute." } }
Cache responses on your side where you can — most pairs update on a fixed interval (see pairs), so polling faster than that interval adds no freshness.
Errors
Errors use conventional HTTP status codes with a consistent JSON body: success is false and error carries a machine-readable code plus a human-readable message.
{ "success": false, "error": { "code": "PAIR_NOT_FOUND", "message": "Requested currency pair [BTC/XYZ] is not available." } }
| Status | Code | When |
|---|---|---|
| 404 | PAIR_NOT_FOUND | Unknown or inactive currency pair, or no rate available for the base asset |
| 400 | INVALID_AMOUNT | amount is not a non-negative number |
| 400 | INVALID_PERIOD | period is not one of 1d, 7d, 30d, 90d |
| 429 | RATE_LIMIT_EXCEEDED | More than 60 req/min from one IP (120 req/min with an API key) |