9 min read

How to Track ASNs and RIRs in Your Inventory

The two records every network needs, the fields worth storing on each ASN, how to classify public and private numbers, and an audit pipeline you can re-run every quarter from the API.

ByAndré Ribeiro· Founder, Obelinf
How to Track ASNs and RIRs in Your Inventory
How to Track ASNs and RIRs in Your Inventory · October 19, 2026
On this page

An autonomous system number is one of the few identifiers your network keeps for its entire life. It shows up in a BGP configuration, in a registry record, in an RPKI authorization, and in the peering agreement that admits you to an exchange. Yet it is also one of the least tracked, because a bare number looks like something a router knows and a spreadsheet can note in a spare column.

That is where the trouble starts. The number alone does not tell the next engineer which registry issued it, which sites announce it, which providers carry it, or whether it is even public. This is the tracking side of the same problem: the two records to keep, the fields worth storing, and a quarterly audit you can run from the API and diff against last quarter’s output.

At a Glance: Where ASN Records Live

Obelinf Spreadsheet RIR portal only
Registry link ASN references the RIR record A text column, often blank One portal per registry
Public or private Classified automatically Manual, error prone Visible only for public numbers
Site and provider links Attached records, searchable Notes that go stale Absent
Cross registry view One query covers every ASN One file if maintained One login per registry
Change history Recorded per change Manual or none Registry side only
Audit export API call with a fixed shape Copy and paste Manual screenshot

The Two Records You Actually Need

Tracking starts with a small model, not a big one. A registry record and an ASN record are enough to answer every question a future engineer will ask, as long as the link between them exists and the ASN points at the things it touches.

A registry record, the ASN it issued, and the sites, providers, and prefixes the ASN connects to RIR record name, slug, is_private ASN record number, name, status, class Sites which sites announce it Circuit providers who carries the traffic Prefixes and ROAs what it originates

The registry record is where the relationship to the authority lives. It carries a name, a short slug, an optional flag for non registry pseudo entries such as private address space, and a description that should hold the account number or sponsoring LIR. Registry slugs are unique inside an organization, so two teams can both keep a record called “legacy” without colliding.

The ASN record is the resource. It carries the number, a human readable name, a lifecycle status, an optional link to the registry that issued it, and a description. Everything else that matters is a relationship outward, to the sites that announce the number and the providers that carry it.

Fields Worth Storing on Every ASN

Keep the field set small enough that it actually gets filled in, and pick fields whose source you can name. Every value below comes from a person, a contract, or a registry, which is what makes the record debuggable later.

Field API name Example Source
The number asn 393216 Registry assignment
Display form asdot 6.0 for 393216 Derived from the number
Class class public, private-16, private-32, reserved Derived from the number
Name name ACME NETWORKS Registry holder record
Lifecycle status active Your team
Registry rir_id RIPE NCC Registry assignment
Registry name rir_name RIPE NCC Resolved from the record
Notes description Sponsoring LIR, account reference Contract or registry
Sites sites NYC, DC1 Network design
Providers providers Example Transit Contract

Status and class are the two fields teams forget, and both carry weight. Status is how a number gets decommissioned without deleting a record that a changelog entry still references. Class is what stops a private number from being announced, and it is cheap to compute rather than type.

Classify Each Number Before You Store It

The public internet only accepts a subset of the AS number space, and mixing the categories is a common cause of a filtered announcement. Classify every number and store the result, so a private number is never mistaken for a public one during a configuration change.

The four ASN classes stored for each number with their numeric ranges private-16 64512 to 65534 Internal use Never announced private-32 4200000000+ Larger private pool Never announced reserved 0, 23456, 64496- 64511, 65536-131071 Documentation and AS_TRANS public everything else Globally routable Registry assigned The reserved ranges include 0, the documentation block, AS_TRANS at 23456, and the top value at 4294967295. None of them should ever appear in a peering configuration.

Classify in one pass and store the answer. This is the same logic any tool should apply, and it makes the audit trivial because the class is already on the record.

# Classify a single number the same way a tracking tool should
asn=64520
if   [ "$asn" -ge 64512 ] && [ "$asn" -le 65534 ]; then echo "private-16"
elif [ "$asn" -ge 4200000000 ] && [ "$asn" -le 4294967294 ]; then echo "private-32"
elif [ "$asn" -eq 0 ] || [ "$asn" -eq 23456 ] || [ "$asn" -eq 4294967295 ] \
  || { [ "$asn" -ge 64496 ] && [ "$asn" -le 64511 ]; } \
  || { [ "$asn" -ge 65536 ] && [ "$asn" -le 131071 ]; }; then echo "reserved"
