Java SDK · Feature

Errors, Rate Limits & Usage

Every method throws a typed exception on failure and the client never retries — you stay in control of back-off. It also exposes your current quota so you can throttle before you hit a limit, and aggregate usage for dashboards and alerts.

Trusted by thousands of businesses
Fast JSON API responses
Real-time validation
Simple integration, SDKs & examples
What it does

Predictable failures, no hidden retries

Network calls fail — keys expire, quotas run out, servers hiccup. The SDK turns each HTTP status into a specific exception type you can catch, and deliberately leaves retry policy to you, so a burst of failures can't silently multiply your request volume. When you do hit a rate limit, the exception tells you exactly when the quota resets.

Prerequisites

1

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());
}
Unchecked exceptions: all SDK exceptions extend 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.
2

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
}
3

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());
4

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());
Reference

Exception taxonomy

ExceptionHTTP statusMeaning
AuthenticationException401, 403Missing or invalid API key
RateLimitException429Quota exhausted; exposes getLimit(), getRemaining(), getReset()
InvalidRequestException400, 404, 422Malformed input or unknown resource
ServerException5xxip-api.io server-side failure
IpApiExceptionotherBase type for all of the above (unchecked; also wraps transport failures)
FAQ

Frequently asked questions

How do I handle errors from the ip-api.io SDK in Java?

Every method throws on failure. Catch the typed exceptions, all derived from IpApiException: AuthenticationException (401/403), RateLimitException (429), InvalidRequestException (400/404/422), and ServerException (5xx). They are unchecked, so you opt into handling them.

Does the SDK retry failed requests automatically?

No. The client never retries — you stay in control of back-off. On a 429, RateLimitException.getReset() gives the Unix timestamp when your quota renews, so you can schedule a retry instead of hammering the API.

How do I check my remaining quota before hitting a limit?

Call client.rateLimit(). It returns planId(), planName(), and ipApi() / emailApi() blocks with limit(), remaining(), used() and usagePercent(), plus intervalSeconds() and nextRenewalDate().

What does RateLimitException expose?

RateLimitException is parsed from the x-ratelimit-* response headers and exposes getLimit() (quota for the window), getRemaining() (requests left), and getReset() (Unix timestamp when quota renews). Headers absent? The value is -1.

Start building with the ip-api.io Java SDK

Add io.ip-api:ipapi to your build, drop in your free API key, and ship in minutes — one client for geolocation, fraud detection, and email validation.

Need support?

Explore how IP-API.io can enhance your security, provide robust bot protection, and improve IP geolocation accuracy for your applications.

Contact Support

Found a bug in the SDK?

The io.ip-api:ipapi library is open source. Open an issue or pull request on GitHub and we'll take a look.

Open on GitHub