Skip to content

archive ​

21 endpoints at a glance
MethodPathSummary
POST/atlas/probes-archive/refresh/Refresh Probes Archive
GET/probes-archive/{date}/Get For Date
GET/probes-archive/daily/List Daily
GET/probes-archive/daily/{date}/Get Daily
POST/probes-archive/daily/{date}/recompute-statsRecompute Daily Stats
POST/probes-archive/daily/{date}/runRun Daily
POST/probes-archive/daily/{date}/stopStop Daily
POST/probes-archive/daily/backfillSubmit Backfill
POST/probes-archive/daily/backfill-stale-statsBackfill Stale Daily Stats
POST/probes-archive/daily/backfill/recover-staleRecover Stale Backfill
GET/probes-archive/daily/backfill/statusGet Backfill Status
POST/probes-archive/daily/recompute-allRecompute All Daily Stats
POST/probes-archive/daily/recompute-stats-rangeRecompute Daily Stats Range
POST/probes-archive/daily/seed-first-seenSeed First Seen
GET/probes-archive/daily/stats-coverageDaily Stats Coverage
GET/probes-archive/deployment-filters/Get Deployment Filters
GET/probes-archive/deployment-movers/Get Deployment Movers
GET/probes-archive/deployment-series/Get Deployment Series
GET/probes-archive/overview-stats/Get Overview Stats
GET/probes-archive/probes/{probe_id}/Get For Probe
GET/probes-archive/series/Get Series

archive​

Retrieve historical data


List Daily​

GET
/probes-archive/daily/

Newest-first list of daily-summary rows.

Admin-gated because the rows carry error tracebacks. Optional
since / until are inclusive YYYY-MM-DD bounds; limit
clamped to 1000 by the storage layer.

lite=true projects away the heavy stats block and the
error traceback — useful for whole-year fetches like the
admin calendar view where only the per-day status pill is
rendered. Drops a year-wide payload from ~3 MB to ~50 KB.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

since
until
limit
Type
integer
Default
100
lite
Type
boolean
Default
false

Responses​

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground​

Headers
Variables
Key
Value

Samples​


Get Daily​

GET
/probes-archive/daily/{date}/

Single daily-summary row including the full stats block.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

date*
Type
string
Required

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Variables
Key
Value

Samples​


Stop Daily​

POST
/probes-archive/daily/{date}/stop

Stop a queued or running daily import (cooperative).

queued → import_day's entry-check writes a terminal
stopped row without importing. running → the per-batch
checkpoint bails, finishing as stopped with the probe rows
that already landed preserved (stats deliberately not recomputed
over a partial import — re-backfill the date for a clean stats
block). Already-terminal / missing → 409 / 404.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

date*
Type
string
Required

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Variables
Key
Value

Samples​


Run Daily​

POST
/probes-archive/daily/{date}/run

Synchronous import-run for one date — admin cookie-session.

Blocks for the duration of the import (~minutes for ~50k probes).
Same audit wiring as the api-key-gated
POST /atlas/probes-archive/refresh/ endpoint in
:mod:api.main — both go through :func:run_and_record so
db.task_history and db.probes_archive_daily stay in sync.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

date*
Type
string
Required

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Variables
Key
Value

Samples​


Recompute Daily Stats​

POST
/probes-archive/daily/{date}/recompute-stats

Rebuild the stats block for one date from saved archive rows.

No RIPE call — reads only db.probes_archive. Useful when the
stats schema gains new fields (e.g. cross-tabs added later) and
historical rows need backfilling, or when an operator just wants
fresh numbers without paying the import cost.

Fast (~seconds) — runs synchronously and returns the updated
daily summary directly. Wrapped in :func:run_and_record so the
operation lands in db.task_history alongside the normal
import runs.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

date*
Type
string
Required

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Variables
Key
Value

Samples​


Recompute Daily Stats Range​

POST
/probes-archive/daily/recompute-stats-range

Rebuild the stats block for every date in a window.

No RIPE call — reads only db.probes_archive and rewrites each
daily summary's stats / probes_count / stats_recomputed_at
in place. Loops :meth:ProbesArchive.recompute_stats across the
range; dates with no archive rows or no daily-summary row are
surfaced as skipped entries rather than aborting the run.

Synchronous on purpose — per-date recompute is ~seconds (it's
just $group aggregations against an already-indexed
collection), and the
:attr:ProbesArchive.RECOMPUTE_RANGE_MAX_DAYS cap keeps the
worst-case request inside the frontend's long-running HTTP
timeout. Operators wanting a wider rebuild chunk the submission.

Wrapped in :func:run_and_record so the bulk job lands as a
single entry in db.task_history (one row per range, not one
per date — the per-date trail lives in stats_recomputed_at
on each daily-summary row).

Parameters​

Header Parameters

authorization
x-api-key

Request Body​

application/json
JSON
{
  
"since": "string",
  
"until": "string"
}

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Body

Samples​


Recompute All Daily Stats​

POST
/probes-archive/daily/recompute-all

Unconditionally recompute every daily-stats row across the
full history — fire-and-forget.

