Skip to content

Caching & conditional requests

Every response carries ETag: "<dataset_version>" and a short public Cache-Control: public, max-age=300 (/v1/dump: max-age=3600), so a browser or HTTP cache reuses a response for five minutes without asking. After that, send If-None-Match with the last ETag you saw; if dataset_version hasn’t changed, the API answers 304 Not Modified with no body.

Send the ETag back exactly as you received it, quotes included: it may reach you weak (W/"e9c25a6") after passing through a proxy or CDN, and that form matches too. Don’t compare it to dataset_version yourself; let the 304 tell you.

Terminal window
curl -D - -o /dev/null \
-H 'If-None-Match: "e9c25a6"' \
https://truefloat.app/api/v1/items/7/44/patterns
HTTP/2 304
etag: "e9c25a6"
cache-control: public, max-age=300
access-control-allow-origin: *
access-control-expose-headers: ETag, Retry-After
JavaScript
let etag = null;
async function poll(url) {
const res = await fetch(url, etag ? { headers: { 'If-None-Match': etag } } : {});
if (res.status === 304) return null; // nothing changed
if (!res.ok) throw new Error(`HTTP ${res.status}`); // a 429: wait Retry-After seconds
etag = res.headers.get('ETag');
return res.json();
}
Python
import requests
etag = None
def poll(url):
global etag
headers = {'If-None-Match': etag} if etag else {}
res = requests.get(url, headers=headers, timeout=30)
if res.status_code == 304:
return None # nothing changed
res.raise_for_status() # a 429: wait Retry-After seconds
etag = res.headers.get('ETag')
return res.json()

dataset_version, and so the ETag, changes when the data changes or when the way responses are derived from it changes. A docs, formatting or infrastructure deploy leaves it alone, so your ETag survives those. See dataset_version.

Responses are also cached at the Cloudflare edge for 10 minutes, so a burst of identical requests from many callers doesn’t reach the origin at all. A new dataset_version can therefore take up to 10 minutes to show up everywhere.

Polling more often than the 10-minute edge cache just re-reads the same cached response. See Building on the API for a sane cadence.