Developers
The index, over HTTPS
A crowd-behaviour index with zero price-derived
inputs, an append-only archive, and point-in-time reconstruction.
Keyed, metered, versioned under /v1/.
$ curl https://bulldial.com/v1/health
…
Authentication
Send the key with every request, either way. Keys are stored
hashed; a lost key is reissued, never recovered. Three endpoints are
public and need no key: /v1/health,
/v1/meta/tiers, /v1/meta/methodology.
$ curl -H "Authorization: Bearer $KEY" https://bulldial.com/v1/fomo/current
$ curl -H "X-API-Key: $KEY" https://bulldial.com/v1/fomo/current
Every metered response carries
X-RateLimit-Limit, X-RateLimit-Remaining and
X-RateLimit-Reset (midnight UTC). Past the limit the API
returns 429 with the tier and the count, not a dropped
connection.
Tiers
Full pricingEndpoints
| Endpoint | Returns | Tier |
|---|---|---|
GET /v1/health | Liveness, version, methodology tag | public |
GET /v1/meta/methodology | Every component, constant, band and guarantee | public |
GET /v1/meta/tiers | This page's tier table, as data | public |
GET /v1/fomo/current | Today's reading, band, confidence | free |
GET /v1/fomo/history?start=&end= | The full daily series | pro |
GET /v1/fomo/components | Per-component decomposition of today's number | pro |
GET /v1/fomo/mechanisms | Mechanism scores, dispersion, confidence | pro |
GET /v1/fomo/divergence | The index against price, and the gap | pro |
GET /v1/fomo/signals | Reading plus the recent event stream | pro |
GET /v1/fomo/events?since=&limit= | Band changes, spikes, divergence opens/closes | pro |
GET /v1/fomo/narratives | Theme concentration over the live corpus | pro |
GET /v1/fomo/asof/{date}?knowledge_date= | Point-in-time reconstruction, no lookahead | quant |
GET /v1/series/{id}?knowledge_date= | Raw component series at any past vintage | quant |
GET /v1/series/{id}/revisions | How often the upstream rewrote its past | quant |
GET /v1/meta/sources | Provenance and licence verdict per series | any key |
GET /v1/meta/usage | Your own call counts, last 30 days | any key |
The point-in-time guarantee
/v1/fomo/asof/{date} recomputes the index from
observations recorded on or before knowledge_date and
nothing else. No value revised after that date is used, so the
reading contains no lookahead. If nothing was knowable by that date
the endpoint says so and returns null — it never substitutes
later-known values.
/v1/series/{id}/revisions is the same property
inside out: it counts the dates each upstream source restated after
we first recorded them. The archive is append-only and bitemporal;
that is what makes both answers possible.
{
"value": 41.7,
"point_in_time": {
"as_of": "2026-06-01",
"knowledge_date": "2026-06-01",
"guarantee": "Computed only from observations
recorded on or before knowledge_date…"
}
}
Quickstart
# today's reading
$ curl -s -H "Authorization: Bearer $KEY" \
https://bulldial.com/v1/fomo/current
# the series, June onward
$ curl -s -H "Authorization: Bearer $KEY" \
"https://bulldial.com/v1/fomo/history?start=2026-06-01"
import json, os, urllib.request
req = urllib.request.Request(
"https://bulldial.com/v1/fomo/current",
headers={"Authorization": "Bearer " + os.environ["BULLDIAL_KEY"]},
)
with urllib.request.urlopen(req) as r:
reading = json.load(r)
print(reading["value"], reading["band"])
const r = await fetch("https://bulldial.com/v1/fomo/current", {
headers: { "X-API-Key": process.env.BULLDIAL_KEY },
});
const reading = await r.json();
console.log(reading.value, reading.band);
CORS is open on /v1/: browser clients
work without a proxy. Free-tier responses carry an attribution field;
showing the number in public requires showing
"FOMOmeter by bulldial.com" beside it.
Errors
| Status | Meaning | Body carries |
|---|---|---|
401 | No key, or a revoked one | A hint naming both accepted headers |
403 | Your tier lacks the scope | The scope name and /v1/meta/tiers |
429 | Daily quota exhausted | Tier, calls used; resets midnight UTC |
503 | No reading published for the date | Nothing is imputed, ever |