JavaScript SDK · Feature

Errors, Rate Limits & Usage

The client maps every HTTP failure to a typed error and 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 class you can branch on, 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

Catch typed errors

Every error extends IpApiError, which carries statusCode and the raw response body. Catch the specific subclass you care about.

import {
  IpApiClient,
  IpApiError,
  AuthenticationError,
  RateLimitError,
  InvalidRequestError,
  ServerError,
} from "ip-api-io";

const client = new IpApiClient({ apiKey: process.env.IP_API_IO_KEY });

try {
  const info = await client.lookup("8.8.8.8");
  console.log(info.location.country);
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log(`quota hit — resets at ${error.reset}`);
  } else if (error instanceof AuthenticationError) {
    console.log("check your API key");
  } else if (error instanceof InvalidRequestError) {
    console.log("bad request:", error.message);
  } else if (error instanceof ServerError) {
    console.log("ip-api.io is having trouble, try later");
  } else if (error instanceof IpApiError) {
    console.log(`error ${error.statusCode}: ${error.message}`);
  } else {
    throw error; // network / timeout — native fetch error
  }
}
Transport failures (DNS, connection, timeout) surface as the native fetch error — e.g. an AbortError once timeoutMs elapses — not an IpApiError.
2

Handle rate limits with RateLimitError

On HTTP 429 the client throws RateLimitError, parsed from the x-ratelimit-* headers. Because the client never retries, reset tells you when to.

try {
  await client.lookup("8.8.8.8");
} catch (error) {
  if (error instanceof RateLimitError) {
    console.log(error.limit);      // your quota for the window
    console.log(error.remaining);  // requests left (0 here)
    console.log(error.reset);      // unix timestamp when quota renews
    const waitMs = (error.reset ?? 0) * 1000 - Date.now();
    // schedule a retry after `waitMs` 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.

const rl = await client.rateLimit();

console.log(rl.plan_name);
console.log(rl.ip_api.remaining, "/", rl.ip_api.limit);
console.log(rl.email_api.usage_percent, "% used");
console.log(rl.next_renewal_date);
4

Account usage with usageSummary

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

const usage = await client.usageSummary();

console.log(usage.totalRequests, usage.successfulRequests);
console.log(usage.rateLimitedRequests, usage.quotaConsumed);
console.log(usage.periodStart, "→", usage.periodEnd);
Reference

Error taxonomy

ErrorHTTP statusMeaning
AuthenticationError401, 403Missing or invalid API key
RateLimitError429Quota exhausted; exposes limit, remaining, reset
InvalidRequestError400, 404, 422Malformed input or unknown resource
ServerError5xxip-api.io server-side failure
IpApiErrorotherBase / fallback (carries statusCode, body)
FAQ

Frequently asked questions

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

Wrap calls in try/catch and check the typed subclass: AuthenticationError (401/403), RateLimitError (429), InvalidRequestError (400/404/422), ServerError (5xx), or the base IpApiError. Transport failures like timeouts surface as the native fetch error.

Does the SDK retry failed requests automatically?

No. The client never retries — you stay in control of back-off. On a 429, RateLimitError.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 await client.rateLimit(). 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 RateLimitError expose?

RateLimitError is parsed from the x-ratelimit-* response headers and exposes limit (quota for the window), remaining (requests left), and reset (unix timestamp when quota renews). Use reset to compute how long to wait before retrying.

Start building with the ip-api.io JavaScript SDK

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

Open on GitHub