A free, versioned JSON API for the W.E.T. benchmark indices — the governed class, with published methodology and a checksum-chained settlement ledger. No account, no key. Values are delayed to the previous close and attribution is required.
Fields are added, never removed or retyped. A breaking change mints v2 and leaves v1 serving. Licence wet-licence/v1.
curl -s https://www.worldeventtrading.com/api/public/v1/indices
Ticker, name, class, unit, the latest released settled value, methodology URL, attribution string, and the venue disclosure for each benchmark.
curl -s https://www.worldeventtrading.com/api/public/v1/indices/wetgri
Every settled day from genesis to the embargo cut, each row carrying its checksum, the previous checksum, and the composition digest.
curl -s https://www.worldeventtrading.com/api/public/v1/indices \
| python3 -c "import json,sys
for i in json.load(sys.stdin)['indices']:
l = i['latest'] or {}
print(i['ticker'], l.get('date','-'), l.get('value','-'), i['latestUnavailableReason'] or '')"A null latest is a real answer, and the reason says which one: embargoed_under_free_tier (today's close is not out yet), no_settlement_published, or awaiting_restatement. A null value inside a row is a third thing again — a day with insufficient data publishes no number rather than carrying yesterday's forward.
curl -s https://www.worldeventtrading.com/api/public/v1/indices/wetgri \
| python3 -c "import json,sys
d = json.load(sys.stdin)
print('rows', d['count'], 'chainVerified', d['chainVerified'], 'superseded', d['supersededDays'])
for r in d['rows']:
print(r['date'], r['value'], 'SUPERSEDED' if r['superseded'] else 'live', r['checksum'])"Rows flagged SUPERSEDED were restated. They stay in the response because the chain runs through them — filter them out and your own verification will fail on correct data — but never quote one as a current value. Use latest, which already excludes them.
curl -s https://www.worldeventtrading.com/api/public/v1/indices/wetgri \ | python3 -c "import json,sys; print(json.dumps(json.load(sys.stdin)['checksumRecipe'], indent=2))"
The full field-by-field construction, served with the data rather than only documented here — so an implementation can be checked against the same source the engine is transcribed from.
curl -sD - -o /dev/null https://www.worldeventtrading.com/api/public/v1/indices/wetx \ | grep -i '^x-ratelimit\|^x-wet'
Rate-limit and licence headers ride on every response, including errors.
curl -s https://www.worldeventtrading.com/api/pro/v1/indices/wetgri
Entitlement is resolved server-side from your session; a caller cannot assert a tier. Unentitled requests return 402 with the upgrade path and a link to the free endpoint, not 404 — pretending the route does not exist would be a worse answer than saying what it costs. BENCHMARK VALUES THEMSELVES ARE PUBLIC AND ALWAYS WILL BE: the free tier serves the complete settlement history, genesis forward, chain intact. Pro removes the D+1 delay (and flags a same-day row as still provisional), adds the intraday indicative, adds constituent-level detail, and grants commercial use.
| Ticker | Slug | Unit | Index |
|---|---|---|---|
| WETGRI | wetgri | index-level | W.E.T. Geopolitical Risk Index |
| WETFED | wetfed | basis-points | W.E.T. Fed Path Index |
| WETX | wetx | index-level | World Event Uncertainty Index |
| WETFRAG | wetfrag | index-level | W.E.T. Fragmentation Index |
Benchmarks only. Slates are the tactical class under lighter governance and are not served by the public API — see the index board.
This tier exists to be quoted. The whole history is served — genesis forward, chain intact — because a track record that can only be sampled is one nobody can audit, and being auditable is the product claim.
Previous close only. A settlement dated D becomes available on UTC date D+1; today's WET Close is withheld until tomorrow. The rule is keyed on the settlement date, not on elapsed hours, so any response can be reproduced and checked.
Per the W.E.T. Geopolitical Risk Index (WETGRI), W.E.T. World Event Trading.
Served as each index’s attribution field, so it never has to be retyped from this page.
60 / 60s
Per client IP, per endpoint, per origin instance. Every header below is in access-control-expose-headers, so a browser client can read the quota it is being held to.
| Header | Meaning | Sent on |
|---|---|---|
| x-ratelimit-limit | Requests permitted in one window. | every response |
| x-ratelimit-remaining | Requests left in the current window, floored at 0. | every response |
| x-ratelimit-reset | Unix time in SECONDS when the window resets. | every response |
| x-ratelimit-policy | The policy as `<requests>;w=<seconds>` — currently `60;w=60`. | every response |
| retry-after | Seconds to wait before retrying. Back off on this value, not on a guess. | 429 only |
| x-wet-licence | The tier serving the response: `free`. | every response |
| x-wet-licence-version | The licence version — currently `wet-licence/v1`. | every response |
| x-wet-attribution-required | Always `true` on this tier. | every response |
Back off on retry-after rather than on a guess. The limiter runs at the origin and per instance, and responses are edge-cacheable — so treat the counters as the origin’s view of usage, not a per-client ledger. A durable per-key quota arrives with authentication.
Every omission is named in the response itself. An undisclosed omission in a licensed feed is indistinguishable from missing data, and you would have no way to tell which one you were looking at.
The free tier serves the full settled series minus the embargoed tail — never a recent window. The checksum chain starts at the first published value, so a window would leave you unable to verify a single link. Each response carries chainVerified and the exact algorithm, so you can recompute the chain yourself in any language rather than take ours on trust. It is null, not true, when no rows are released yet — verification over an empty series is vacuous, not passing.
Every settlement row carries a checksum chained to the previous row’s. Recomputing the chain is how you establish that our history has not moved since you last read it — without asking us. Below is the construction, exactly as the engine computes it. It is also served as checksumRecipe on every history response, and has been re-derived from this text alone, in another language, against every published row.
Two 32-bit unsigned accumulators run in parallel over the same string. Initialise h1 = 0x811c9dc5 and h2 = 0x01000193. For each character c of the canonical string, in order, taking c as its UTF-16 code unit (all published inputs are ASCII): h1 = ((h1 XOR c) * 0x01000193) mod 2^32 <-- this leg, and only this leg, is FNV-1a h2 = ((h2 + c) * K) mod 2^32 <-- add-then-multiply; K depends on which digest is being computed K = 0x85ebca6b for a settlement checksum. K = 0x27d4eb2f for a composition digest. Nothing else differs between them. The multiplications MUST wrap at 32 bits (exact integers masked to 0xffffffff, or Math.imul). IEEE-754 doubles lose low bits on these products and will silently produce a wrong digest.
64 bits, rendered as 16 lowercase hex characters: hex8(h1) followed by hex8(h2), both zero-padded.
slug|date|value|divisor|compositionDigest|previousChecksum -- six fields joined by the ASCII pipe '|', in this order.
| slug | The benchmark slug exactly as served: wetgri, wetfed, wetx, wetfrag. |
| date | The settlement date, ISO YYYY-MM-DD, as served. |
| value | Fixed-point decimal with exactly 6 digits after the point (JavaScript Number.toFixed(6)). A null value (an insufficient_data day) is encoded as 0, i.e. "0.000000". |
| divisor | Fixed-point decimal with exactly 9 digits after the point. A null divisor (every benchmark except WETGRI, which alone is divisor-chained) is encoded as 0, i.e. the literal "0.000000000" -- the field is never omitted. |
| compositionDigest | The 16-hex-character digest as published on the row, inserted verbatim. |
| previousChecksum | The prior row's checksum, or the literal ASCII string "genesis" on the first row of the ledger. |
Composition digest: sort the constituent ids ascending by UTF-16 code unit (JavaScript's default Array#sort), join with a single comma, and hash that string with K = 0x27d4eb2f.
A corrected value is APPENDED as a new row; the original stays in the ledger flagged `superseded: true`, and the corrective row carries `restates` and `restatementReason`. Both are served, because the checksum chain runs through the superseded row and dropping it would break verification. Never quote a row with `superseded: true` as a current value — `latest` already excludes them. A settlement date can therefore carry more than one row: key your cache on `checksum`, not on `date`.
A benchmark administrator that corrects a published value in public is doing the job; one that edits a number in place is not. Which is why the wrong row stays visible: a restatement you cannot see is indistinguishable from history quietly changing underneath you. Restatement policy →
| Tier | Latency | Commercial | Price | Status |
|---|---|---|---|---|
| Free — delayed daily values | Previous close only. A settlement dated D is released on UTC date D+1. | No | No charge, no account, no key. | live |
| Pro API | Same-day close on publication, plus the intraday indicative series. | Yes | $99–299 / month. | planned |
| Enterprise | Real-time feed, by agreement. | Yes | Custom. | planned |
Planned means not purchasable. Authentication and billing are not built, and there is no checkout to point at. If you need commercial or redistribution rights today, email indices@worldeventtrading.com.
Quoting a value in journalism, research, teaching or public commentary is always permitted with attribution, whether or not the publication is commercial. What the free tier withholds is productisation: embedding the series in a paid product, reselling it, or redistributing it as a feed.
A benchmark reading of prediction-market prices. Not a forecast, not advice, and never a performance claim. Values describe what markets priced, not what will happen and not what anyone earned.
W.E.T. World Event Trading is a benchmark administrator, not an exchange. Challenging a published value never requires a licence — see complaints & challenges.