> For the complete documentation index, see [llms.txt](https://docs.ipcheck.ing/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ipcheck.ing/developer/configuration/optional-api-keys.md).

# Optional API Keys

None of the keys on this page are required. MyIP starts and serves traffic without a single one of them. Each key simply switches on one more capability.

The pattern is always the same:

1. You set an environment variable and restart the backend.
2. The backend exposes a **boolean** (never the value) for that variable through `GET /api/configs`.
3. The frontend reads those booleans and shows, hides, or disables the matching UI.

{% hint style="info" %}
`/api/configs` only ever answers `true` / `false`. Your keys stay on the server and are never sent to the browser.
{% endhint %}

## Summary

| Environment variable                                   | Unlocks                                                                        | Cost                              |
| ------------------------------------------------------ | ------------------------------------------------------------------------------ | --------------------------------- |
| `IPINFO_API_KEY`                                       | IPinfo.io as a selectable IP geolocation source                                | Free plan available               |
| `IPAPIIS_API_KEY`                                      | IPAPI.is as a selectable IP geolocation source                                 | See provider pricing              |
| `IP2LOCATION_API_KEY`                                  | IP2Location.io as a selectable IP geolocation source                           | Free plan available               |
| `GOOGLE_MAP_API_KEY`                                   | Map button on IP detail cards (Google Static Maps)                             | Google Cloud account with billing |
| `MAC_LOOKUP_API_KEY`                                   | Authenticated MAC Lookup requests (the tool works without it)                  | Free plan available               |
| `CLOUDFLARE_API_KEY`                                   | ASN Info panel (Cloudflare Radar) — and, with the two below, shareable reports | Free Cloudflare account           |
| `CLOUDFLARE_ACCOUNT_ID` + `CLOUDFLARE_KV_NAMESPACE_ID` | Shareable diagnostic reports stored in Workers KV                              | Free Cloudflare account           |
| `RIPESTAT_SOURCE_APP`                                  | Not a key — identifies your deployment to RIPEstat                             | Free, no signup                   |

{% hint style="warning" %}
`/api/configs` is edge-cacheable for one hour. After adding a key and restarting, a CDN or browser may keep serving the old feature flags for up to an hour. Hard-refresh or purge the cache if a new feature does not appear.
{% endhint %}

## IP geolocation sources

MyIP can query several IP databases. The user picks the active one in **Preferences**. Sources whose key is missing are shown struck-through and cannot be selected; if a previously saved choice loses its key, it is moved to the nearest available source automatically, with a notice.

Three sources are key-gated: IPinfo.io, IPAPI.is, and IP2Location.io. The others (IP-API.com, IP.sb, MaxMind) need no key — see [MaxMind Setup](/developer/getting-started/maxmind-setup.md) and [IP Data Sources](/developer/architecture/ip-data-sources.md).

### IPinfo.io — `IPINFO_API_KEY`

* **Unlocks**: `IPinfo.io` in the IP source picker, served by `GET /api/ipinfo`.
* **Without it**: the source is disabled in the picker. (The endpoint itself falls back to a token-less request, but the UI will not offer it.)
* **Where to get it**: sign up at [ipinfo.io](https://ipinfo.io/) and copy the access token from your dashboard.

{% hint style="info" %}
The legacy spelling `IPINFO_API_TOKEN` is still read as a fallback, so old deployments keep working after an upgrade. New setups should use `IPINFO_API_KEY`.
{% endhint %}

### IPAPI.is — `IPAPIIS_API_KEY`

* **Unlocks**: `IPAPI.is` in the IP source picker, served by `GET /api/ipapiis`. This source also returns hosting / proxy flags.
* **Without it**: the source is disabled in the picker. Calling the endpoint directly returns a 500.
* **Where to get it**: sign up at [ipapi.is](https://ipapi.is/).

### IP2Location.io — `IP2LOCATION_API_KEY`

* **Unlocks**: `IP2Location.io` in the IP source picker, served by `GET /api/ip2location`.
* **Without it**: the source is disabled in the picker. Calling the endpoint directly returns a 500.
* **Where to get it**: sign up at [ip2location.io](https://www.ip2location.io/).

{% hint style="success" %}
**Key rotation is built in.** `IPINFO_API_KEY`, `IPAPIIS_API_KEY`, `IP2LOCATION_API_KEY` and `GOOGLE_MAP_API_KEY` all accept a **comma-separated list**. One key is picked at random per request, which spreads load across several free accounts.

```bash
IPINFO_API_KEY="token_one,token_two,token_three"
```

{% endhint %}

## Google Maps — `GOOGLE_MAP_API_KEY`

* **Unlocks**: the map button on an IP detail card. It opens a static map centred on the IP's coordinates, served by `GET /api/map`, with a dedicated dark-mode style.
* **Without it**: the map button never renders. Everything else on the card is unaffected.
* **Where to get it**: Google Cloud Console → enable the **Maps Static API** → create an API key. A billing-enabled Google Cloud project is required.

{% hint style="warning" %}
Restrict the key in Google Cloud (by API, and by IP where possible) before putting it on a public instance. The backend proxies the image, so the key never reaches visitors — but a key leaked from the server side is still a billing risk.
{% endhint %}

## MAC Lookup — `MAC_LOOKUP_API_KEY`

* **Unlocks**: authenticated requests to [maclookup.app](https://maclookup.app/) from the MAC Lookup tool (`GET /api/macchecker`).
* **Without it**: the tool still works. The backend sends the request without a key, and whatever limits the provider applies to anonymous traffic apply to you.
* **Where to get it**: register at [maclookup.app](https://maclookup.app/) and create an API key.

This is the one key on this page that buys throughput rather than a feature.

## Cloudflare Radar — `CLOUDFLARE_API_KEY`

* **Unlocks**: the **ASN Info** button in the ASN block of an IP detail card, served by `GET /api/cfradar`. The panel shows the ASN name, country, organization and estimated user count, plus 7-day traffic splits: IPv4 vs IPv6, HTTP vs HTTPS, desktop vs mobile, bot vs human.
* **Without it**: the ASN Info button is hidden. The two neighbouring buttons — **ASN History** and **ASN Connectivity** — keep working: they are powered by RIPEstat and by local CAIDA snapshots, not by Cloudflare.
* **Where to get it**: Cloudflare dashboard → **My Profile → API Tokens → Create Token**. The token needs read access to Radar.

{% hint style="info" %}
The legacy spelling `CLOUDFLARE_API` is still read as a fallback.
{% endhint %}

Radar data is fetched as five independent segments. If some of them fail, the panel degrades field by field instead of erroring out — small or private ASNs legitimately have no traffic data.

## Shareable reports — `CLOUDFLARE_ACCOUNT_ID` + `CLOUDFLARE_KV_NAMESPACE_ID`

MyIP can turn a diagnostic run into a share link backed by Cloudflare Workers KV.

* **Unlocks**: `POST /api/report` (store) and `GET /api/report/:id` (read), plus the share-link option in the report dialog and the read-only report page.
* **Requires all three of**: `CLOUDFLARE_API_KEY`, `CLOUDFLARE_ACCOUNT_ID`, `CLOUDFLARE_KV_NAMESPACE_ID`. Miss any one and the feature stays off.
* **Without them**: both endpoints answer `503`, `/api/configs` reports `reportSharing: false`, and the share UI never appears. Users can still copy the report as Markdown or download it as JSON.

<details>

<summary>Setting it up</summary>

1. Cloudflare dashboard → **Workers & Pages → KV** → create a namespace.
2. Copy the namespace's **hex ID** — not its name. `CLOUDFLARE_KV_NAMESPACE_ID` expects the ID.
3. Copy your **Account ID** from the dashboard into `CLOUDFLARE_ACCOUNT_ID`.
4. Make sure the token in `CLOUDFLARE_API_KEY` also carries the **Workers KV Storage: Edit** permission. The same token is used for Radar and for KV.

</details>

How stored reports behave:

* The report body is validated against a strict schema whitelist — no free-form text can be stored.
* Report IDs are 16 random bytes, base64url-encoded (22 characters), so links are unguessable.
* Each report is written with a TTL and expires from KV on its own. Expired IDs answer `404`.
* Reports are never edge-cached, on read or on write.

{% hint style="warning" %}
The report endpoints have **no dedicated rate limit**. On a public instance, cover them with the global limiter (see [Security Options](/developer/configuration/security-options.md)) or with edge rules.
{% endhint %}

## RIPEstat — `RIPESTAT_SOURCE_APP`

This is not an API key and needs no account. RIPEstat asks callers to identify themselves through a `sourceapp` parameter; this variable sets it. It defaults to `myip`.

Set it to something that identifies your deployment (for example `myip-yourdomain`) so your traffic is distinguishable if RIPE ever needs to reach you about it.

RIPEstat powers ASN History and the org-name fallback used by ASN Connectivity. Both work whether or not this variable is set.

## Things that need no configuration

* **GitHub stars** (`GET /api/github-stars`) calls GitHub's public REST API unauthenticated and is edge-cached for a day. There is no token to set.
* **ASN Connectivity** runs off local CAIDA snapshots, with RIPEstat only as a fallback for missing org names.

## Setting the variables

{% tabs %}
{% tab title="Node (.env)" %}
{% code title=".env" %}

```bash
IPINFO_API_KEY="your-ipinfo-token"
IPAPIIS_API_KEY="your-ipapi-is-key"
IP2LOCATION_API_KEY="your-ip2location-key"
GOOGLE_MAP_API_KEY="your-google-maps-key"
MAC_LOOKUP_API_KEY="your-maclookup-key"
CLOUDFLARE_API_KEY="your-cloudflare-token"
CLOUDFLARE_ACCOUNT_ID="your-account-id"
CLOUDFLARE_KV_NAMESPACE_ID="your-namespace-hex-id"
RIPESTAT_SOURCE_APP="myip-yourdomain"
```

{% endcode %}

Restart the backend afterwards. See [Deploy with Node.js](/developer/getting-started/deploy-with-nodejs.md).
{% endtab %}

{% tab title="Docker" %}

```bash
docker run -d -p 18966:18966 \
  -e IPINFO_API_KEY="your-ipinfo-token" \
  -e GOOGLE_MAP_API_KEY="your-google-maps-key" \
  -e CLOUDFLARE_API_KEY="your-cloudflare-token" \
  -e CLOUDFLARE_ACCOUNT_ID="your-account-id" \
  -e CLOUDFLARE_KV_NAMESPACE_ID="your-namespace-hex-id" \
  -e RIPESTAT_SOURCE_APP="myip-yourdomain" \
  --name myip \
  jason5ng32/myip:latest
```

Every variable on this page is read at runtime, so `docker run -e` is enough — no rebuild needed. See [Deploy with Docker](/developer/getting-started/deploy-with-docker.md).
{% endtab %}
{% endtabs %}

## Related pages

* [Environment Variables](/developer/reference/environment-variables.md) — the full list, including the required ones
* [Features Tied to IPCheck.ing](/developer/configuration/features-tied-to-ipcheck-ing.md) — capabilities that depend on private services
* [API Endpoints](/developer/reference/api-endpoints.md) — what each route returns
* [Security Options](/developer/configuration/security-options.md) — keep strangers from burning your quota


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.ipcheck.ing/developer/configuration/optional-api-keys.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
