Prerequisites
- A Java 17+ project with
io.ip-api:ipapiadded - A free ip-api.io API key
Catch the typed exceptions
Each exception derives from IpApiException and carries a getStatusCode() and message. Catch the specific type you care about first.
import io.ipapi.exception.*;
try {
IpInfo info = client.lookup("8.8.8.8");
System.out.println(info.ip());
} catch (RateLimitException e) {
System.out.println("quota hit — resets at " + e.getReset());
} catch (AuthenticationException e) {
System.out.println("check your API key");
} catch (InvalidRequestException e) {
System.out.println("bad request: " + e.getMessage());
} catch (ServerException e) {
System.out.println("ip-api.io is having trouble, try later");
} catch (IpApiException e) {
System.out.println("ip-api.io error: " + e.getMessage());
} RuntimeException via IpApiException, so the compiler doesn't
force a try/catch — handle them where it makes sense for your app. Network
failures are wrapped in IpApiException too.
Handle rate limits with RateLimitException
On HTTP 429 you get RateLimitException, carrying the x-ratelimit-* header values (-1 when a header is absent). Because the client never retries, getReset() tells you when to.
} catch (RateLimitException e) {
System.out.println(e.getLimit()); // your quota for the window
System.out.println(e.getRemaining()); // requests left (0 here)
System.out.println(e.getReset()); // Unix timestamp when quota renews
// schedule a retry at e.getReset() instead of hammering the API
} Check quota proactively with rateLimit
Read your current limits without triggering a 429, so you can throttle in advance.
var rl = client.rateLimit();
System.out.println(rl.planName());
System.out.println(rl.ipApi().remaining() + " / " + rl.ipApi().limit());
System.out.printf("%.1f%% used%n", rl.emailApi().usagePercent()); Account usage with usageSummary
Aggregate usage for the current period — handy for dashboards and internal alerts.
var usage = client.usageSummary();
System.out.println(usage.totalRequests() + " " + usage.successfulRequests());
System.out.println(usage.rateLimitedRequests() + " " + usage.quotaConsumed());
System.out.println(usage.periodStart() + " " + usage.periodEnd());