From 3595aa0656689293e83e4813e88c7f896ba29cf8 Mon Sep 17 00:00:00 2001 From: Gregory Oschwald Date: Fri, 10 Jul 2026 20:52:40 +0000 Subject: [PATCH] Add residential proxy data to anonymizer object This adds support for the new residential sub-object nested within the anonymizer object in the GeoIP2 Insights web service response. The residential object is sourced from the GeoIP Residential Proxy database and contains a confidence score, the last seen date for the network, and the associated provider name. Because the residential proxy feed is a superset of what is available in Anonymous Plus, the anonymizer object may now contain only the residential property. The shared shape of these feed records is exposed as a new AnonymizerFeedRecord interface so it can be reused if additional feeds (e.g. vpn, mobile, datacenter) are added in the future. Co-Authored-By: Claude Fable 5 --- CHANGELOG.md | 17 +++++++++++++++++ fixtures/geoip2.json | 7 ++++++- src/records.ts | 32 ++++++++++++++++++++++++++++++++ src/webServiceClient.spec.ts | 8 +++++++- 4 files changed, 62 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c909810..b870e8dd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,23 @@ CHANGELOG ========= +7.1.0 (unreleased) +------------------ + +* A new `residential` property has been added to the `anonymizer` object in + the `Insights` response model. This is sourced from the GeoIP Residential + Proxy database and is available from the GeoIP2 Insights web service only. + As the residential proxy feed is a superset of what is available in + Anonymous Plus, the `anonymizer` object may now contain only the + `residential` property. The `residential` object includes the following + properties: + * `confidence`: A score (1-99) representing MaxMind's confidence that the + network is part of an actively used residential proxy + * `networkLastSeen`: The last day (YYYY-MM-DD) the network was sighted in + our analysis of the residential proxy feed + * `providerName`: The name of the residential proxy provider associated + with the network + 7.0.0 (2026-06-29) ------------------ diff --git a/fixtures/geoip2.json b/fixtures/geoip2.json index 216e9e7f..f51ed6a0 100644 --- a/fixtures/geoip2.json +++ b/fixtures/geoip2.json @@ -139,6 +139,11 @@ "is_residential_proxy": false, "is_tor_exit_node": false, "network_last_seen": "2025-04-14", - "provider_name": "NordVPN" + "provider_name": "NordVPN", + "residential": { + "confidence": 82, + "network_last_seen": "2026-05-11", + "provider_name": "quickshift" + } } } diff --git a/src/records.ts b/src/records.ts index 8cfdeadb..9741c040 100644 --- a/src/records.ts +++ b/src/records.ts @@ -217,6 +217,32 @@ export interface SubdivisionsRecord { readonly names: Names; } +/** + * Contains data shared by the feed records nested within the anonymizer + * record, such as `residential`. Each of these records describes network + * activity attributed to a specific feed of anonymizing providers. This + * record is only available from the GeoIP Insights web service. + */ +export interface AnonymizerFeedRecord { + /** + * A score ranging from 1 to 99 that represents our percent confidence that + * the network is currently part of an actively used service in this feed. + * This value is only available from GeoIP Insights. + */ + readonly confidence?: number; + /** + * The last day that the network was sighted in our analysis of this feed + * of anonymized networks. The date is in ISO 8601 format (YYYY-MM-DD). + * This value is only available from GeoIP Insights. + */ + readonly networkLastSeen?: string; + /** + * The name of the identified provider, such as "NordVPN" or "SurfShark". + * This value is only available from GeoIP Insights. + */ + readonly providerName?: string; +} + /** * Contains data for the anonymizer record associated with an IP address. * This record is only available from the GeoIP Insights web service. @@ -271,6 +297,12 @@ export interface AnonymizerRecord { * This value is only available from GeoIP Insights. */ readonly providerName?: string; + /** + * Data about the residential proxy feed associated with the IP address, + * sourced from the GeoIP Residential Proxy database. This value is only + * available from GeoIP Insights. + */ + readonly residential?: AnonymizerFeedRecord; } /** diff --git a/src/webServiceClient.spec.ts b/src/webServiceClient.spec.ts index 402a06e8..93c866c5 100644 --- a/src/webServiceClient.spec.ts +++ b/src/webServiceClient.spec.ts @@ -346,7 +346,7 @@ describe('WebServiceClient', () => { it('returns an insight class', async () => { const ip = '8.8.8.8'; - expect.assertions(107); + expect.assertions(110); const { client, requests } = clientWith(() => jsonResponse(200, testFixture) @@ -474,6 +474,12 @@ describe('WebServiceClient', () => { expect(got.anonymizer!.isTorExitNode).toEqual(false); expect(got.anonymizer!.networkLastSeen).toEqual('2025-04-14'); expect(got.anonymizer!.providerName).toEqual('NordVPN'); + + expect(got.anonymizer!.residential!.confidence).toEqual(82); + expect(got.anonymizer!.residential!.networkLastSeen).toEqual( + '2026-05-11' + ); + expect(got.anonymizer!.residential!.providerName).toEqual('quickshift'); }); });