Skip to content

Authentication

Every request to the IPWho API must be authenticated with your API key. You can get a key — free, 2,000 lookups/day, no credit card — from the free plan page. This page covers the three ways to send the key, which to prefer, and how authentication errors surface.

The API accepts your key three ways. All three return the same response; they differ only in how exposed the key is.

Send the key as a Bearer token. This keeps it out of request URLs, browser history, proxy logs, and analytics — the safest option for server-side code.

Terminal window
curl -sS -H "Authorization: Bearer sk.xxx" \
"https://api.ipwho.org/ip/8.8.8.8"

A plain custom header, equivalent in security to the Bearer form. Use whichever fits your HTTP client’s conventions.

Terminal window
curl -sS -H "X-API-Key: sk.xxx" \
"https://api.ipwho.org/ip/8.8.8.8"

Append apiKey to the URL. This is the fastest way to test a call, but the key becomes part of the full URL — which is commonly written to server logs, browser history, and referrer headers. Prefer a header for anything beyond a quick test.

Terminal window
curl -sS "https://api.ipwho.org/ip/8.8.8.8?apiKey=sk.xxx"

Load the key from an environment variable rather than hardcoding it, and never commit it to version control:

import os, urllib.request, json
API_KEY=os.env...Y"] # set it in your environment, not in code
req = urllib.request.Request(
"https://api.ipwho.org/ip/8.8.8.8",
headers={"Authorization": f"Bearer {API_KEY}"},
)
with urllib.request.urlopen(req, timeout=10) as resp:
data = json.loads(resp.read())

When a key is missing or invalid, the API responds with HTTP 401 and a JSON body describing the problem:

{ "error": "missing_api_key" }
{ "error": "invalid_api_key" }

Handle these by checking the HTTP status before parsing the response, and surface a clear message to the caller rather than retrying — a 401 will not succeed on retry with the same key.