---
title: "What Is My IP API: Get Your Public IP Programmatically"
slug: "/tutorials/what-is-my-ip-api"
description: "Need a what's-my-IP API? IPGeolocation.io's getip returns your public IP as JSON, XML, or plain text. Code for curl, Python, Node.js, Go, and PHP."
---

# What Is My IP API? Get the Caller's Public IP with getip

By [Daud Ahmad](https://www.linkedin.com/in/daudahmad0303) Software Engineer

Posted on October 21, 2026 | 10 min read

![What Is My IP API? Get the Caller's Public IP with getip](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/10/what-is-my-ip-api-feature.png)

A "what is my IP" API returns the public IP address of whoever calls it. IPGeolocation.io's getip endpoint does this with one GET request, no API key, and no account:

```bash
curl https://api.ipgeolocation.io/v3/getip
```

```json
{"ip":"203.0.113.24"}
```

Your own address replaces the example 203.0.113.24.

Who calls decides the answer. Run that request on a server and getip returns the server's outbound IP. Call it from a visitor's browser and it returns the visitor's IP.

* * *

## TL;DR

To use IPGeolocation.io's getip as your "what is my IP" API, send one `GET` to `https://api.ipgeolocation.io/v3/getip` from the machine whose address you need and read the `ip` field.

*   `output=text` returns the bare address for scripts; `output=xml` returns XML.
*   Browser code on any website can call it.
*   A backend that needs a visitor's IP reads it from the incoming request instead.
*   For data about the caller's IP, such as its location and ASN, call `/v3/ipgeo` without an `ip` parameter.

* * *

## Get your public IP with curl

One curl command gets your public IP from any terminal. Plain text suits scripts best:

```bash
curl -sS --fail --max-time 10 "https://api.ipgeolocation.io/v3/getip?output=text"
```

```text
203.0.113.24
```

The text reply has no trailing newline, so your prompt may land on the same line; `ip=$(curl ...)` captures it cleanly.

The `output` parameter picks the format:

| Request | Content type | Body |
| --- | --- | --- |
| `/v3/getip` | `application/json` | `{"ip":"203.0.113.24"}` |
| `/v3/getip?output=xml` | `application/xml` | `<LinkedHashMap><ip>203.0.113.24</ip></LinkedHashMap>` |
| `/v3/getip?output=text` | `text/plain` | `203.0.113.24` |

The [Get IP endpoint reference in the IPGeolocation.io API docs](https://ipgeolocation.io/documentation/api-response-formats.html) covers the `Accept` header too. `getip` uses no credits, has no rate limit, and runs under the API's 99.99% uptime SLA; as of October 2026, it handles more than 500 million requests a month, counted from our API logs.

`-sS` hides the progress meter but keeps errors, `--fail` turns an HTTP error status into a non-zero exit code instead of printing the error body, and `--max-time` stops a stalled request. Very short timeouts are a common production pitfall; 10 seconds allows for a slow network.

With JSON, `jq` pulls out the field:

```bash
curl -sS --fail --max-time 10 https://api.ipgeolocation.io/v3/getip | jq -r .ip
```

In PowerShell, `Invoke-RestMethod` parses the JSON for you:

```powershell
(Invoke-RestMethod -Uri "https://api.ipgeolocation.io/v3/getip" -TimeoutSec 10).ip
```

Both print only the address.

* * *

## Caller IP vs. visitor IP: what getip returns

getip returns the public IP of whatever machine sends the request, so the same URL gives different answers depending on where your code runs:

| Where the request comes from | What getip returns |
| --- | --- |
| Your laptop on a home or office network | Your network's public IP, shared by every device behind the router |
| A server or container behind a NAT gateway | The gateway's public IP |
| A CI runner or serverless function | The platform's outbound IP for that run, which can change between runs |
| A visitor's browser, running your page | The visitor's public IP, returned to the visitor's browser |
| Any of these through a VPN or proxy | The VPN or proxy exit IP |

Two mistakes are common. Developers expect getip to match the private address in their network settings, such as 192.168.1.20 ([public and private IP addresses](https://ipgeolocation.io/guides/what-is-an-ip-address-and-how-does-it-work) explains the difference). And backends expect it to return the end user's IP, but a server that calls getip while handling a visitor's request gets its own address back; [how to get a visitor's real IP address in your backend](https://ipgeolocation.io/guides/get-real-client-ip-address) shows the right way. Any what-is-my-IP service behaves this way, because it answers with the address the request arrives from.

One exception is how we handle proxies on our end at IPGeolocation.io: getip also reads the `X-Forwarded-For` and `CF-Connecting-IP` headers. When a proxy adds one, such as a corporate proxy that inspects HTTPS traffic, getip reports the original client instead of the proxy, which can be a private address. Any client can set those headers too, so treat a getip result as information about the caller, never as proof of identity.

![Diagram: getip gives server code the server's outbound IP and browser code the visitor's IP; backends read the request.](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/10/getip-same-endpoint-different-caller.webp)

* * *

## Get your public IP in code

Each server-side example gets your public IP address with a 10-second timeout, checks that the reply is a real IP, and prints it or exits with an error.

* * *

### 1. Python

Everything it imports (`ipaddress`, `json`, and `urllib`) ships with Python 3, so there's nothing to install. Save this as `get_public_ip.py`:

```python
import http.client
import ipaddress
import json
import urllib.request

GETIP_URL = "https://api.ipgeolocation.io/v3/getip"


def get_public_ip(timeout: float = 10.0) -> str:
    """Return the public IP of the machine running this code."""
    try:
        with urllib.request.urlopen(GETIP_URL, timeout=timeout) as response:
            payload = json.load(response)
    except (OSError, ValueError, http.client.HTTPException) as exc:  # network, timeout, bad reply
        raise RuntimeError(f"getip request failed: {exc}") from exc

    ip = payload.get("ip") if isinstance(payload, dict) else None
    try:
        # Check the value before the rest of your code relies on it
        return str(ipaddress.ip_address(str(ip)))
    except ValueError as exc:
        raise RuntimeError(f"getip returned an unexpected value: {ip!r}") from exc


if __name__ == "__main__":
    try:
        print(get_public_ip())
    except RuntimeError as err:
        raise SystemExit(f"Could not get the public IP: {err}")
```

`python3 get_public_ip.py` prints one address, such as `203.0.113.24`. If the network stalls, you'll see `Could not get the public IP: getip request failed: <urlopen error timed out>` after 10 seconds instead.

* * *

### 2. Node.js

Node.js 18 and later have `fetch` built-in. Save this as `get-public-ip.mjs`; the `.mjs` extension allows top-level `await`:

```javascript
import { isIP } from "node:net";

const GETIP_URL = "https://api.ipgeolocation.io/v3/getip";

async function getPublicIp() {
  // Give up after 10 seconds so a stalled network can't hang the script
  const response = await fetch(GETIP_URL, { signal: AbortSignal.timeout(10000) });
  if (!response.ok) {
    throw new Error(`getip returned HTTP ${response.status}`);
  }
  const data = await response.json();
  const ip = data?.ip;
  if (!isIP(ip ?? "")) {
    throw new Error(`getip returned an unexpected value: ${ip}`);
  }
  return ip;
}

try {
  console.log(await getPublicIp());
} catch (err) {
  console.error("Could not get the public IP:", err.message);
  process.exitCode = 1;
}
```

`node get-public-ip.mjs` prints the address. If you see `fetch is not defined`, your Node.js version is older than 18.

* * *

### 3. JavaScript in the browser

Web pages on any site can call getip, so a page can show visitors their own public IP with no API key. That suits static and cached pages, where no server code sees the visitor's request:

```html
<p>Your public IP: <span id="visitor-ip">checking...</span></p>
<script>
  // Runs in the visitor's browser, so getip returns the visitor's IP
  (async () => {
    const el = document.getElementById("visitor-ip");
    try {
      const response = await fetch("https://api.ipgeolocation.io/v3/getip", {
        signal: AbortSignal.timeout(10000),
      });
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      const data = await response.json();
      el.textContent = data?.ip ?? "unavailable";
    } catch (err) {
      el.textContent = "unavailable";
      console.warn("getip failed:", err);
    }
  })();
</script>
```

The span shows the visitor's address, or "unavailable" if the call fails. getip suits this client-side job because there's no key to leak; if you send the value to your backend, keep it out of security decisions. For location data in the browser, see [IP geolocation in JavaScript](https://ipgeolocation.io/tutorials/ip-geolocation-in-javascript).

* * *

### 4. Go

Go 1.18 added `net/netip`, which parses and validates the address in one call. Save this as `main.go`:

```go
package main

import (
	"encoding/json"
	"fmt"
	"net/http"
	"net/netip"
	"os"
	"time"
)

const getipURL = "https://api.ipgeolocation.io/v3/getip"

func getPublicIP() (netip.Addr, error) {
	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Get(getipURL)
	if err != nil {
		return netip.Addr{}, fmt.Errorf("request failed: %w", err)
	}
	defer resp.Body.Close()

	if resp.StatusCode != http.StatusOK {
		return netip.Addr{}, fmt.Errorf("unexpected status: %s", resp.Status)
	}

	var body struct {
		IP string `json:"ip"`
	}
	if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
		return netip.Addr{}, fmt.Errorf("decoding response: %w", err)
	}

	addr, err := netip.ParseAddr(body.IP)
	if err != nil {
		return netip.Addr{}, fmt.Errorf("getip returned an unexpected value: %q", body.IP)
	}
	return addr, nil
}

func main() {
	ip, err := getPublicIP()
	if err != nil {
		fmt.Fprintln(os.Stderr, "Could not get the public IP:", err)
		os.Exit(1)
	}
	fmt.Println(ip)
}
```

`go run main.go` prints the address. An HTTP error prints `Could not get the public IP: unexpected status: ...` and exits with status 1.

* * *

### 5. PHP

This uses PHP's curl extension (`php -m | grep curl` confirms it's installed). Save it as `get-public-ip.php`:

```php
<?php

function getPublicIp(int $timeoutSeconds = 10): string
{
    $ch = curl_init('https://api.ipgeolocation.io/v3/getip');
    curl_setopt_array($ch, [
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT        => $timeoutSeconds,
        CURLOPT_FAILONERROR    => true, // treat HTTP 4xx and 5xx as errors
    ]);
    $body = curl_exec($ch);

    if ($body === false) {
        throw new RuntimeException('getip request failed: ' . curl_error($ch));
    }

    $data = json_decode($body, true);
    $ip = is_array($data) ? ($data['ip'] ?? null) : null;

    if (!is_string($ip) || filter_var($ip, FILTER_VALIDATE_IP) === false) {
        throw new RuntimeException('getip returned an unexpected value');
    }
    return $ip;
}

try {
    echo getPublicIp(), PHP_EOL;
} catch (RuntimeException $e) {
    fwrite(STDERR, 'Could not get the public IP: ' . $e->getMessage() . PHP_EOL);
    exit(1);
}
```

`php get-public-ip.php` prints the address. An HTTP error prints `Could not get the public IP: getip request failed: ...` and exits with status 1.

* * *

## Three jobs for getip

* * *

### 1. Find your server's outbound IP for an allowlist

When a partner asks which IP your requests come from, run the plain-text curl command on the machine that sends them (a server, container, or CI step), not your laptop.

Check more than once: NAT gateways without a fixed IP, CI runners, and serverless platforms can switch addresses, which breaks an allowlist built from one sample. For production, the IPGeolocation.io team recommends static outbound IPs where your platform offers them, with getip to confirm which one your traffic uses.

* * *

### 2. Detect when your public IP changes

For dynamic DNS or a home lab, this script acts only when getip's answer differs from the last saved value:

```bash
#!/usr/bin/env bash
# Run from cron, for example every 10 minutes: */10 * * * * bash /path/to/check-ip.sh
set -euo pipefail

STATE_FILE="${HOME}/.last_public_ip"

# --retry waits longer between attempts after a timeout or a temporary HTTP error
if ! new_ip=$(curl -sS --fail --max-time 10 --retry 3 \
    "https://api.ipgeolocation.io/v3/getip?output=text"); then
  echo "getip failed; keeping the last known IP" >&2
  exit 1
fi

# Accept only a dotted-quad value, never an error page
if [[ ! "$new_ip" =~ ^([0-9]{1,3}\.){3}[0-9]{1,3}$ ]]; then
  echo "unexpected response from getip" >&2
  exit 1
fi

old_ip=$(cat "$STATE_FILE" 2>/dev/null || true)
if [[ "$new_ip" != "$old_ip" ]]; then
  echo "Public IP changed from ${old_ip:-unknown} to $new_ip"
  # Update your DNS record or allowlist here, then save the new value
  printf '%s' "$new_ip" > "$STATE_FILE"
fi
```

We suggest polling every 5 to 15 minutes, depending on how fast you need to react. A failed call never counts as a change: curl retries with growing waits, the script keeps the last known IP, and its non-zero exit lets your monitoring alert you. The first run prints`Public IP changed from unknown to 203.0.113.24`; later runs stay quiet until the address moves.

![Flow: run getip on a schedule, check the result is an IP, and update DNS or allowlists only when the IP really changed.](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/10/detect-public-ip-change-flow.webp)

* * *

### 3. Check that a proxy or VPN is working

Call getip directly, then through the proxy, and compare. `--proxy-user` Passes the proxy login; reading it from environment variables keeps the password out of your shell history:

```bash
# Your address without the proxy
curl -sS --fail --max-time 10 "https://api.ipgeolocation.io/v3/getip?output=text"; echo

# The same request through the proxy
curl -sS --fail --max-time 10 \
  --proxy proxy.example.com:8080 \
  --proxy-user "$PROXY_USER:$PROXY_PASS" \
  "https://api.ipgeolocation.io/v3/getip?output=text"; echo
```

Without a scheme, curl treats the proxy address as an HTTP proxy. For a SOCKS5 proxy, use `--proxy socks5h://proxy.example.com:1080` with the same `--proxy-user` option; the `h` lets the proxy resolve the hostname. A wrong password makes curl stop with an error instead of printing an address. For a VPN, run the first command before and after connecting.

An unchanged address usually means the proxy exits through your own public IP, for example because it runs on your network. A new address shows the request went through, though not where that exit is located. The IP Geolocation API answers that, and its [security data](https://ipgeolocation.io/ip-security-api.html) flags VPN, proxy, and Tor exits with a threat score.

* * *

## From your IP to what it reveals

When you need more than the address, [IPGeolocation.io's IP Geolocation API](https://ipgeolocation.io/ip-location-api.html) returns what it reveals. [Call `/v3/ipgeo` without an `ip` parameter](https://ipgeolocation.io/documentation/ip-location-api.html), with your API key in `IPGEO_API_KEY`, and it looks up the caller's IP:

```bash
curl -sS --fail --max-time 10 "https://api.ipgeolocation.io/v3/ipgeo?apiKey=$IPGEO_API_KEY"
```

The response starts with the same `ip` field, followed by objects such as `location`, `asn`, and `time_zone`. A missing or wrong key returns HTTP 401.

The same endpoint can return geolocation, security, network and ASN, company, abuse contact, time zone, and user agent data, so one call can show where an address is, what risk signals it carries, and who runs its network. Locations are built from multiple independent signals, including active measurements, that are cross-checked and refreshed continuously.

A standard lookup costs 1 credit, and security data adds 2. The free plan's 1,000 credits a day cover location, country metadata, currency, ASN basics, and time zone; security, network, company, abuse contact, and user agent data in this response are on paid plans, as the [pricing page](https://ipgeolocation.io/pricing.html) shows.

Our recommendation: use getip when you need only the address, and call `/v3/ipgeo` directly when you need data about it. Keep the API key on your server ([how to secure your API key before production](https://ipgeolocation.io/tutorials/secure-api-key-before-production)); on paid plans, [Request Origin](https://ipgeolocation.io/documentation/api-authentication.html) lets browser code call `/v3/ipgeo` without exposing it.

![Comparison: getip returns only your IP with no key or credits; /v3/ipgeo without an IP adds its data for 1 credit.](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/10/getip-vs-ipgeo-what-your-ip-reveals.webp)

## Frequently asked questions

### Is the getip API free to use?

**Answer:** Yes. IPGeolocation.io's getip endpoint needs no API key or account, uses no credits, and has no rate limit. It runs under the API's 99.99% uptime SLA.

### Why does getip return my server's IP instead of my visitor's?

**Answer:** Because your server made the request. IPGeolocation.io's getip returns the public IP of whatever machine calls it, so a backend call gets the backend's outbound IP unless the request carries a forwarding header. Read a visitor's IP from the incoming request instead.

### How do I get my public IP with curl?

**Answer:** Run `curl -sS --fail --max-time 10 "https://api.ipgeolocation.io/v3/getip?output=text"`. With `output=text`, IPGeolocation.io's getip returns only your public IP address, ready for a shell variable. Leave the parameter out for JSON, or use `output=xml` for XML.

### Can I call getip from browser JavaScript?

**Answer:** Yes. IPGeolocation.io's getip answers `fetch()` calls from web pages on any site without an API key, and in the browser it returns the visitor's public IP. Use it for display or personalization, not security decisions.

### Does getip return location data?

**Answer:** No. IPGeolocation.io's getip returns only the IP address. For its location, ASN, and time zone, call the `/v3/ipgeo` endpoint without an `ip` parameter; it looks up the caller for 1 credit per standard lookup.

* * *

## Next steps

[Get a free IPGeolocation.io API key](https://app.ipgeolocation.io/signup) (1,000 credits a day, no credit card) and run the caller lookup on `/v3/ipgeo`, or start with [Getting Started with the IP Geolocation API](https://ipgeolocation.io/tutorials/getting-started-with-ip-geolocation-api).

### Related Tutorials

[![Check if an IP Is a VPN, Proxy, or Tor Exit Node](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/10/check-if-ip-is-vpn-proxy-or-tor-1.png)](https://ipgeolocation.io/tutorials/check-ip-for-vpn-proxy-tor)

[Check if an IP Is a VPN, Proxy, or Tor Exit Node](https://ipgeolocation.io/tutorials/check-ip-for-vpn-proxy-tor)

Check any IP for VPN, proxy, residential proxy, Tor, and relay flags with a browser lookup, one IPGeolocation.io API call, or the Tor Project's own exit list, then decide what each kind of match deserves.

Posted on October 27, 2026

By Abdul Mateen

[Read More](https://ipgeolocation.io/tutorials/check-ip-for-vpn-proxy-tor)

[![Show Prices in Local Currency Based on IP](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/10/show-prices-in-local-currency-by-ip-1.png)](https://ipgeolocation.io/tutorials/show-prices-in-local-currency-based-on-ip)

[Show Prices in Local Currency Based on IP](https://ipgeolocation.io/tutorials/show-prices-in-local-currency-based-on-ip)

Detect each visitor's currency with one IPGeolocation.io lookup, convert your base price with daily exchange rates, and format it for their locale. Runnable Node.js and Express code, with a switcher that always wins.

Posted on October 22, 2026

By [Daud Ahmad](https://www.linkedin.com/in/daudahmad0303)

[Read More](https://ipgeolocation.io/tutorials/show-prices-in-local-currency-based-on-ip)

[![How to Add Geolocation to Your Shopify Store](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/07/How-to-Add-Geolocation-to-Your-Shopify-Store.svg)](https://ipgeolocation.io/tutorials/add-geolocation-to-shopify)

[How to Add Geolocation to Your Shopify Store](https://ipgeolocation.io/tutorials/add-geolocation-to-shopify)

How to route Shopify visitors to the right market by country, and how to decide whether you need a geolocation app or Shopify's built-in redirect.

Posted on July 14, 2026

By [Anwar Ahmed](https://www.linkedin.com/in/anwar-ce/)

[Read More](https://ipgeolocation.io/tutorials/add-geolocation-to-shopify)

[![How to Get IP Geolocation in JavaScript (Node + Browser)](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/06/ip-geolocation-in-javascript.png)](https://ipgeolocation.io/tutorials/ip-geolocation-in-javascript)

[How to Get IP Geolocation in JavaScript (Node + Browser)](https://ipgeolocation.io/tutorials/ip-geolocation-in-javascript)

Get IP geolocation in JavaScript the right way: the official SDK in Node.js, the correct browser pattern without exposing your key, the visitor's real IP via Express and Next.js, and the location, timezone, currency, ASN, VPN, proxy and threat data the API returns.

Posted on June 24, 2026

By Mudassar Tariq

[Read More](https://ipgeolocation.io/tutorials/ip-geolocation-in-javascript)

[![How to Get IP Geolocation in PHP (API Tutorial)](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/06/ip-geolocation-in-php-1.png)](https://ipgeolocation.io/tutorials/ip-geolocation-in-php)

[How to Get IP Geolocation in PHP (API Tutorial)](https://ipgeolocation.io/tutorials/ip-geolocation-in-php)

Get IP geolocation in PHP with the official IPGeolocation.io library: install with Composer, run your first lookup, and read the real visitor IP in vanilla PHP and Laravel. Links to optional VPN/proxy, abuse contact, and bulk lookups on paid plans.

Posted on June 22, 2026

By Mudassar Tariq

[Read More](https://ipgeolocation.io/tutorials/ip-geolocation-in-php)

[![How to Get IP Geolocation in Python (API Tutorial)](https://blogs.ipgeolocation.io/blogs-site/content/images/2026/06/ipgeolocation-in-python-1.png)](https://ipgeolocation.io/tutorials/ip-geolocation-in-python)

[How to Get IP Geolocation in Python (API Tutorial)](https://ipgeolocation.io/tutorials/ip-geolocation-in-python)

Get IP geolocation in Python with the official IPGeolocation.io library: single lookups, async requests, and real visitor IP handling in Flask and FastAPI, plus optional bulk lookup and VPN/proxy detection examples.

Posted on June 19, 2026

By Mudassar Tariq

[Read More](https://ipgeolocation.io/tutorials/ip-geolocation-in-python)
