RPKI History

An API to query historical RPKI data, more specifically, Validated ROA Payloads (VRPs).

Links:

We obtain VRP data from the RPKI Views project and store it in a compact form for fast access. From each dump we extract the output/rpki-client.csv file, which contains just the VRPs, and update our database.

A VRP entry consists of five fields:

ASN,IP Prefix,Max Length,Trust Anchor,Expires
AS13335,1.0.0.0/24,24,apnic,1753280249

We ignore the expiry time and only work on dump-time granularity. For each ingested dump we compare the set of VRPs (in form of asn, prefix, max_length) with the previous dump. Each VRP has a visible time range, during which is was continuously visible. Since most VRPs are stable, this allows us to update just the time range, keeping the database size compact.

Data limitations:

Data sources:

Endpoints

/vrp

Returns the list of covering VRPs for a prefix at a specific time, time range, or at the latest dump time if no time parameter is specified.

Parameters

Mandatory:

There are two types of time parameters, which are mutually exclusive: Point-in-time and time range. For a time range only one bound can be specified, in which case the returned list will include all earlier/later data available.

Point-in-time:

Time range:

Result Format

// https://www.ihr.live/rpki-history/api/vrp?prefix=8.8.8.0/24
[
  {
    "prefix": "8.8.8.0/24",
    "asn": 15169,
    "max_length": 24,
    "visible": {
      "from": "2023-12-29T17:30:54+00:00",
      "to": "2025-08-13T06:29:10+00:00"
    }
  }
]

visible refers to the timespan during which the VRP was continuously visible, i.e., present in the dumps. Thus, if a VRP is missing from a dump, a new entry with a separate visible range is created. This time is unrelated to the validity time (Not before/Not after) of the ROA!

/status

Returns the RPKI status for the specified prefix/ASN combination at the specified time, or at the latest dump time if no timestamp is specified.

Parameters

Mandatory:

Optional:

Result Format

// https://www.ihr.live/rpki-history/api/status?prefix=8.8.8.0/24&asn=15169
{
  "status": "Valid"
}

// https://www.ihr.live/rpki-history/api/status?prefix=8.8.8.0/25&asn=15169
{
  "status": "Invalid",
  "reason": {
    "code": "moreSpecific",
    "description": "Covering VRP with matching origin ASN found, but queried prefix is more specific than maxLength attribute allows."
  }
}

status is one of [Valid, Invalid, NotFound].

reason (only for Invalid status) gives more detailed information about why the status is invalid. code is for automatic processing, while description provides a human-readable explanation.

/metadata

Returns the list of dumps contained in the database. Since this list is very long, this endpoint is paginated and returns at most 10000 results per page.

Parameters

Mandatory: None

Optional:

Result Format

// https://www.ihr.live/rpki-history/api/metadata
{
  "next": "https://www.ihr.live/rpki-history/api/metadata?page_size=1000&page=2",
  "results": [
    {
      "timestamp": "2020-12-06T16:37:23+00:00",
      "deleted_vrps": 0,
      "unchanged_vrps": 0,
      "new_vrps": 205850
    },
    // ...
  ]
}

next is the URL to the next page. It will be an empty string if there are no results left.

timestamp refers to the dump time (taken from the filename).

[deleted|updated|new]_vrps indicates the number of VRPs differing from the previous dump. Note that deleted refers to a VRP that was present in the previous dump, but not in the current one.

Database Dump

For easier analysis of the dataset, or self-hosting, a dump of the database (updated weekly) is available.

Self-hosting

If for some reason you want to host your own version of this page, here is how.

Getting Started

Create secrets files containing the Postgres user passwords.

# For normal user
touch ./secrets/postgres-pw.txt
# For read-only user
touch ./secrets/postgres-ro-pw.txt
# Of course write actual passwords to these files...

Initialize database. This will also build the initial Docker image, which might take some time.

docker compose run --rm init-db

Optional: Restore database dump.

docker compose exec -T database pg_restore -d rpki_history < rpki-history.dump

Optional (but recommended): Create an index over the prefix column to greatly decrease query time. This is not built into the init-db script, since it is faster to build the index once after all data was imported.

docker compose exec database psql -c "CREATE INDEX ON vrps USING gist (prefix inet_ops)"

Start the API server.

docker compose up -d api

Updating the Data

To import the latest available data (uses RPKIViews by default):

docker compose run --rm update-db

For more usage options (e.g., importing a specific timestamp):

docker compose run --rm update-db --help

Backup/restore Database

Backup

docker compose exec database pg_dump --data-only -Fc > rpki-history.dump

Restore

Assumes fresh install or that postgres_data volume was deleted.

# Reinitialize database to create schema *and additional user*.
docker compose run --rm init-db
# Restore data
docker compose exec -T database pg_restore -d rpki_history < rpki-history.dump