# 🌍 Bulk IP Geolocation & ISP Lookup - No API Key (`renzomacar/ip-geolocation`) Actor

Look up any list of IPv4/IPv6 addresses and get country, region, city, lat/long, ISP, ASN, organization, timezone and proxy/VPN flags. Keyless ipinfo/ipapi alternative for visitor analytics, fraud checks, geo-targeting and security recon.

- **URL**: https://apify.com/renzomacar/ip-geolocation.md
- **Developed by:** [Renzo Madueno](https://apify.com/renzomacar) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$5.00 / 1,000 ip enricheds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## 🌍 Bulk IP Geolocation & ISP Lookup

### 🎥 Video walkthrough

https://youtu.be/-Vm4ns\_mJ9Q

**Paste a list of IP addresses, get back who and where they are.** For every
IPv4 or IPv6 address you supply, this Actor returns the **country, region, city,
postal code and latitude/longitude**, plus the **network owner** — the ISP, the
organization, the **ASN** (autonomous system number) and its domain — and the
**timezone / UTC offset**. When the underlying source exposes it, you also get
**proxy / VPN** security flags.

No API key. No dashboard to sign up for, no monthly quota to babysit. It runs one
lightweight lookup per IP and hands you a clean, flat record per address — ready
to drop straight into your analytics warehouse, CRM or fraud rules.

***

### What "IP enrichment" actually gets you

A raw IP address is just a number. Enriching it turns that number into context
your product and your team can act on. Three layers come back for each IP:

- **Geography** — `country`, `countryCode`, `region`, `city`, `postal`,
  `latitude`, `longitude`. Where in the world the connection is coming from,
  down to city level for most IPv4 ranges.
- **Network ownership** — `isp`, `org`, `asn`, `asnDomain`. *Who* runs the
  network. This is what separates a residential comcast/vodafone user from an
  AWS/Google/Azure data-center IP (a bot, a scraper, or server-to-server
  traffic) or a known VPN/proxy provider.
- **Time & risk** — `timezone`, `utcOffset`, and (when available) `isProxy` /
  `isVpn`. Local time for the visitor, and a first signal of anonymized traffic.

The ASN + organization pair is the quiet hero here. "This request came from
`AS15169 Google LLC`" or "`AS16509 Amazon.com`" tells you in one field that a
"user" is really a cloud host — a distinction that pure geo databases miss and
that fraud, abuse and analytics teams live and die by.

***

### Who uses this, and for what

- **Visitor & product analytics.** Attach a country/city/ISP to every session or
  signup in your events pipeline without wiring a paid SDK into your app. Segment
  by geography, spot data-center traffic skewing your funnel, localize dashboards.
- **Fraud & abuse checks.** Flag signups and checkouts coming from data-center
  ASNs, mismatched geographies, or proxy/VPN ranges. Enrich a list of IPs from
  your logs and score them offline before they touch a human.
- **Personalization & geo-targeting.** Pre-fill country/currency/language, gate
  region-locked content, or route a lead to the right sales rep by timezone —
  from the IP you already logged.
- **Security recon & incident response.** Turn a pile of IPs from firewall logs,
  auth failures or an abuse report into "which networks, which countries, which
  hosting providers" in one pass.
- **Sales & lead intelligence.** Reverse-resolve the IPs hitting your site to the
  owning organization to prioritize accounts.

***

### An ipinfo / ipapi alternative — the honest version

Commercial IP APIs (ipinfo.io, ipapi.co, ip-api.com Pro, MaxMind) are excellent,
and if you need contractual SLAs, guaranteed accuracy tiers, or millions of
lookups a day, buy one. But for the very common job of **enriching a bounded list
of IPs on a schedule** — nightly log batches, a signup export, a research set —
you don't need a subscription and an API key rotation. This Actor gives you the
same core fields (geo + ISP + ASN + org + timezone) on a **pay-per-result** basis
with **zero key management**, and drops the output into an Apify dataset you can
pull via API, export to CSV/JSON, or chain into another Actor.

**On accuracy — read this.** IP geolocation is an *estimate*, not GPS.

- **Country** is highly reliable. **Region and city** are good for most fixed-line
  IPv4 but can point at the ISP's regional hub rather than the exact town.
- **Mobile and IPv6** addresses are looser — carrier-grade NAT and dynamic
  allocation mean the city can be off by a lot.
- **Latitude/longitude** is an approximate centroid, **never** a street address.
  Treat it as "roughly this metro area."
- **ISP / ASN / org** is the most trustworthy signal in the record — it comes
  from routing registries, not guesswork.

**Which source is used.** Every lookup goes to **ipwho.is** first (free, keyless,
IPv4 + IPv6). If ipwho.is is unavailable or rate-limits, the Actor automatically
falls back to **ip-api.com** and maps its response to the identical output shape;
the `source` field on each record tells you which one answered. Note that
ip-api.com's free tier is **non-commercial** — ipwho.is is the default and
handles the vast majority of lookups. Proxy/VPN security flags are only populated
when the source returns them; otherwise they come back `null` rather than a
guessed value.

***

### Example — input & output

**Input:**

```json
{
  "ipAddresses": ["8.8.8.8", "1.1.1.1", "104.16.132.229"],
  "maxConcurrency": 3
}
```

**Output** (one record per IP; abridged):

```json
{
  "ip": "8.8.8.8",
  "isValid": true,
  "type": "IPv4",
  "country": "United States",
  "countryCode": "US",
  "region": "California",
  "city": "Mountain View",
  "postal": "94039",
  "latitude": 37.3860517,
  "longitude": -122.0838511,
  "isp": "Google LLC",
  "org": "Google LLC",
  "asn": "AS15169",
  "asnDomain": "google.com",
  "timezone": "America/Los_Angeles",
  "utcOffset": "-07:00",
  "isProxy": null,
  "isVpn": null,
  "source": "ipwho.is",
  "error": null,
  "lookedUpAt": "2026-07-04T00:00:00.000Z"
}
```

Invalid input is never silently dropped — a malformed IP returns
`{ "isValid": false, "error": "invalid-ip" }`, and a well-formed IP that couldn't
be resolved returns `{ "isValid": true, "error": "lookup-failed: ..." }`, so your
downstream job can tell the two apart.

***

### What each field means

| Field | What it tells you |
|---|---|
| `ip` | The address you supplied (IPv6 lower-cased for consistency). |
| `isValid` | `true` if the IP is well-formed **and** resolved; `false` for malformed input. |
| `type` | `IPv4` or `IPv6`. |
| `country` / `countryCode` | Country name and ISO 3166-1 alpha-2 code. |
| `region` / `city` / `postal` | Sub-national location (approximate — see accuracy note). |
| `latitude` / `longitude` | Approximate coordinates of the metro area. |
| `isp` | The internet service provider serving the IP. |
| `org` | The organization that owns/uses the block (often a company or cloud host). |
| `asn` / `asnDomain` | Autonomous System Number (e.g. `AS15169`) and its domain. |
| `timezone` / `utcOffset` | IANA timezone id and current UTC offset. |
| `isProxy` / `isVpn` | Anonymizer flags when the source provides them, else `null`. |
| `source` | Which provider answered (`ipwho.is` or `ip-api.com`). |
| `error` | `null` on success; `invalid-ip` or `lookup-failed: …` otherwise. |
| `lookedUpAt` | ISO timestamp of the lookup. |

***

### The enrichment suite: resolve → enrich → verify

This Actor is the **IP layer** of a broader data-enrichment toolkit. Pair it with
its siblings to go from a raw signal to a full profile:

- **Domain Health Enricher** — take a domain and check MX, SPF, DKIM, DMARC and
  general deliverability health.
- **WHOIS & DNS Lookup** — resolve a domain's registration, nameservers and full
  DNS record set (A/AAAA/MX/TXT/NS).
- **Company Enrichment** — turn a domain into tech stack, contacts and mail
  provider.

A common flow: an IP hits your logs → **this Actor** resolves it to an org and
ASN → if it maps to a company domain, hand that domain to **WHOIS & DNS Lookup**
and **Company Enrichment** for the full picture.

***

### Automate it

Run it on a schedule or fire it from your own code:

- **Schedule** a nightly run over the IPs collected from your logs — point it at a
  fresh input list and let the dataset accumulate.
- **API / SDK.** Call the Actor with your `ipAddresses` array via the Apify API or
  the JS/Python client, then read results straight from the run's dataset.
- **Chain it.** Use it as a step in an Apify workflow — feed it IPs scraped by
  another Actor, then push the enriched output onward.
- **Cost control.** It bills **per successfully enriched IP** (pay-per-event).
  Invalid or unresolvable IPs are **not** charged, and the run respects
  `ACTOR_MAX_TOTAL_CHARGE_USD` so you can cap spend on any single run.

***

### FAQ

**Do I need an API key?** No. It's keyless — ipwho.is (and the ip-api.com
fallback) require no signup.

