Swift SDK · Feature

Errors, Rate Limits & Usage

Every method throws IpApiError 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 IpApiError case you can switch over, 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

Switch over the IpApiError enum

Each API-status case carries the relevant details. Switch over the specific case you care about.

do {
    let info = try await client.lookup(ip: "8.8.8.8")
    print(info.ip)
} catch let error as IpApiError {
    switch error {
    case .rateLimit(_, _, let reset):
        print("quota hit — resets at \(reset)")
    case .authentication:
        print("check your API key")
    case .invalidRequest(let message):
        print("bad request: \(message)")
    case .server(let status):
        print("ip-api.io is having trouble (status \(status)), try later")
    case .transport(let underlying):
        print("transport / decode error: \(underlying)")
    }
}
Transport failures (DNS, connect, timeout, decode) surface as .transport, which wraps the underlying URLSession / DecodingError — they are not an API status error.
2

Handle rate limits with the .rateLimit case

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

case .rateLimit(let limit, let remaining, let reset):
    print(limit)     // your quota for the window
    print(remaining) // requests left (0 here)
    print(reset)     // Unix timestamp when quota renews
    // schedule a retry at `reset` 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.

let rl = try await client.rateLimit()

print(rl.planName ?? "")
print("\(rl.ipApi.remaining) / \(rl.ipApi.limit)")
print(String(format: "%.1f%% used", rl.emailApi.usagePercent))
4

Account usage with usageSummary

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

let usage = try await client.usageSummary()

print(usage.totalRequests, usage.successfulRequests)
print(usage.rateLimitedRequests, usage.quotaConsumed)
print(usage.periodStart, usage.periodEnd)
Reference

Error taxonomy

CaseHTTP statusMeaning
.authentication401, 403Missing or invalid API key
.rateLimit429Quota exhausted; carries limit, remaining, reset
.invalidRequest400, 404, 422Malformed input or unknown resource
.server5xxip-api.io server-side failure
.transportNetwork / decode failure (wraps the underlying error)
FAQ

Frequently asked questions

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

Every method throws IpApiError. switch over the enum: .authentication (401/403), .rateLimit (429), .invalidRequest (400/404/422), .server (5xx), or .transport for network/decode failures.

Does the SDK retry failed requests automatically?

No. The client never retries — you stay in control of back-off. On a 429, the .rateLimit case'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 try await client.rateLimit(). It returns planId, planName, and ipApi / emailApi blocks with limit, remaining, used and usagePercent, plus intervalSeconds and nextRenewalDate.

What does the rateLimit case expose?

The .rateLimit case 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 Swift SDK

Add ipapi-swift via Swift Package Manager, 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 ipapi-swift package is open source. Open an issue or pull request on GitHub and we'll take a look.

Open on GitHub