# RouteViews API Documentation ## Table of Contents * [Introduction](#introduction) * [Access](#access) * [End points not discoverable from API root](#undiscoverable) * [`/asn/`*asn*](#asn) - query routes originated by an Autonomous System * [`/prefix/`*prefix*](#prefix) - query a route (or its parent) in the RIB * [`/rib/collectors`](#rib_collectors) - get list of collectors for which we have current RIB information * [RPKI query](#rpki) - query validation state for a prefix or for an ASN * [End points discoverable from API root](#discoverable) * [collector](#collector) - a list of RouteViews Collectors in operation * [peer](#peer) - individual peer listings * [peering](#peering) - peering statistics per peer/collector * [timeseries](#timeseries) - peering counts over time * [rirtimeseries](#rirtimeseries) - rir grouped peering counts over time * Appendices * [Author Goals](#author) ## <a id="introduction"></a> Introduction Welcome to the RouteViews API reference guide. This guide documents the access details of our API, and gives examples of common use cases. The RouteViews API is intended for network operators and researchers who need to make regular access to _current_ RouteViews data as part of their monitoring of the global routing system. The API is not intended for deep historical queries; the [MRT archive](https://archive.routeviews.org) combined with tools from [BGPKIT](https://bgpkit.com/parser) and [CAIDA](https://bgpstream.caida.org/) are recommended for this use case. Historically the RouteViews collectors have offered command line access for network operators to make quick checks about BGP announcements and general reachability information. However, with the continue growth of the Internet, and the ever increasing size of both the IPv4 and IPv6 routing tables, this direct command line access is putting an increasing burden on the RouteViews collector infrastructure. The API replaces this regular (automated) access that many operators and researchers use, and supplements the BGP UPDATES and RIB dumps that are stored on our BGP data archive at https://archive.routeviews.org. Currently, the API gives access to a subset of the RouteViews global collector infrastructure, using the latest data as seen at the following exchanges: Exchange | collector ---------|----------- AMS-IX | route-views.amsix.routeviews.org LINX | route-views.linx.routeviews.org NAPAfrica | route-views.napafrica.routeviews.org Equinix Sydney | route-views.sydney.routeviews.org Multi-hop at U of Oregon | route-views3.routeviews.org Multi-hop at U of Oregon | route-views6.routeviews.org We will add more exchanges as the infrastructure that supports the API is scaled up. ## <a id="access"></a> Access The API can be accessed without authentication as a guest user, with severe rate limits to the usage (currently 1 API call per second). In order to relax these limits, the API users must authenticate themselves via the API key mechanism. [The API key management](https://api.routeviews.org/member-area/key-management) is available to any user authenticated through [PeeringDB](https://www.peeringdb.com/). The HTTP header to use for passing API keys is `Api-Key`, for example: ```sh curl -L -s 'Api-Key: BAD_KEY_.SOME-LONG-NONSENSICAL-STRING-111' "https://api.routeviews.org/rib/collectors" ``` Rate limit for valid keys is 10 API calls per second. Supplying a non-existing key returns an error. Supplying no key at all is allowed, but, as mentioned above, with severe rate limits. ## <a id="undiscoverable"></a> Endpoints currently not discoverable via API root There are three endpoints not currently discoverable from the API root | Term | Explanation | |---|---| | [ASN](#asn) | query routes originated by an Autonomous System | | [Prefix](#prefix) | query a route (and any parent) in the RIB | | [RPKI](#rpki) | query validation state for a prefix or for an ASN | ### <a id="asn"></a>Autonomous System Number To find out all the routes originated by an Autonomous System, the following syntax is used (using AS4608 as an example): ```sh curl -L -s "https://api.routeviews.org/asn/4608" | jq . ``` which gives a response like this: ```json [ "103.0.0.0/16", "202.12.29.0/24", "203.119.76.0/23", "203.119.76.0/24", "203.119.77.0/24", "203.119.100.0/22", "203.119.104.0/21", "203.133.248.0/23", "203.133.248.0/24", "203.133.249.0/24", "2001:dc0:2000::/35", "2001:dc0:a000::/35", "2001:dc0:e000::/35", "2001:dd8:8::/48", "2001:dd8:9::/48", "2001:dd8:a::/48", "2001:dd8:b::/48", "2001:dd8:c::/48", "2001:dd8:d::/48", "2001:dd8:f::/48", "2401:2000::/32", "2401:2000:6000::/35", "2408:2000::/24" ] ``` It is possible to request routes of a certain address family. For this, use the `af` parameter, which can take the following values: `4`, `6`, `IPv4`, `IPv6`, for example: ```sh curl -L -s "https://api.routeviews.org/asn/4608?af=4" | jq . ``` resulting in ```json [ "103.0.0.0/16", "202.12.29.0/24", "203.119.76.0/23", "203.119.76.0/24", "203.119.77.0/24", "203.119.100.0/22", "203.119.104.0/21", "203.133.248.0/23", "203.133.248.0/24", "203.133.249.0/24" ] ``` and ```sh curl -L -s "https://api.routeviews.org/asn/4608?af=6" | jq . ``` resulting in ```json [ "2001:dc0:2000::/35", "2001:dc0:a000::/35", "2001:dc0:e000::/35", "2001:dd8:8::/48", "2001:dd8:9::/48", "2001:dd8:a::/48", "2001:dd8:b::/48", "2001:dd8:c::/48", "2001:dd8:d::/48", "2001:dd8:f::/48", "2401:2000::/32", "2401:2000:6000::/35", "2408:2000::/24" ] ``` ### <a id="prefix"></a>Prefix To find out about a prefix (or its closest match/parent) in the RIB, the following syntax is used (using 128.223.51.103/32 as an example): ```sh curl -L -s "https://api.routeviews.org/prefix/128.223.51.103/32" | jq ``` which produces the response: ```json [ { "prefix": "128.223.0.0/16", "origin_asn": 3582, "rpki_state": "not-found", "rpki_roas": null, "reporting_peers": [ { "peer_asn": 267613, "peer_addr": "195.66.226.39", "collector": "route-views.linx", "as_path": "267613 52320 6461 11164 3701 3582 3582 3582 3582 3582 3582", "communities": "5469:11000 5469:10850 5469:2200", "timestamp": "2024-07-09T10:00:06Z" }, { "peer_asn": 1031, "peer_addr": "195.66.231.48", "collector": "route-views.linx", "as_path": "6447 1031 174 3701 3701 3701 3701 3582 3582 3582 3582 3582 3582", "communities": "1031:701 1031:800 1031:802", "timestamp": "2024-07-12T02:47:21Z" }, ... { "peer_asn": 34177, "peer_addr": "80.249.210.38", "collector": "route-views.amsix", "as_path": "6447 34177 3356 3701 3701 3701 3701 3701 3582 3582 3582 3582 3582 3582", "communities": "", "timestamp": "2024-07-13T10:49:43Z" } ] } ] ``` This lists every single instance of the prefix via every path on every collector supported by this API. The `/prefix` call returns ALL matching prefixes, with the results grouped by prefix+origin_asn, and sorted by the same combination key, with the longest match first. The same query syntax is used for IPv6 (we don't require the request to specify which address family): ```sh curl -L -s "https://api.routeviews.org/prefix/2001:468:d01:33::80df:3367/128" | jq ``` which produces: ```json [ { "prefix": "2001:468:d01::/48", "origin_asn": 3582, "rpki_state": "not-found", "rpki_roas": null, "reporting_peers": [ { "peer_asn": 18106, "peer_addr": "2001:d98::19", "collector": "route-views6", "as_path": "18106 3701 3582 3582 3582 3582 3582 3582", "communities": "33108:3000", "timestamp": "2024-07-09T10:00:00Z" }, { "peer_asn": 20912, "peer_addr": "2001:40d0::1e", "collector": "route-views6", "as_path": "6447 20912 6939 3701 3582 3582 3582 3582 3582 3582", "communities": "", "timestamp": "2024-07-12T02:32:57Z" }, ... }, { "prefix": "2001:468:d00::/40", "origin_asn": 4600, "rpki_state": "not-found", "rpki_roas": null, "reporting_peers": [ { "peer_asn": 41805, "peer_addr": "2001:7f8:1::a504:1805:1", "collector": "route-views.amsix", "as_path": "6447 3257 174 53013 52840 13786 6939 2152 2153 4600", "communities": "3257:56601 3257:30516 3257:8838 3257:56600 3257:50003", "timestamp": "2024-07-13T09:34:37Z" }, ... ] }, { "prefix": "::/0", "origin_asn": 18106, "rpki_state": "not-found", "rpki_roas": null, "reporting_peers": [ { "peer_asn": 53767, "peer_addr": "2605:9d00::2", "collector": "route-views6", "as_path": "18106", "communities": "", "timestamp": "2024-07-09T10:00:00Z" } ] } ] ``` Note the hierachy here: 1. We looked up 2001:468:d01:33::80df:3367/128 2. This /128 is a subnet of 2001:468:d01::/48 which is announced by AS3582. 3. 2001:468:d01::/48 is a subnet of 2001:468:d00::/40 which is originated by AS4600 4. And because AS18106 is sending RouteViews the IPv6 default route, it is a parent of 2001:468:d00::/40 and is also included in the list. 5. Note that 2001:468::/32 is an assigment by ARIN, but the /32 is not announced to the global routing table. ### <a id="rib_collectors"></a> `/rib/collectors` To get a list of collectors for which the API has current RIB information (see `/prefix` and `/asn` above), the following syntax is used: ```sh curl -L -s "https://api.routeviews.org/rib/collectors" | jq . ``` which produces the response: ```json [ "route-views.amsix", "route-views.linx", "route-views.napafrica", "route-views.sydney", "route-views3", "route-views6" ] ``` ### <a id="rpki"></a> RPKI The API can also provide the validation state of any specific prefix or for all the prefixes originated by an ASN. The RPKI validation information is from the point of view of `frr.routeviews.org` which receives two views of the full IPv4 & IPv6 BGP tables from the University of Oregon, and receives validation information from two validators ([NLnetLabs Routinator 3000](https://www.nlnetlabs.nl/projects/routing/routinator/) and [RPKI-client/StayRTR](https://github.com/bgp/stayrtr/). To query the validation state of any single prefix, use this syntax: ```sh curl -L -s "https://api.routeviews.org/rpki?prefix=43.224.43.0/24" | jq . ``` which gives this response: ```json { "43.224.43.0/24": { "asn": [ { "45558": "invalid" } ], "timestamp": "2024-07-13T04:07:01.653+00:00" } } ``` showing that this particular prefix is _invalid_. Here is an example of a prefix with validation state _notfound_: ```sh curl -L -s "https://api.routeviews.org/rpki?prefix=2001:44b8::/32" | jq . ``` giving a result of: ```json { "2001:44b8::/32": { "asn": [ { "4739": "notfound" } ], "timestamp": "2024-07-13T10:07:01.848+00:00" } } ``` And finally here is an example of a prefix with validation state _valid_: ```sh curl -L -s "https://api.routeviews.org/rpki?prefix=1.1.1.0/24" | jq . ``` giving a result of: ```json { "1.1.1.0/24": { "asn": [ { "13335": "valid" } ], "timestamp": "2024-07-13T10:07:01.848+00:00" } } ``` To find out the validation state of prefixes originated by any specific autonomous system, the following syntax is used: ```sh curl -L -s "https://api.routeviews.org/rpki?asn=44869" | jq . ``` which produces the following output: ```json { "44869": { "prefix": [ { "5.103.0.0/16": "valid" }, { "5.186.0.0/16": "valid" }, { "37.122.240.0/21": "valid" }, { "46.21.32.0/20": "valid" }, { "77.33.0.0/16": "valid" }, { "78.143.64.0/18": "valid" }, { "80.71.64.0/19": "valid" }, { "80.208.0.0/17": "valid" }, { "80.209.0.0/17": "valid" }, { "87.104.0.0/18": "valid" }, { "89.239.192.0/18": "valid" }, { "212.178.160.0/19": "valid" }, { "2a02:17c0::/32": "valid" } ], "timestamp": "2024-07-13T04:07:01.653+00:00" } } ``` ## <a id=discoverable></a>Endpoints discoverable from API root The following table lists the API Root Options (all discoverable from the API root). | Term | Explanation | |---|---| | [collector](#collector) | a list of RouteViews Collectors in operation | | [peer](#peer) | individual peer listings | | [peering](#peering) | peering statistics per peer/collector | | [timeseries](#timeseries) | peering counts over time| | [rirtimeseries](#rirtimeseries) | rir grouped peering counts over time | Please Note: Output is paginated. (**TODO**: Is there a way to get all peers in one req, or if we aren't doing that?) Links are provided for the next and previous page in the output. Using any other query field appears to not paginate the response (or I have not hit the limit for pagination in my testing) ### Request ```sh curl -L -s "https://api.routeviews.org/peer/?page=4" | jq . ``` ### Response ```json { "count": 1435, "next": "https://api.routeviews.org/peer/?page=5", "previous": "https://api.routeviews.org/peer/?page=3", "results": [ { "url": "https://api.routeviews.org/peer/301/", "name": "EDGEUNO SAS, CO", "ip": "206.126.238.207", "asn": "7195", "rir": "lacnic", "country_code": "CO" }, ``` ## <a id="collector"></a> collector Schema: operationId: listCollectors | Name | Description | Example | |---|---|---| | url | link to collector by 'id' | https://api.routeviews.org/collector/44/ | | name | name of the collector | pitmx.qro | | label | label used on collector | pitmx.qro | | type | Routing Daemon in service (FRR/Quagga/Cisco) | FRR | | lat | latitude | 20.56710440 | | lng | longitude | -100.25827800 | | country | ISO-3166 country code | MX | | rir_region | RIR region (AFRINIC/APNIC/ARIN/LACNIC/RIPE NCC) | LACNIC | | ipv4 | peering interface IPv4 address | 200.23.206.183 | | ipv6 | peering interface IPv6 address | 2803:3440:9025::6447:1 | | bmp | running bmp (0 &#124; 1) | 1 | | ix_speed | Speed of the peering interface | 10000 | | installed | date of installation | 2024-02-23T22:15:00Z | | removed | date of decommissioning | null | | scamper | is participating in scamper (0 &#124; 1) | 1 | ### Collector example Queries Example: List all FRR collectors in the LACNIC Region #### Request ```sh $ curl -L -s "https://api.routeviews.org/collector/?rir_region=LACNIC&type=frr" | jq . ``` #### Response ```json { "count": 7, "next": null, "previous": null, "results": [ { "url": "https://api.routeviews.org/collector/2/", "name": "route-views.chile", "label": "chile", "type": "FRR", "lat": "-33.43970500", "lng": "-70.64541600", "country": "CL", "rir_region": "LACNIC", "ipv4": "200.16.114.60", "ipv6": "2001:1398:32:177::60", "bmp": 1, "rpki": 1, "ix_speed": 1000, "multihop": 0, "installed": "2018-01-31T20:00:00Z", "removed": null, "scamper": 1 }, { "url": "https://api.routeviews.org/collector/8/", "name": "route-views2.saopaulo", "label": "saopaulo2", "type": "FRR", "lat": "-23.54598800", "lng": "-46.63583600", "country": "BR", "rir_region": "LACNIC", "ipv4": "187.16.219.166", "ipv6": "2001:12f8::219:166", "bmp": 1, "rpki": 1, "ix_speed": 1000, "multihop": 0, "installed": "2018-04-25T18:00:00Z", "removed": null, "scamper": 1 }, { "url": "https://api.routeviews.org/collector/9/", "name": "route-views.rio", "label": "rio", "type": "FRR", "lat": "-22.95172800", "lng": "-43.21047600", "country": "BR", "rir_region": "LACNIC", "ipv4": "45.6.52.213", "ipv6": "2001:12f8:0:2::213", "bmp": 1, "rpki": 1, "ix_speed": 1000, "multihop": 0, "installed": "2019-05-31T21:34:00Z", "removed": null, "scamper": 1 }, { "url": "https://api.routeviews.org/collector/10/", "name": "route-views.fortaleza", "label": "fortaleza", "type": "FRR", "lat": "-3.73478700", "lng": "-38.45800800", "country": "BR", "rir_region": "LACNIC", "ipv4": "200.219.146.184", "ipv6": "2001:12f8:0:9::184", "bmp": 1, "rpki": 1, "ix_speed": 1000, "multihop": 0, "installed": "2019-05-31T21:44:00Z", "removed": null, "scamper": 1 }, { "url": "https://api.routeviews.org/collector/35/", "name": "route-views.peru", "label": "peru", "type": "FRR", "lat": "-12.12544000", "lng": "-76.97743200", "country": "PE", "rir_region": "LACNIC", "ipv4": "45.183.47.201", "ipv6": "2803:cd60:6411:5::ab", "bmp": 1, "rpki": 1, "ix_speed": 1000, "multihop": 0, "installed": "2021-06-23T05:30:00Z", "removed": null, "scamper": 1 }, { "url": "https://api.routeviews.org/collector/42/", "name": "pit.scl", "label": "pit.scl", "type": "FRR", "lat": "-33.44748700", "lng": "-70.67367600", "country": "CL", "rir_region": "LACNIC", "ipv4": "45.68.17.253", "ipv6": "2801:14:9000::6447:1", "bmp": 1, "rpki": 1, "ix_speed": 10000, "multihop": 0, "installed": "2023-08-31T23:45:00Z", "removed": null, "scamper": 0 }, { "url": "https://api.routeviews.org/collector/44/", "name": "pitmx.qro", "label": "pitmx.qro", "type": "FRR", "lat": "20.56710440", "lng": "-100.25827800", "country": "MX", "rir_region": "LACNIC", "ipv4": "200.23.206.183", "ipv6": "2803:3440:9025::6447:1", "bmp": 1, "rpki": 1, "ix_speed": 10000, "multihop": 0, "installed": "2024-02-23T22:15:00Z", "removed": null, "scamper": 0 } ] } ``` Example : List all collectors in a country (NL) #### Request ```sh curl -L -s "https://api.routeviews.org/collector/?country=NL" | jq . ``` #### Response ```json { "count": 2, "next": null, "previous": null, "results": [ { "url": "https://api.routeviews.org/collector/11/", "name": "route-views.amsix", "label": "amsix", "type": "FRR", "lat": "52.36060700", "lng": "4.89814300", "country": "NL", "rir_region": "RIPE NCC", "ipv4": "80.249.214.5", "ipv6": "2001:7F8:1::A500:6447:1", "bmp": 1, "rpki": 1, "ix_speed": 1000, "multihop": 0, "installed": "2018-07-11T23:19:00Z", "removed": null, "scamper": 1 }, { "url": "https://api.routeviews.org/collector/43/", "name": "amsix.ams", "label": "amsix.ams", "type": "FRR", "lat": "52.36060700", "lng": "4.89814300", "country": "NL", "rir_region": "RIPE NCC", "ipv4": "80.249.213.84", "ipv6": "2001:7f8:1::a500:6447:2", "bmp": 1, "rpki": 1, "ix_speed": 100, "multihop": 0, "installed": "2024-02-22T23:20:00Z", "removed": null, "scamper": 0 } ] } ``` ## <a id="peer"></a> peer Schema: operationId: listPeers | Name | Description | Example | |---|---|---| | url | url pointing to specific peer id | https://api.routeviews.org/peer/1/ | | name | Description of the peer | DCMSB-AS-AP DE CIX MALAYSIA SDN. BHD., MY | | ip | IP Address (IPv4 or IPv6 address) | 103.119.232.252 | | asn | The ASN of the peer | 38175 | rir | The RIR region that the peer is in | apnic | | country_code | ISO-3166 country code | MY | Example : List all peers for a given ASN (2914) #### Request ```sh % curl -L -s "https://api.routeviews.org/peer/?asn=2914" | jq . ``` #### Response ```json { "count": 8, "next": null, "previous": null, "results": [ { "url": "https://api.routeviews.org/peer/1038/", "name": "NTT-LTD-2914, US", "ip": "129.250.1.248", "asn": "2914", "rir": "arin", "country_code": "US" }, { "url": "https://api.routeviews.org/peer/46/", "name": "NTT-LTD-2914, US", "ip": "129.250.1.71", "asn": "2914", "rir": "arin", "country_code": "US" }, { "url": "https://api.routeviews.org/peer/441/", "name": "NTT-LTD-2914, US", "ip": "195.66.224.138", "asn": "2914", "rir": "arin", "country_code": "US" }, { "url": "https://api.routeviews.org/peer/1072/", "name": "NTT-LTD-2914, US", "ip": "2001:418:0:1000::f000", "asn": "2914", "rir": "arin", "country_code": "US" }, { "url": "https://api.routeviews.org/peer/1053/", "name": "NTT-LTD-2914, US", "ip": "2001:418:0:1000::f003", "asn": "2914", "rir": "arin", "country_code": "US" }, { "url": "https://api.routeviews.org/peer/305/", "name": "NTT-LTD-2914, US", "ip": "2001:504:0:2::2914:1", "asn": "2914", "rir": "arin", "country_code": "US" }, { "url": "https://api.routeviews.org/peer/486/", "name": "NTT-LTD-2914, US", "ip": "2001:7f8:4::b62:1", "asn": "2914", "rir": "arin", "country_code": "US" }, { "url": "https://api.routeviews.org/peer/270/", "name": "NTT-LTD-2914, US", "ip": "206.126.236.12", "asn": "2914", "rir": "arin", "country_code": "US" } ] } ``` ## <a id="peering"></a> peering Schema operationId: listPeerings | Name | Description | Example | |---|---|---| | url | link to specific entry by id | https://api.routeviews.org/peering/44/ | | prefix_count | number of prefixes received | 940830 | | date | date of last measurement | 2024-01-11T00:00:00Z | | coverage | **CHECK THIS, APPEARS TO BE A % of high tide of prefix count** | 0.821557 | | collector | link to specific collector by id | https://api.routeviews.org/collector/3/ | | peer | links top specific peer by id | https://api.routeviews.org/peer/44/ | only the general peering/ and peering/{id} are currently supported ## <a id="timeseries"></a>timeseries Schema: operationId: retrieveTimeseries | Name | Description | Example | |---|---|---| | url | unique id link for timeseries | https://api.routeviews.org/timeseries/4/ | | collector | name of collector | route-views2 | | date | date of measurement | 2001-10-28T08:28:08Z | | ipv4_peer_count | number of IPv4 peers | 17 | | ipv4_rib_count | number of prefixes in rib | 3256816 | | ipv6_peer_count | number of IPv4 peers | 0 | | ipv6_rib_count | number of prefixes in rib | 0 | | ipv4_prefix_count | number of routes in fib | 107469 | | ipv6_prefix_count | number of routes in fib | 0 | Looks like we can't search on the collector name, not implemented (might be deliberate) #### Request ```sh $ curl -L -s "https://api.routeviews.org/timeseries/?collector=route-views2" ``` #### Response ```json { "collector": [ "Select a valid choice. That choice is not one of the available choices." ] } ``` ## <a id="rirtimeseries"></a> rirtimeseries schema: operationID: retrieveRirTimeseries | Name | Description | Example | |---|---|---| | url | unique id for record | https://api.routeviews.org/rirtimeseries/2/ | collector | name of collector | route-views2 | | date | date/time for record | 2001-10-26T23:48:06Z | | afrinic_v4_peer_count | IPv4 RIR peer count | 0 | afrinic_v6_peer_count | IPv6 RIR peer count | 0 | arin_v4_peer_count | IPv4 RIR peer count | 14 | arin_v6_peer_count | IPv6 RIR peer count | 0 | apnic_v4_peer_count | IPv4 RIR peer count | 0 | apnic_v6_peer_count | IPv6 RIR peer count | 0 | lacnic_v4_peer_count | IPv4 RIR peer count | 0 | lacnic_v6_peer_count | IPv6 RIR peer count | 0 | ripencc_v4_peer_count | IPv4 RIR peer count | 3 | ripencc_v6_peer_count | IPv6 RIR peer count | 0 I cannot query for collector here currently. ## Appendices ### <a id="author"></a>Goals for the author * start out with basic testing and descriptions for the API (using the schema in the repo for guidance) * document any potential gotchas * don't hammer the API just yet * offer suggestions where appropriate * 'prettify' this into static documentation