You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A comprehensive Go SDK for APNIC (Asia-Pacific Network Information Centre) public data services, providing full coverage of all APNIC data endpoints and query capabilities.
RDAP /help: server capability (rdapConformance) and notices
RDAPSearchDomains(ctx, name)
RDAP /domains: search in-addr.arpa domains by name
All RDAP lookups have *At variants (e.g., RDAPLookupIPAt(ctx, ip, date)) for point-in-time historical queries (RFC3339), returning the resource state at that UTC instant, based on APNIC history_version_0 extension.
6. Transfers (IP/ASN Transfer Records)
Method
Description
FetchTransfers(ctx)
Fetch latest transfer records (daily JSON snapshot)
GetTransfers(ctx)
Cached transfer records
FetchTransfersByYear(ctx, year)
Fetch transfers by year
FetchTransfersAll(ctx, date)
Fetch cumulative transfers-all (pipe-delimited, all transfers since 2010); date="" for latest, YYYYMMDD for archive
FetchTransfersAllMD5(ctx, date)
MD5 checksum for transfers-all
FetchTransfersAllASC(ctx, date)
PGP signature (.asc) for transfers-all
7. Changes (Resource Change Records)
Method
Description
FetchChanges(ctx)
Fetch latest change records
GetChanges(ctx)
Cached change records
FetchChangesByDate(ctx, date)
Fetch changes by date
7b. Whois/RDAP Service Telemetry
Method
Description
FetchTelemetry(ctx, date)
Fetch whois-rdap-stats telemetry (hourly): query volume, type distribution, top ASN; date="" for latest
REx (Resource EXplorer, api.rex.apnic.net/v1/*) is a public REST API from APNIC that aggregates delegated resources across all five RIRs (APNIC/ARIN/RIPE/LACNIC/AFRINIC) into a unified view, grouped by resource holder (opaqueId). This capability cannot be replaced by per-RIR stats/RDAP:
Method
Description
FetchRExUserNetwork(ctx)
Self-locate network: return covering prefix, origin ASN, economy code based on caller's source IP (no parameters)
FetchRExResources(ctx, type)
Cross-RIR recent delegated resources (with holder attribution), type can be ipv4/ipv6/asn or empty
FetchRExHolder(ctx, opaqueID, rir)
Aggregate all ASN and prefixes held by one organization, given opaqueId and responsible RIR
FetchRExHoldersUniqueCount(ctx)
Total unique holder count across all RIRs
rir values: afrinic/apnic/arin/lacnic/ripencc (RIPE NCC code is ripencc, not ripe). opaqueId can be obtained from RExResource.OpaqueID or extended delegated stats. REx uses HTTPS public API, shares unified HTTP client, inherits anti-scraping headers.
8. Whois Queries
Method
Description
QueryWhois(ctx, query)
Raw Whois query
QueryWhoisIP(ctx, ip)
IP address Whois query (parsed result)
QueryWhoisASN(ctx, asn)
ASN Whois query (parsed result)
QueryWhoisWithFlags(ctx, query, flags)
Whois query with flags
ParseWhoisResponse(response)
Parse Whois response text
9. Reverse DNS
Method
Description
ReverseDNS(ctx, ip)
IP reverse DNS (PTR) lookup
10. Historical Data
Method
Description
FetchHistoricalDelegated(ctx, date)
Fetch historical delegated data by date
FetchHistoricalExtended(ctx, date)
Fetch historical extended data by date
FetchHistoricalAssigned(ctx, date)
Fetch historical assigned stats by date
FetchHistoricalLegacy(ctx, date)
Fetch historical legacy data by date
FetchDelegatedByYear(ctx, year)
Fetch delegated data by year
FetchExtendedByYear(ctx, year)
Fetch extended data by year
ListAvailableYears()
List available historical data years
11. Data Integrity Verification
flowchart LR
subgraph Verify_Flow["Verification Flow"]
Data["Download<br/>data file"]
MD5_File["Download<br/>.md5 file"]
ASC_File["Download<br/>.asc file"]
PubKey["Fetch<br/>CURRENT_PUBLIC_KEY"]
Calc["Compute<br/>local MD5"]
Compare["Compare<br/>MD5 strings"]
PGP_Verify["PGP<br/>signature verify"]
end
Data --> Calc --> Compare
MD5_File --> Compare
ASC_File --> PGP_Verify
PubKey --> PGP_Verify
Data --> PGP_Verify
Loading
Method
Description
VerifyMD5(ctx, dataType, date)
End-to-end: download data file + MD5 sidecar, compute locally and compare
FetchMD5Checksum(ctx, dataType, date)
Fetch MD5 checksum (compatible with BSD MD5 (file) = and GNU style)
FetchASCSignature(ctx, dataType, date)
Fetch PGP signature (.asc)
FetchPublicKey(ctx)
Fetch APNIC signing public key (CURRENT_PUBLIC_KEY)
12. Filtering & Grouping
Method
Description
FilterEntries(entries, country, resType)
Filter by country and type
FilterByStatus(entries, status)
Filter by status
FilterByDateRange(entries, start, end)
Filter by date range
FilterExtendedByOpaqueID(entries, opaqueID)
Filter by organization ID
FilterExtendedByCountry(entries, country)
Filter extended by country
FilterExtendedByType(entries, resType)
Filter extended by type
FilterExtendedByStatus(entries, status)
Filter extended by status
GroupByCountry(entries)
Group by country
GroupExtendedByOpaqueID(entries)
Group by organization
GroupExtendedByCountry(entries)
Group extended by country
13. Chain Filtering API
flowchart LR
Entries["Entries<br/>Input"]
subgraph Filter_Chain["Chain Filter"]
ByCountry["ByCountry(cn)"]
ByType["ByType(ipv4)"]
ByStatus["ByStatus(allocated)"]
ByDateRange["ByDateRange(start, end)"]
end
Result["Result<br/>Filtered entries"]
Entries --> ByCountry --> ByType --> ByStatus --> ByDateRange --> Result
To avoid being detected as a scraper, SDK enables browser mimicry middleware by default: all HTTP exits (including whois jitter) inject mainstream Chrome request headers (UA, Accept-Language, Sec-Fetch-, Sec-Ch-Ua-, etc.), plus token bucket rate limiting and random jitter between requests. Adjustable via Options:
client:=apnic.NewClient(
apnic.WithStealth(true), // default true; false sends only UA+Accept (backward compatible)apnic.WithBrowserUserAgent("Mozilla/5.0 ..."), // custom browser UAapnic.WithJitter(200*time.Millisecond, 800*time.Millisecond), // random delay range per requestapnic.WithRateLimit(2.0), // global max requests per second (token bucket, 0=unlimited)apnic.WithFTPBaseURL(apnic.DefaultFTPBaseURL), // FTP root for IRR/transfers-all/telemetryapnic.WithRRDPBaseURL(apnic.DefaultRRDPBaseURL),
apnic.WithThymeBaseURL(apnic.DefaultThymeBaseURL),
apnic.WithRExBaseURL(apnic.DefaultRExBaseURL), // REx cross-RIR registry
)
Compatibility: when stealth is on, sets Accept-Encoding: gzip. Go Transport won't auto-decompress, so fetchText, RRDP stream parsers and REx fetchJSON explicitly handle Content-Encoding: gzip to avoid double decompression. Test with APNIC_NO_JITTER=1 to skip jitter for speed.
Chunked Download for Large Files (Default On)
APNIC FTP throttles large files (delegated 4.3MB, extended, IRR apnic.db.inetnum.gz 50MB+) to single-connection bandwidth ~8-22 KB/s—this is not anti-scrap detection (same speed for any UA, no 403, normal accept-ranges: bytes), but server-level rate limiting. Single connection for 50MB IRR dump takes ~40 min, far exceeding typical timeouts.
SDK enables multi-connection chunked download by default: probe Range support, then split file into ~2MB chunks, download with 4 concurrent Range requests in round-robin (each connection independently rate-limited, total throughput 3-4×), merge via io.Pipe with on-demand gzip decompression. Each chunk request goes through doHTTPRequest, inherits full browser headers + token bucket + jitter. Endpoints without Range support or with transport-layer gzip transparently fall back to single connection.
flowchart TB
subgraph Chunked_Download["Chunked Download Flow"]
Probe["Probe Range<br/>GET Range:0-0<br/>→ Content-Length<br/>→ supports Range?"]
subgraph Strategy["Download Strategy"]
Chunked["Chunked<br/>Split into 2MiB<br/>4 workers × N blocks"]
Single["Single Connection<br/>Fallback (no Range)"]
end
subgraph Workers["Concurrent Workers"]
W1["Worker 1<br/>Range 0-2MiB"]
W2["Worker 2<br/>Range 2MiB-4MiB"]
W3["Worker 3<br/>Range 4MiB-6MiB"]
W4["Worker 4<br/>Range 6MiB-..."]
end
Merge["Merge via io.Pipe<br/>Ordered by index"]
Decompress["gzip.NewReader<br/>if .gz"]
Result["Result<br/>io.Reader"]
end
Probe -->|supports Range| Chunked --> Workers --> Merge --> Decompress --> Result
Probe -->|no Range| Single --> Decompress --> Result
Chunk strategy: default 2MiB per chunk (~90s at 22KB/s, well below suggested 5min per-chunk timeout). maxConcurrent controls concurrency, not chunk count—50MB file splits into ~25 chunks rotated via 4 workers. Hard caps: 64 chunks max, 16 concurrency max, to avoid server pressure. If per-chunk timeout still triggers, reduce WithChunkSize (e.g., 1MiB) or increase WithDownloadTimeout.
Slow block tolerance: when a chunk hits context deadline exceeded due to stuck connection, SDK auto-splits it into two sub-chunks with new concurrent retry, bypassing the dead TCP connection, avoiding single-point jitter killing the whole download.
CLI (Command-Line Interface)
The repository includes a cobra-based apnic CLI covering all SDK capabilities:
Full subcommand and parameter documentation in docs/SKILLS.md.
Multi-command workflow examples (country resource audit / IP全景 investigation / transfer/change tracking / data integrity verification) in docs/workflows.md.
Test Coverage
SDK: 100.0% statement coverage
CLI: All named functions 100% (overall 99.1%, difference is main() entry osExit(runMain()) unreachable)
Data Flow Example: IP Investigation
sequenceDiagram
participant User
participant CLI
participant SDK as apnic-skills SDK
participant APNIC as APNIC Services
User->>CLI: apnic rdap ip 1.1.1.1
CLI->>SDK: RDAPLookupIP(ctx, "1.1.1.1")
SDK->>APNIC: GET rdap.apnic.net/ip/1.1.1.1
APNIC-->>SDK: RDAPNetwork JSON
SDK-->>CLI: RDAPNetwork struct
CLI-->>User: Handle/Country/Type/CIDR
User->>CLI: apnic whois ip 1.1.1.1
CLI->>SDK: QueryWhoisIP(ctx, "1.1.1.1")
SDK->>APNIC: whois.apnic.net:43
APNIC-->>SDK: Whois text
SDK-->>CLI: WhoisInfo struct
CLI-->>User: Network/Org/Created/Updated
User->>CLI: apnic reverse-dns 1.1.1.1
CLI->>SDK: ReverseDNS(ctx, "1.1.1.1")
SDK->>APNIC: DNS PTR lookup
APNIC-->>SDK: PTR names
SDK-->>CLI: []string
CLI-->>User: one.one.one.one.
Loading
License
MIT
About
APNIC Go SDK — comprehensive coverage of all APNIC public data services (stats, RDAP, whois, IRR, RPKI/RRDP, thyme BGP, REx cross-RIR, transfers, changes, telemetry) with anti-scraping, chunked download, and a cobra CLI.