Rust SDK · Feature

Errors, Rate Limits & Usage

Every method returns Result<T, Error> 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 Error variant you can match, 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 error tells you exactly when the quota resets.

Prerequisites

1

Match the Error enum

Each API-status variant carries a status and message. Match the specific variant you care about.

use ip_api_io::Error;

match client.lookup_ip("8.8.8.8").await {
    Ok(info) => println!("{}", info.ip),
    Err(Error::RateLimit { reset, .. }) => {
        println!("quota hit — resets at {reset}");
    }
    Err(Error::Authentication { .. }) => println!("check your API key"),
    Err(Error::InvalidRequest { message, .. }) => println!("bad request: {message}"),
    Err(Error::Server { .. }) => println!("ip-api.io is having trouble, try later"),
    Err(Error::Transport(e)) => println!("transport / decode error: {e}"),
    Err(e) => println!("other error: {e}"),
}
Transport failures (DNS, connect, timeout, decode) surface as Error::Transport, which wraps the underlying reqwest error — they are not an API status error.
2

Handle rate limits with the RateLimit variant

On HTTP 429 you get Error::RateLimit, carrying the x-ratelimit-* header values (-1 when a header is absent). Because the client never retries, reset tells you when to.

Err(Error::RateLimit { limit, remaining, reset }) => {
    println!("{limit}");     // your quota for the window
    println!("{remaining}"); // requests left (0 here)
    println!("{reset}");     // unix timestamp when quota renews
    // schedule a retry at `reset` instead of hammering the API
}
3

Check quota proactively with rate_limit

Read your current limits without triggering a 429, so you can throttle in advance.

let rl = client.rate_limit().await?;

if let Some(plan) = &rl.plan_name {
    println!("{plan}");
}
println!("{} / {}", rl.ip_api.remaining, rl.ip_api.limit);
println!("{:.1}% used", rl.email_api.usage_percent);
4

Account usage with usage_summary

Aggregate usage for the current period — handy for dashboards and internal alerts.

let usage = client.usage_summary().await?;

println!("{} {}", usage.total_requests, usage.successful_requests);
println!("{} {}", usage.rate_limited_requests, usage.quota_consumed);
println!("{} {}", usage.period_start, usage.period_end);
Reference

Error taxonomy

VariantHTTP statusMeaning
Error::Authentication401, 403Missing or invalid API key
Error::RateLimit429Quota exhausted; carries limit, remaining, reset
Error::InvalidRequest400, 404, 422Malformed input or unknown resource
Error::Server5xxip-api.io server-side failure
Error::ApiotherFallback for any other status (carries status, message)
Error::TransportNetwork / decode failure (wraps the reqwest error)
FAQ

Frequently asked questions

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

Every method returns Result<T, Error>. match on the Error enum: Authentication (401/403), RateLimit (429), InvalidRequest (400/404/422), Server (5xx), or Api for other statuses. Transport failures surface as Transport.

Does the SDK retry failed requests automatically?

No. The client never retries — you stay in control of back-off. On a 429, the RateLimit variant's reset 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.rate_limit().await?. It returns plan_id, plan_name, and ip_api / email_api blocks with limit, remaining, used and usage_percent, plus interval_seconds and next_renewal_date.

What does the RateLimit variant expose?

The Error::RateLimit variant is parsed from the x-ratelimit-* response headers and carries limit (quota for the window), remaining (requests left), and reset (unix timestamp when quota renews). Headers absent? The value is -1.

Start building with the ip-api.io Rust SDK

Run cargo add ip-api-io, drop in your free API key, and ship in minutes — one async 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 ip-api-io crate is open source. Open an issue or pull request on GitHub and we'll take a look.

Open on GitHub