Unhinged

Developers

History, ranked, as JSON.

Everything on the site is available as a free, open API. No key, no sign-up, CORS enabled on every read. Every event is sourced and scored 0–100 for how far outside the ordinary it sits.

Base: https://unhinged.l2gseo.com/api/v1 JSON · UTF-8 CORS: * Licence: CC BY 4.0

Quick start

One request gets you today’s full edition — 26 events, ranked, with sources.

// browser or Node 18+
const r = await fetch("https://unhinged.l2gseo.com/api/v1/today");
const { date, events } = await r.json();
console.log(date, events[0].title, events[0].score);
# shell
curl -s https://unhinged.l2gseo.com/api/v1/today | jq '.events[:3] | .[] | {rank, score, title}'

Endpoints

GET
/today

Today’s edition in UTC. If today has not been published yet, the most recent edition is served and is_today is false.

GET
/editions

Index of every published edition: key, date, entry count, the #1 title and its peak score.

GET
/editions/{MM-DD}

One edition in full, ranked by score, with crowd tallies (crowd.u = “unhinged” votes, crowd.d = “overrated”). 404 if that date is not published yet — the body tells you where to request it.

GET
/random?n=1

Random events from the whole archive, up to 10 per call. Good for bots, widgets and “did you know” slots. Never cached.

GET
/requests

The request board: open dates sorted by votes, with queue position, plus recently fulfilled ones. The top of the queue is researched and published the next morning.

POST
/requests

Body {"key":"MM-DD"}. Creates the request or adds an upvote to it. Returns 409 already_published if the date exists, 400 bad_edition for impossible dates, 429 queue_full past 90 open requests. Same-origin only.

GET
/challenge?day=YYYY-MM-DD

The Daily Challenge deck: ten {id, ed} references, identical for everyone on that UTC day, plus how many people have finished and the score histogram (21 buckets of 50 points). Resolve references against /editions/{ed}.

POST
/challenge

Body {"day":"YYYY-MM-DD","score":0-1000}. Records a finished run for today or yesterday (UTC) and returns beat, the percentage of earlier players the score outranks. Same-origin only.

GET
/api/og?d=MM-DD

Not under /v1, but useful: a 1200×630 PNG share card for any edition, rendered on demand. Use it as og:image or embed it directly.

Event object

fieldtypemeaning
idstringStable slug, unique across the archive (1896-zanzibar).
editionstringMM-DD key of the edition it belongs to.
datestringHuman date, e.g. September 10.
yearnumberYear of the event.
titlestringOne-line headline.
dekstringTwo to four sentences of what actually happened, checked against the edition’s sources.
scorenumberUnhinged score, 0–100. Bands: 90+ Unhinged, 75–89 Severe, 60–74 Strange, 45–59 Notable, below 45 Footnote.
tagsstring[]Free-form topical tags.
source{label, url}Where to read more — the reference this entry was checked against. Link it when you republish; the edition-level sources array lists everything consulted for the whole day.
ranknumberEditor’s rank within the edition (only in edition responses).
crowd{u, d}Reader votes (only in /editions/{key}).
urlstringCanonical page for the edition.

Caching, limits and fair use

Reads carry cache-control headers and are served from the CDN; today’s edition can be up to 10 minutes stale, the index up to 10 minutes, a single edition up to 5. Editions never change once published, so cache them for as long as you like. There is no hard rate limit; please keep it under a request per second sustained and identify your app in the user-agent. Bulk consumers should read /editions once and then fetch only new keys.

Text and scores are licensed CC BY 4.0: use them anywhere, including commercially, with a visible credit to Unhinged and a link to unhinged.l2gseo.com. Scores are editorial judgement, not fact; every dek is checked against the sources listed with its edition.

Errors

Every error is JSON: {"ok":false,"error":"snake_case_reason"} with a matching HTTP status. Reads use 400 for malformed keys, 404 for dates that are not published (with a pointer to the request queue), and 5xx only when something is actually broken.

Changelog

v1 — initial release: today, editions, single edition with crowd tallies, random, request board, Daily Challenge.