The "fix everything" lever, distinct from the stale-drain: it
rebuilds all days regardless of their schema/freshness
classification, so days wrongly stamped current under an
earlier/incomplete first_seen (the cause of a flat new_probes
history after a seed) actually get corrected — something
backfill-stale-stats and the drain cron can't do, since they only
touch days still classified stale.

No RIPE call (DB-only $group recompute), idempotent, and empty
days seal as they go. A full ~10-year rebuild runs well past the
gateway timeout, so it's handed to a background task — one
recompute_probes_archive_stats_all row in db.task_history —
and returns immediately. Poll
GET /probes-archive/daily/stats-coverage (or watch the
New-probes graph fill in) for progress. The 15-min drain cron keeps
it current afterwards.

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers

Samples​


Seed First Seen​

POST
/probes-archive/daily/seed-first-seen

One-time backfill of db.probes_archive_first_seen from the
full archive.

Required after deploy because the daily stats' new_probes /
by_country_new now read from this cache instead of the
full-collection $group that was hitting the Mongo socket-
timeout cliff. Walks year by year (each $group bounded to one
year's slice) and $min-upserts into the cache — idempotent
and safe to re-run.

Fire-and-forget: a full-archive rebuild scans many years of rows
and runs well past the gateway timeout (a single full year already
does), so the work is handed to a background task — wrapped in
:func:run_and_record as one seed_probes_archive_first_seen
(trigger=manual) row — and the request returns {"status": "started"} immediately. Poll
GET /task-history/?task_name=seed_probes_archive_first_seen
for the result counters / completion.

since / until (YYYY or YYYY-MM-DD) narrow the seed
to a sub-range; a bare year is widened to that year's full span.
A malformed bound is rejected synchronously (400) before the job
is scheduled.

Parameters​

Header Parameters

authorization
x-api-key

Request Body​

application/json
JSON
{
  
"since": "string",
  
"until": "string"
}

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Body

Samples​


Daily Stats Coverage​

GET
/probes-archive/daily/stats-coverage

Per-class daily-stats coverage over the retained window.

Pure read — one indexed date-range scan, no recompute.
Returns the :meth:ProbesArchive.stats_coverage blob
(schema_version + counts of
missing/stale_schema/stale_data/current +
stale_dates). 400 on a bad / inverted range.

Parameters​

Header Parameters

authorization
x-api-key

Query Parameters

since

inclusive start, YYYY-MM-DD

until

inclusive end, YYYY-MM-DD

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Variables
Key
Value

Samples​


Backfill Stale Daily Stats​

POST
/probes-archive/daily/backfill-stale-stats

Force an immediate newest-first recompute of stale daily-stats.

The on-demand burst counterpart to the drain cron — use right
after a deliberate STATS_SCHEMA_VERSION bump to converge now
rather than waiting for the cron to grind through. DB-only,
idempotent, bounded (max_days server-clamped). Wrapped in
:func:run_and_record so it lands in db.task_history.

Parameters​

Header Parameters

authorization
x-api-key

Request Body​

application/json
JSON
{
  
"max_days": 1000
}

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Body

Samples​


Submit Backfill​

POST
/probes-archive/daily/backfill

Queue a date range for serial backfill.

Returns immediately with the list of dates that were queued.
status: "queued" rows are pre-inserted into
db.probes_archive_daily so the admin dashboard's heatmap
reflects the submission right away. The in-process worker then
pulls one date at a time and runs import_day against it; each
run audits to db.task_history with trigger: "backfill".

The queue lives in process memory — a backend restart drops
pending entries, but the pre-inserted queued rows survive,
and re-submitting the same range picks up where the worker left
off (the dates that already succeeded are filtered out by
only_missing=true).

Parameters​

Header Parameters

authorization
x-api-key

Request Body​

application/json
JSON
{
  
"since": "string",
  
"until": "string",
  
"only_missing": true
}

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers
Body

Samples​


Get Backfill Status​

GET
/probes-archive/daily/backfill/status

Worker queue depth, currently-importing date, and liveness.

All three fields are best-effort snapshots — by the time the
response reaches the client the worker may have advanced. The
dashboard already polls daily rows for status transitions; this
endpoint is for the queue-depth badge and the worker-alive
tripwire that surfaces the recovery button.

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

application/json
JSON
{
  
"queued": 0,
  
"in_flight": "string",
  
"worker_alive": true
}

Playground​

Headers

Samples​


Recover Stale Backfill​

POST
/probes-archive/daily/backfill/recover-stale

Re-queue any rows stuck in running / queued state.

The in-process worker's queue lives in memory — a backend
restart drops it, but the queued / running rows it was
tracking persist in db.probes_archive_daily. The same
recovery runs automatically at worker startup; this endpoint
covers the rare follow-up case where the worker task died
silently while the backend kept running, leaving the queue
stranded.

Safe to call any time. :meth:ProbesArchive.import_day is
idempotent (per-(probe, day) upserts plus a daily-summary
rewrite), so re-running over a date that's part-imported
completes it; re-running over a fully-imported date is a no-op
against the per-probe collection and a fresh recompute of the
stats block.

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers

Samples​


Get Series​

GET
/probes-archive/series/

Daily stats blob across a date range, oldest-first.

Drives the operator-facing /graphs/probes-archive trends
view. Each entry in results is one probes_archive_daily
doc with its pre-computed stats block — the trend view's
eight charts (status / capability / ASN-count / new probes /
anchors / country / hardware-generation / region) all hang off
this single fetch.

include_asn=true opts in to the heavy stats.by_asn
distribution (tens-of-thousands of entries per row in the worst
case); default omits it. The scalar stats.asn_count_v4 /
asn_count_v6 counters are always included regardless.

include_missing=true opts in to the
stats.missing_countries + stats.missing_cities coverage
lists. The cities list is ~80 KB per row at the 500k-population
threshold; default omits it to keep the series payload small.
The single-day detail route (/daily/{date}/) always carries
both.

No auth gate — the data is aggregate population counts over
public RIPE info; matches the existing pattern for
/graphs/probes/new and /events/buckets/.

Declared before /{date}/ further down so the literal
series segment can't be mis-routed to the per-day reader.

Parameters​

Query Parameters

since
until
include_asn
Type
boolean
Default
false
include_missing
Type
boolean
Default
false

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Variables
Key
Value

Samples​


Get Deployment Series​

GET
/probes-archive/deployment-series/

Probe count over time — multi-select filters + optional split.

Backs /graphs/probes-archive/deployment. Auto-routes between
the daily-stats fast path (a multi-year fleet line is cheap) and a
bounded raw-aggregation fallback for filter combos the stored
crosstabs can't answer (source says which). Gap days
(missing / non-success import) come back as null so a bad
import never reads as a fleet collapse.

No auth gate — aggregate counts over public RIPE info, same as
/series/. Declared before /{date}/ so the literal segment
can't be mis-routed. 400 on a bad / inverted / over-cap range or
an unsupported metric/dimension combo.

Parameters​

Query Parameters

since
until
country
region
status
asn
split
Type
string
Default
"none"
metric
Type
string
Default
"count"
smooth
Type
integer
Default
0
top_n
Type
integer
Default
0

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Variables
Key
Value

Samples​


Get Deployment Filters​

GET
/probes-archive/deployment-filters/

Selector option lists for the deployment view (countries /
regions / top ASNs from the latest daily row + the fixed RIPE
status set). Single-doc read — instant, no scan. No auth gate.

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Samples​


Get Deployment Movers​

GET
/probes-archive/deployment-movers/

Biggest growers / shrinkers for a dimension over the window
(first-vs-last non-gap day delta from the stored marginals). Pure
daily-stats read, no auth gate. 400 on a bad range / dimension.

Parameters​

Query Parameters

since
until
dimension
Type
string
Default
"country"
limit
Type
integer
Default
15

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Variables
Key
Value

Samples​


Get Overview Stats​

GET
/probes-archive/overview-stats/

Whole-collection top-line for the admin panel — date range,
coverage, total rows, storage size, latest import, probes-per-day
aggregates. See :meth:ProbesArchive.get_overview_stats.

Declared before /{date}/ below so the literal
overview-stats segment doesn't get matched as a date string
and routed to the per-day reader. FastAPI tries routes in
declaration order — keep this above the date-catch.

Parameters​

Header Parameters

authorization
x-api-key

Responses​

Successful Response

application/json
JSON
{
  
"additionalProperties": "string"
}

Playground​

Headers

Samples​


Get For Date​

GET
/probes-archive/{date}/

Per-day list of every probe row.

Capped server-side — full daily list is ~50k rows; limit
clamps to 5000. Use skip for pagination if you really need
everyone.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

date*
Type
string
Required

Query Parameters

skip
Type
integer
Default
0
limit
Type
integer
Default
1000

Responses​

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground​

Headers
Variables
Key
Value

Samples​


Get For Probe​

GET
/probes-archive/probes/{probe_id}/

Per-probe history, oldest-first.

Optional since / until (YYYY-MM-DD) bound the date
range; without them the full history is returned.

Parameters​

Header Parameters

authorization
x-api-key

Path Parameters

probe_id*
Type
integer
Required

Query Parameters

since
until

Responses​

Successful Response

application/json
JSON
[
  
{
  
  
"additionalProperties": "string"
  
}
]

Playground​

Headers
Variables
Key
Value

Samples​


Refresh Probes Archive​

POST
/atlas/probes-archive/refresh/

Import the RIPE probe-archive for one date (default: yesterday).

Synchronous from the caller's perspective — the request blocks for
the duration of the import (~minutes for ~50k probes). Routed
through :func:run_and_record so the run lands in both
db.task_history (operational view) and
db.probes_archive_daily (per-date business view).

Authorizations​

APIKeyQuery
Type
API Key (query: api-key)
or
APIKeyHeader
Type
API Key (header: x-api-key)

Parameters​

Query Parameters

date

Responses​

Successful Response

application/json
JSON
[
]

Playground​

Authorization
Variables
Key
Value

Samples​


Atlas — built on RIPE Atlas data.