Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.dexpaprika.com/llms.txt

Use this file to discover all available pages before exploring further.

Why this matters

The DexPaprika REST API sits behind Cloudflare with caching enabled. The behavior is generally invisible if you are a server-side consumer making fresh requests, but a few headers change what your client should do when the origin is briefly unavailable, and the CORS story is incomplete enough to bite browser-side code. This page documents the headers you will see today.

Cache-Control

Every successful GET returns a Cache-Control header that looks like this:
cache-control: public, max-age=60, s-maxage=60, stale-while-revalidate=10, stale-if-error=600
Breaking down what each directive means for your client:
DirectiveMeaning
publicThe response may be cached by shared caches (CDN, proxies).
max-age=60Your client may serve from its own cache for 60 seconds before revalidating.
s-maxage=60Shared caches may serve from cache for 60 seconds.
stale-while-revalidate=10After max-age expires, caches may serve stale for 10 more seconds while fetching a fresh copy in the background.
stale-if-error=600If revalidation fails, caches may keep serving the stale copy for up to 600 seconds (10 minutes) instead of failing the request.
The practical effect of stale-if-error=600 is that a brief origin outage does not break your client. If the API is unreachable, your CDN (or a properly configured HTTP cache library) returns the last-good response with Age: <some_number> indicating staleness. The data is not real-time during the outage, but your application keeps working. For agents and SDK consumers: most HTTP client libraries do not honor stale-if-error by default. If your application needs the resilience this directive promises, use a cache layer that implements it (e.g., a CDN in front of your service, or libraries like cachecontrol for Python, node-cache-control for Node.js). For LLM tool calls: the MCP layer does not currently cache between calls, so stale-if-error does not protect MCP-driven flows. The underlying REST cache still helps because Cloudflare serves the stale copy upstream of the MCP.

Cf-Cache-Status

A Cloudflare-specific header that tells you whether your request hit the CDN cache:
cf-cache-status: HIT      ← served from CDN cache
cf-cache-status: MISS     ← served from origin
cf-cache-status: BYPASS   ← cache intentionally skipped
cf-cache-status: DYNAMIC  ← cache not applicable (e.g., 4xx, 5xx, OPTIONS)
This is informational. You do not need to act on it. It is useful when debugging stale data: if you see HIT and the data looks old, the cache is doing its job and the response is up to max-age seconds out of date.

Age, Last-Modified

Age is the number of seconds since the cached response was generated. Last-Modified is the absolute timestamp of the underlying resource (when the API determined the snapshot).
age: 13
last-modified: Wed, 13 May 2026 13:18:11 GMT
If you need to tell your user how fresh the price data is, Age is the most direct signal: the data is at most Age + max-age seconds old.

CORS

The DexPaprika REST API currently has limited CORS support. Server-side code works without any special handling. Browser-side code that calls the API directly will fail the preflight check. What the API returns today:
# OPTIONS preflight:
HTTP/2 204
allow: OPTIONS, GET
vary: Origin, accept-encoding

# Simple GET with Origin header:
HTTP/2 200
cache-control: public, max-age=60, ...
vary: Origin, accept-encoding
What is missing for browser fetches to work:
  • Access-Control-Allow-Origin
  • Access-Control-Allow-Methods
  • Access-Control-Allow-Headers
Without these, browsers reject the response even though the network call succeeds. This is a known limitation. Work-arounds while it is being addressed:
  1. Server-side proxy. Run a small worker (Cloudflare Workers, Vercel Edge, Deno Deploy) that fetches from api.dexpaprika.com and re-serves with the right CORS headers to your frontend.
  2. DexPaprika MCP. Connect through mcp.dexpaprika.com from an agent runtime that handles the CORS layer for you.
  3. Static export. If your data refreshes infrequently, fetch at build time and serve as static JSON.
For real-time browser dashboards, options 1 and 2 are the practical paths.

h-hap

You will see this header on every response:
h-hap: 01
It is an internal infrastructure marker. You can ignore it. Future versions of the API may remove it without notice.

Headers not present (today)

Some headers you might expect from a mature API are not currently emitted:
  • Deprecation (RFC 9745) and Sunset (RFC 8594): not set. When DexPaprika deprecates an endpoint or field in the future, these will appear with the relevant dates. Until then, deprecation status is documented in the API reference and in the changelog, not in headers.
  • RateLimit-* (draft-ietf-httpapi-ratelimit-headers): not set. See Rate limits for the current rate-limit story.
  • ETag / If-None-Match: not set. Use Last-Modified if you need to track resource freshness.

Quick reference

cache-control:    public, max-age=60, ..., stale-if-error=600
cf-cache-status:  HIT | MISS | BYPASS | DYNAMIC
age:              <seconds since cached>
last-modified:    <RFC 7231 date>
vary:             Origin, Accept-Encoding
All response headers are lowercase per HTTP/2 convention. If you parse them from a library that returns header names verbatim, accept both Cache-Control and cache-control — some intermediaries normalize, others don’t. For error responses (4xx, 5xx), most cache-related headers are absent and cf-cache-status: DYNAMIC is set. The error envelopes themselves are documented in Error handling.