LunarWerx · Developer access
The reset record,
in your own tools.
Check when Codex limits last reset, count the resets we have tracked, or bring the forecast into your own dashboard.
FreeNo API keyJSON · v1Browser access enabled
Start with the stats
Make a GET request. There is no signup or credential to manage.
curl https://codex.lunarwerx.com/api/v1/stats
const response = await fetch('https://codex.lunarwerx.com/api/v1/stats');
if (!response.ok) throw new Error('Reset data is unavailable');
const stats = await response.json();
console.log(stats.lastResetAt, stats.totalResets);
Four endpoints
| GET | What you get |
|---|---|
/api/v1/stats | Last reset timestamp, lifetime tracked total, counts over 7 and 30 days, gap statistics, and identified banked resets. |
/api/v1/resets | Reset history, newest first, with gaps and announcement text and links where available. |
/api/v1/forecast | 24-hour and near-term probabilities, uncertainty intervals, and the website's historical accuracy scores. |
/api/v1/health | Observer, timeline and cron health, plus the AI model configuration and its last successful reading. |
Read the history
curl 'https://codex.lunarwerx.com/api/v1/resets?limit=25&offset=0'
curl 'https://codex.lunarwerx.com/api/v1/resets?since=2026-09-01T00:00:00Z'
limit defaults to 50 (1–100). offset defaults to 0. Follow nextOffset until it is null. totalMatching counts the rows after filtering; totalResets always counts the whole record. An offset beyond the last row returns an empty list.
since returns resets strictly after a UTC timestamp, with optional three-digit milliseconds. Keep the first page's newest timestamp for your next poll. Pagination uses a live snapshot: if generatedAt changes between pages, restart the read and deduplicate by timestamp.
What the numbers mean
totalResetscounts the project's deduplicated record, starting atrecordStartedAt. It is not a claim to know every reset OpenAI ever issued.- Routine scheduled window rollovers and redemption of a personal reset credit are excluded. Identified banked grants are included;
banked.countis the subset identified from announcement wording, not your account's available credits. - All dates are UTC. Durations say hours or days in their field names. Recent counts use trailing 7×24-hour and 30×24-hour windows at
generatedAt. The recent gap mean and median use completed gaps whose endpoints are within the last 120 days. gapDaysis the gap to the previous reset in the full record, even when that reset is outside your filter. Missing dates, links, or statistics arenull.- Forecast probabilities are fractions:
0.25means 25%. Low and high are uncertainty estimates from the timing model. They do not establish a reset schedule or guaranteed coverage. - New historical imports require verifiable evidence of a completed reset, such as an official completion announcement or a measured refill. Speculation, future promises and a bare usage reading of zero do not qualify. Source links and timestamp uncertainty must accompany an import.
Forecast accuracy
liveAccuracy scores forecasts saved before their outcomes, separately for six hours and 24 hours. It starts empty: no earlier predictions are invented or backfilled. Only finished, non-overlapping windows count. status: collecting means fewer than 30 daily windows have been scored; reaching 30 is not proof of accuracy. Error scores are Brier scores, where lower is better.
baselineBrier uses the simple trailing-rate probability saved at the same time. withoutHintsBrier tests removing hint boosts. hintWindows, hintBrier and hintWithoutHintsBrier isolate windows where those boosts changed the probability. smoothHistoryBrier evaluates a candidate with gradually decaying history weights; that candidate does not drive the page. Comparisons cover the same outcomes and up to the last 180 days. Outcomes mean resets in this project's record, not an assertion of complete worldwide coverage.
recording: saved means the returned probabilities are the scheduled publication stored in the journal. unsaved means the recording was missing or stale and the site used its read-only fallback. accuracy remains the historical replay: brierRollingBase and rollingSkill compare against an average using only earlier data; legacy brierBase and skill compare against an average with hindsight. Legacy live* fields identify recent replays, not archived forecasts.
Scoring waits ten minutes after a forecast window closes so reset confirmation and ledger ingestion can arrive before a result is counted.
Freshness and failures
The stats, history and forecast share the website's snapshot, cached inside the Worker for up to five minutes. Poll at most once every 300 seconds. Compare generatedAt to your clock. Health is cached for up to 60 seconds and includes checkedAt.
Health returns HTTP 503 when its observer, primary timeline, cron, or AI configuration is degraded. ai.configured means credentials are configured; it is not a live model test. lastSuccessfulReadAt can be old on a quiet timeline. lastSuccessfulModel is the saved response model version, or the requested alias for older readings.
Data endpoints return HTTP 503 if the complete ledger cannot be read or the snapshot is over ten minutes old. An unavailable timeline or OpenAI status source is reported under sources; it does not erase an otherwise available reset record.
{"error":{"code":"data_unavailable","message":"A fresh, complete reset record is temporarily unavailable."}}
HTTP 400 means invalid parameters, 404 an unknown endpoint, and 405 an unsupported method. On 503, wait for the Retry-After interval (60 seconds). GET, HEAD and OPTIONS are supported. Browser CORS is enabled without credentials. No client request triggers an AI call or an alert.