else echo "public"
fi

Load What You Already Have

Start from the records you already hold rather than a blank list. The registry records rarely change, so they are the easiest thing to model first, and every ASN then has somewhere to point in your IP address management hierarchy.

export OBELINF_API_KEY="your_read_write_key"
export OBELINF_ORG="acme-netops"
BASE="https://api.obelinf.com/${OBELINF_ORG}"

# Registry records first
curl --fail --silent --show-error -H "Authorization: Bearer ${OBELINF_API_KEY}" \
  "${BASE}/rirs?all=true&order=asc" \
  | jq -r '.rirs[] | [.id, .name, .slug, (.is_private|tostring)] | @tsv'

Create any registry you are missing, then create the ASN with the registry attached. A registry record can be created for a pseudo authority too, which is useful for private space that never had an issuing body.

curl --fail --silent --show-error -X POST \
  -H "Authorization: Bearer ${OBELINF_API_KEY}" \
  -H "Content-Type: application/json" \
  "${BASE}/rirs" \
  -d '{"name":"RFC 6996 Private","slug":"private-rfc6996","is_private":true,"description":"Private ASN ranges for internal use"}'

For public numbers, the registry will fill in the holder name for you. The lookup endpoint resolves a public ASN through RDAP and returns the class alongside it, and it deliberately returns an empty name for private and reserved numbers instead of making an external request.

curl --fail --silent --show-error -H "Authorization: Bearer ${OBELINF_API_KEY}" \
  "${BASE}/asns/registry-lookup?asn=3320" \
  | jq -r '[.asn, .class, (.name // "no name"), (.rir // "no rir")] | @tsv'
3320	public	DTAG	RIPE NCC

That single call gives you the three values that are otherwise typed by hand: the class, the registered name, and the registry. Confirm the name against your own records before you accept it, because the holder string is whatever the registry publishes, and a sponsoring LIR can appear instead of the operating company.

Read the Records Back With a Fixed Shape

The value of an inventory is not the storage, it is the export. Define one output shape now, keep it identical between runs, and every future audit becomes a comparison instead of a data gathering exercise. The all=true flag raises the page size to 1000, so page with offset if you hold more ASNs than that.

mkdir -p "audit/$(date +%F)"

curl --fail --silent --show-error -H "Authorization: Bearer ${OBELINF_API_KEY}" \
  "${BASE}/asns?all=true&order=asc" \
  | jq -r '.asns[] | [.asn, .asdot, .class, .name, (.rir_name // "-"), .status] | @tsv' \
  | sort > "audit/$(date +%F)/asns.tsv"

column -t -s $'\t' "audit/$(date +%F)/asns.tsv"
3320    3320     public       DTAG            RIPE NCC   active
64512   64512    private-16   Core iBGP       -          active
393216  6.0      public       ACME NETWORKS   RIPE NCC   active
65000   65000    private-16   Lab             -          deprecated

The asdot column is where a 32 bit number shows itself. A 16 bit number reads the same in both columns, while 393216 in the first column appears as 6.0 in the second. Seeing both forms in the export is what stops a duplicate record from being created for a number that already exists under the other notation. The - in the registry column is the field to act on, because an ASN with no registry reference cannot be reconciled against anything.

The list endpoint searches ASNs by name and by number, so a partial digit finds the record without a full scan. Registry records search on the name prefix, which is faster but narrower, so search for a full name rather than a fragment.

Keep the Registry Side Current

Registry records change more slowly than ASNs, but they fail in a worse way when they are wrong, because the ASN record inherits the error. The account reference, the sponsoring LIR, and the abuse contact all belong in the registry description, and the registry detail endpoint tells you how many ASNs depend on it.

curl --fail --silent --show-error -H "Authorization: Bearer ${OBELINF_API_KEY}" \
  "${BASE}/rirs/${RIR_ID}" \
  | jq -r '[.rir.name, (.rir.asn_count|tostring)] | @tsv'

That asn_count is a dependency check, and the same count prevents a careless deletion. Deleting a registry that still has ASNs attached is refused with a conflict that names the count: Cannot delete this RIR because it is referenced by 3 ASN(s). Remove or reassign them first. Treat that refusal as a prompt, not an obstacle, because a registry deleted while numbers still point at it is a gap in the audit trail that is expensive to rebuild.

Cross-Check Against Public Registries

The inventory is the reference, but the registry is the authority, and the two drift apart during a provider migration. Run the external queries as a reconciliation step rather than as the source of truth. The routing registry answers which prefixes a number is authorized to originate.

