Skip to content
myiphero

01 — Network tool

Free IP address API

Get your public IP from the command line or your code. Plain text and JSON, CORS-enabled, no key required.

No keyCORS *IPv4 + IPv6

Quick start

curl myiphero.com

203.0.113.42

Endpoints

API endpoints
RequestReturnsDescription
GET /text/plainPlain IP for CLI clients (curl, Wget, HTTPie, xh, PowerShell). Browsers get the web page.
GET /iptext/plainYour IP followed by a newline, for any client.
GET /jsonapplication/jsonIP, approximate location and network.
GET /api/ipapplication/jsonSame as /json, for code that prefers an /api path.

Options: /ip?format=json returns JSON instead of text; ?fields=ip,country on the JSON endpoints returns only the listed fields. Sending Accept: application/json to / also returns JSON. All endpoints answer over both IPv4 and IPv6 and support GET, HEADand CORS preflight.

JSON response

GET /json

{
  "ip": "203.0.113.42",
  "version": 4,
  "country": "DE",
  "region": "Hesse",
  "city": "Frankfurt am Main",
  "postalCode": "60311",
  "latitude": 50.1109,
  "longitude": 8.6821,
  "timezone": "Europe/Berlin",
  "asn": 64500,
  "org": "Example Networks GmbH",
  "userAgent": "curl/8.11.1"
}

Missing values are null; the set of keys never changes.

ip
string
Public IP address the request came from.
version
4 | 6
IP version of that address.
country
string | null
ISO 3166-1 alpha-2 country code. T1 = Tor.
region
string | null
Region or state name.
city
string | null
City (approximate).
postalCode
string | null
Postal code (approximate).
latitude
number | null
Latitude of the area, not of the user.
longitude
number | null
Longitude of the area.
timezone
string | null
IANA time zone, e.g. Europe/Berlin.
asn
number | null
Autonomous system number of the network.
org
string | null
Organisation that owns the network (ISP, host, VPN).
userAgent
string | null
The User-Agent header you sent.

Code samples

Bash

# Just the IP
curl myiphero.com
curl https://myiphero.com/ip
wget -qO- https://myiphero.com/ip

# Force IPv4 or IPv6
curl -4 https://myiphero.com/ip
curl -6 https://myiphero.com/ip

# JSON, or a single field with jq
curl https://myiphero.com/json
curl -s https://myiphero.com/json | jq -r .country

# Only some fields
curl "https://myiphero.com/json?fields=ip,country,asn"

Python

import json
import urllib.request

with urllib.request.urlopen("https://myiphero.com/json", timeout=5) as r:
    data = json.load(r)

print(data["ip"], data["country"], data["org"])

# With requests:
# import requests
# ip = requests.get("https://myiphero.com/ip", timeout=5).text.strip()

JavaScript

// Browser or Node.js 18+ (CORS is enabled for every origin)
const res = await fetch("https://myiphero.com/json");
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { ip, country, city } = await res.json();
console.log(ip, country, city);

// Plain text
const myIp = (await (await fetch("https://myiphero.com/ip")).text()).trim();

PHP

<?php
$ctx  = stream_context_create(['http' => ['timeout' => 5]]);

// Plain text
$ip = trim(file_get_contents('https://myiphero.com/ip', false, $ctx));

// JSON
$data = json_decode(file_get_contents('https://myiphero.com/json', false, $ctx), true);
echo $data['ip'] . ' ' . $data['country'] . PHP_EOL;

Go

package main

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

type IPInfo struct {
	IP      string `json:"ip"`
	Version int    `json:"version"`
	Country string `json:"country"`
	ASN     int    `json:"asn"`
	Org     string `json:"org"`
}

func main() {
	client := &http.Client{Timeout: 5 * time.Second}
	resp, err := client.Get("https://myiphero.com/json")
	if err != nil {
		panic(err)
	}
	defer resp.Body.Close()

	var info IPInfo
	if err := json.NewDecoder(resp.Body).Decode(&info); err != nil {
		panic(err)
	}
	fmt.Println(info.IP, info.Country, info.Org)
}

Limits, fair use & privacy

Rate limit

Up to 60 requests per 60 seconds per IP address. Above that the API answers 429 Too Many Requests with a Retry-After header. Limits are counted per Cloudflare location, so treat the number as approximate.

Fair use

  • Cache the result in your app; an IP rarely changes more than once a day.
  • For dynamic DNS or monitoring, poll every 5 minutes or less often.
  • Don’t use the API to load-test or as an uptime target.
  • Set a descriptive User-Agent so we can contact heavy users rather than block them.

No SLA: the service is provided as is and may change, see the terms.

Privacy

We never store your IP address. It is read from the request, written into the response and forgotten. There are no logs of API calls, no cookies and no tracking. Responses are sent withCache-Control: no-store so no shared cache keeps them.

The rate limiter keeps a short-lived counter keyed by your address at the Cloudflare edge for at most60 seconds, only to enforce the limit. Location and network data come from Cloudflare’s request metadata; we do not query third-party lookup services. More in theprivacy policy.

Frequently asked questions

Do I need an API key?

No. The API is free and needs no key. Please keep within the fair-use limits below so it stays that way.

Can I call the API from a browser?

Yes. Every endpoint sends Access-Control-Allow-Origin: *, so fetch() works from any website. The response is never cached, so each call returns the current visitor’s address.

How do I get my IPv6 address only?

Use curl -6 https://myiphero.com/ip. If your machine has no IPv6 connectivity the command fails, which makes it a quick IPv6 check too. curl -4 does the same for IPv4.

How accurate is the location data?

Country is reliable in most cases; region and city are approximate and often point to the provider’s nearest hub. Coordinates mark the centre of an area, never a street address. Do not use them for anything that needs precision.

Can I look up an IP address other than my own?

Not with this API: it only reports the address that makes the request. An IP lookup tool for arbitrary addresses is planned.