Reverse proxy public IP data API.
View the IP country/region and ASN in a JSON or plain text format.
Try our human interface via curl:
curl ip.charchar.dev
curl ip.charchar.dev/1.1.1.1Or check out the full REST api reference(include details of the human interface): docs/api-reference.md
IPAPI-agent use TOML as the config file format. It'll automatically find ipapi.toml file in the same directory, or you can specific the config file path via the command line flag:
ipapi-agent --config ./ipapi.tomlFor more examples, see: ipapi.toml.example
The GitHub CI will automatically build and push the amd64/arm64/riscv64 containers to the registries. You can pull those containers from:
| Registry | URL |
|---|---|
| Docker Hub | sourlemonjuice/ipapi-agent |
| GitHub Container Registry | ghcr.io/sourlemonjuice/ipapi-agent |
The example Docker Compose file:
name: ipapi
services:
ipapi-agent:
image: sourlemonjuice/ipapi-agent:latest
restart: unless-stopped
ports:
- 8080:8080
volumes:
- ./ipapi.toml:/ipapi.toml:roOr this command:
docker run --rm -it -p 8080:8080 -v ./ipapi.toml:/ipapi.toml:ro sourlemonjuice/ipapi-agent:latestNote
This container is CGO disabled and based on Alpine, don't worry about container size :)
Also, after v0.5.0, you can use a sematic tag like 0.5 to reference the latest version of v0.5.* or set to full version 0.5.0. This replaced old git tag based naming: v0.4.1.
An IPv4 or IPv6 address to use for server listening.
Default: listen = "::"
Server listening port.
Default: port = 8080
Note
Changing the port in container will break the health check. Leave this unset/default.
Controls which IP addresses or CIDRs can use X-Forwarded-For or X-Real-IP, this should be a reverse proxy.
Default: trusted_proxies = ["127.0.0.1", "::1"]
Upstream selection mode. Available values: single, random, rotated.
single: only use your only one upstream or the first one in the list.
random: randomly choice upstream from the upstream list, per-request applied.
rotate: keep rotating the upstream from the upstream list. The interval time can be set with rotate_interval below.
Note
Whatever the mode of selection, the cache system will not be affected at all.
For example, if the cache time-to-live is 6 hours, during these 6 hours the responses all come from one upstream in a cache pool.
Default: mode = "single"
Set one or more upstreams for further selection. Available codenames:
ip-api.com: very normal option and feel reliable, preferred.
Docs: https://ip-api.com/docs/api:jsonipinfo-free: also preferred, but they say this is a legacy/free API :)
Docs: https://ipinfo.io/missingauthipapi.co: free rate limit to 100 requests per month... Added just for fun.
Docs: https://ipapi.co/api/#complete-location
Default: pool = "ipinfo-free"
You can also: pool = ["ip-api.com", "ipinfo-free"]
Upstream rotation interval used in rotate mode. Parse with go's time.ParseDuration().
Default: rotate_interval = "1h"
You can also: rotate_interval = "72h99m23s"
Controls whether domain name resolution is permitted.
Default: enabled = true
Extend the domain public suffix(not only TLD) blocklist used when resolving the domain. You may want to block lan TLD here, which it supported by some home routers DHCP server but standard.
Built-in list is: "alt", "arpa", "invalid", "local", "localhost", "onion", "test", "internal"
You can also append it: block_suffix = ["lan"]
Warning
These entries can not be used in production. Development purpose only.
Turn on debug information output(GIN and others).
Default: debug = false
GIN log, other logs are not affected.
Default: log = false
This software published under Apache-2.0 license.
Copyright 2025 酸柠檬猹/SourLemonJuice