whois -h whois.radb.net -- "-i origin AS393216" | grep -E '^(route|route6):'
route:          203.0.113.0/24
route6:         2001:db8:100::/48

RDAP answers who the number belongs to and which registry issued it, in a form a script can read. The port43 value is the registry host, which is the field to compare against the rir_name you stored.

awk -F'\t' '$3=="public"{print $1}' "audit/$(date +%F)/asns.tsv" \
  | while read -r asn; do
      holder=$(curl --fail --silent --show-error "https://rdap.org/autnum/${asn}" 2>/dev/null \
        | jq -r '[.handle, (.name // "none"), (.port43 // "none")] | @tsv')
      printf '%s\t%s\n' "$asn" "$holder"
    done | sort > "audit/$(date +%F)/rdap.tsv"

column -t -s $'\t' "audit/$(date +%F)/rdap.tsv"
3320    AS3320    DTAG            whois.ripe.net
393216   AS393216   ACME NETWORKS   whois.ripe.net

A holder of none on a number you classed as public is the signal that the assignment is incomplete, because a public number with no registered holder will be treated as unverified by peers that filter on registry data.

A Quarterly Audit You Can Re-run

The whole point of a fixed output shape is that the next run compares cleanly against the last. Keep the dated directory, and the audit collapses into a diff.

A repeatable audit that pulls the records, cross-checks the registry, diffs against last quarter, and produces a worklist Pull records API, fixed columns Normalize sort and align Cross-check RDAP and whois Diff quarters comm of two files Worklist findings A diff between two runs is the cheapest way to catch an ASN that was added twice, a registry that changed, or a public number whose holder is now wrong.
comm -3 "audit/2026-07-18/asns.tsv" "audit/2026-10-18/asns.tsv"
393216	6.0	public	ACME NETWORKS	RIPE NCC	active
	393216	6.0	public	ACME NETWORKS	RIPE NCC	deprecated
	393217	6.1	public	ACME NETWORKS	RIPE NCC	active

A line without a leading tab exists only in the previous run, a line with one exists only in the current run, and a record that changed in place appears twice, once on each side. Two lines for the same number in different notations is the duplicate that the audit exists to find.

Layer the remaining checks on the same file. Numbers with no registry, public numbers with no RDAP holder, and private numbers that appear in a captured configuration are all one line each.

echo "== ASNs with no registry =="
awk -F'\t' '$5=="-"{print $1, $4}' "audit/$(date +%F)/asns.tsv"

echo "== Private numbers that should never be announced =="
awk -F'\t' '$3!="public"{print $1, $3, $4}' "audit/$(date +%F)/asns.tsv"

The first concrete step is the export, not the cleanup. Run the two API calls today, save the files under a dated directory, and commit them next to whatever else your team keeps in version control. Once one run exists, the next one is a diff, and the audit turns from a project into a habit.

Frequently Asked Questions

What is the difference between an ASN and a RIR?
A Regional Internet Registry is the authority that assigns Internet number resources, including AS numbers, within a geographic region. An ASN is the number itself, a globally unique identifier for an autonomous system, issued by one registry. In an inventory the RIR is the source record and the ASN is the resource it issued, so one RIR record is referenced by every ASN that came from it.
How should I store private ASN ranges?
Store them exactly as you would a public number, with the range labelled as private so nobody announces them by mistake. The 16 bit private range runs from 64512 to 65534 and the 32 bit private range runs from 4200000000 to 4294967294. Enforcing uniqueness per organization is enough, because two separate networks are free to reuse the same private number internally.
Why does an ASN show two notations?
A 32 bit AS number is written in asplain as a single integer and in asdot as two numbers separated by a dot, so 393216 is also written 6.0. Both mean the same value and routers accept either. Store the integer as the canonical value and keep the asdot form for display, because that is what an engineer types into a device console.
How do I keep ASN records current as providers change?
Store the relationships, not just the number. Attach each ASN to the sites that announce it and the circuit providers that carry it, review those attachments whenever a circuit is added, moved, or cancelled, and keep the registry reference and any sponsoring LIR in the description. A number with no attached site or provider is the record most likely to be stale.
Can I track ASNs and RIRs with Obelinf?
Yes. Obelinf stores RIR records and ASN records with a link between them, classifies each number as public, private, or reserved, and attaches ASNs to the sites and circuit providers that use them. You can read the whole set through the REST API and cross-check it against RDAP, so the inventory stays the reference while the registry remains the authority.

Stop reaching for a spreadsheet

Obelinf keeps every subnet, device, circuit, and rack in one live source of truth, with audit logs and a topology view. Free for personal use.

Related Articles