**IPv6 supported?** Yes. Both IPv4 and IPv6 are validated and enriched; the `type`
field tells you which.

**How accurate is the city?** Country is very reliable; city is a good estimate
for fixed-line IPv4 and looser for mobile/IPv6. See the accuracy note above — this
is geolocation, not GPS.

**Will it charge me for bad IPs?** No. Malformed IPs and lookups that fail are
pushed to the dataset (so you can see them) but are **not** billed. You only pay
for IPs that resolved.

**Can I paste a big list?** Yes — one IP per line, IPv4 or IPv6, mixed freely.
Duplicates are removed automatically.

**Is the proxy/VPN flag always filled?** Only when the source returns security
data. When it doesn't, the field is `null` — we never guess.

**Which data source answered?** Check the `source` field on each record. ipwho.is
is the default; ip-api.com is the automatic fallback (non-commercial free tier).

# Actor input Schema

## `ipAddresses` (type: `array`):

One IP address per line — IPv4 (e.g. 8.8.8.8) or IPv6 (e.g. 2606:4700:4700::1111). Each IP is validated, then enriched into one clean record: country, region, city, postal, latitude/longitude, ISP, organization, ASN + ASN domain, timezone and UTC offset, plus proxy/VPN flags when the source provides them. Keyless — no API key required.

## `maxConcurrency` (type: `integer`):

How many IPs to look up in parallel (1–4). A modest value keeps the free geolocation endpoint happy and avoids rate-limiting. Defaults to 3.

## Actor input object example

```json
{
  "ipAddresses": [
    "8.8.8.8",
    "1.1.1.1",
    "104.16.132.229"
  ],
  "maxConcurrency": 3
}
```

# Actor output Schema

## `results` (type: `string`):

Rows produced by Bulk IP Geolocation & ISP Lookup, one item per result in the default dataset.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "ipAddresses": [
        "8.8.8.8",
        "1.1.1.1",
        "104.16.132.229"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("renzomacar/ip-geolocation").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "ipAddresses": [
        "8.8.8.8",
        "1.1.1.1",
        "104.16.132.229",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("renzomacar/ip-geolocation").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "ipAddresses": [
    "8.8.8.8",
    "1.1.1.1",
    "104.16.132.229"
  ]
}' |
apify call renzomacar/ip-geolocation --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=renzomacar/ip-geolocation",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/akbrLRYW0ZXUd5Thr/builds/4xIIhYhVHEOSS1VdR/openapi.json
