IP location.
With context.
Know where a request comes from—and what the data can tell you. Look up IP locations, compare sources, and build a more local experience.
My IP lookup.
See your public IP address and its approximate location.
Press “Look up my IP” to pull your response. Nothing is requested automatically.
Uses one of your public website lookups. IP location is an estimate, not a precise physical address.
integrations
address support
source refreshes
REST API
Look up another IP.
See the estimated location, network, and the data behind each result.
Mountain View, United States
This preview uses example responses and a browser-local counter. Production lookups require the PHP service, approved datasets, and server-enforced quotas.
More than a pin on a map.
Build for where people are.
And understand the data that gets you there.
See where the
answer comes from.
Compare available source results. See disagreements. Follow each answer back to its original dataset.
“Up to date”
needs a timestamp.
Each source moves at its own pace. Know the version, the publication date, and when it became available.
published_at → activated_atMake the first
interaction local.
Country, phone, and language pickers. Server-side country policies. Small building blocks, less setup.
Try the building blocks ↗One request.
Useful context.
A predictable REST API, readable responses, and examples in the languages you already use.
- IPv4 and IPv6 support
- Source-level provenance and freshness
- Clear errors and predictable credit usage
How accurate is IP geolocation?
IP geolocation is an estimate. Country results are generally more stable than city results. Mobile networks, VPNs, and routing changes can affect location. ORIGOOO shows provenance and uncertainty rather than a numerical accuracy guarantee.
Are all seven integrations independent?
No. Distributions may mirror upstream records. ORIGOOO tracks lineage so mirrored datasets do not count as independent votes. The registry shows each integration’s role and readiness.
How do the free allowances work?
The public website allowance is 10 lookup actions per visitor per UTC day. Registered Free accounts receive 1,000 API credits per month. Standard lookups cost one credit and all-source comparisons cost two. The preview uses sample data only.
Can I use this to block access by country?
Country policies must be enforced on your server. A frontend widget alone does not secure content. SDK policies should define trusted proxies, caching, and how unknown locations and service outages are handled.
Apply country rules in Python.
Look up the request country, apply your policy and decide before sending protected content.
1. Install and configure
Extract the SDK and run python -m pip install ./path/to/extracted-sdk inside your virtual environment. It requires Python 3.10+. Wrap the existing WSGI/ASGI app before serving protected routes, and supply explicit proxy CIDRs where applicable.
Download Python SDKSet ORIGOOO_API_KEY on your server. Use a secret key with lookup scope and the API origin https://orig.ooo. These SDKs are source downloads, not public package-registry releases.
2. Apply the rule before your response
This example blocks US and GB, allows other matched countries, and denies when location is unknown. Choose the unknown behaviour for your own service before deployment.
<?php
require __DIR__ . '/origooo-sdk/src/Client.php';
require __DIR__ . '/origooo-sdk/src/Policy.php';
$client = new \OrigoooSdk\Client(getenv('ORIGOOO_API_KEY'), 'https://orig.ooo');
$policy = new \OrigoooSdk\Policy(blocked: ['US', 'GB'], unknown: 'deny');
$country = null;
try {
// Configure trusted proxy CIDRs if your app is behind a proxy.
$ip = \OrigoooSdk\Client::clientIP($_SERVER['REMOTE_ADDR'] ?? '',
$_SERVER['HTTP_X_FORWARDED_FOR'] ?? '', []);
$country = $client->lookup($ip)['country_code'] ?? null;
} catch (\Throwable $error) {
// The policy's explicit unknown behaviour handles lookup failures.
}
if ($policy->decide($country) !== 'allow') {
http_response_code(403);
exit('This service is unavailable for this request.');
}
// Render your protected page only after the policy allows it.import os
from origooo import Client, Policy, WSGIMiddleware
client = Client(os.environ['ORIGOOO_API_KEY'], base_url='https://orig.ooo')
policy = Policy(blocked=frozenset({'US', 'GB'}), unknown='deny')
def protected_app(environ, start_response):
start_response('200 OK', [('Content-Type', 'text/plain')])
return [b'Allowed content']
# Put the middleware before your existing WSGI application.
app = WSGIMiddleware(protected_app, client, policy, trusted_proxies=[])
# ASGI applications can use ASGIMiddleware with the same client/policy.import ooo.orig.Origooo;
import java.time.Duration;
import java.util.Set;
var client = new Origooo(System.getenv("ORIGOOO_API_KEY"),
"https://orig.ooo", Duration.ofSeconds(2), Duration.ofMinutes(5));
var policy = new Origooo.Policy(Set.of(), Set.of("US", "GB"), "deny");
// In your Servlet/Spring filter before invoking the next handler:
String country = null;
try {
// Resolve visitorIp with the SDK's configured proxy-chain helper.
country = client.lookup(visitorIp).countryCode();
} catch (InterruptedException error) {
Thread.currentThread().interrupt();
} catch (java.io.IOException | IllegalArgumentException error) {
// Leave country unknown; the configured policy decides.
}
if (!policy.decide(country).equals("allow")) {
response.setStatus(403);
return;
}
chain.doFilter(request, response);using Origooo;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton(new OrigoooClient(new HttpClient(),
Environment.GetEnvironmentVariable("ORIGOOO_API_KEY")!,
new Uri("https://orig.ooo")));
builder.Services.AddSingleton(new CountryPolicy(
blocked: new[] { "US", "GB" }, unknown: "deny"));
var app = builder.Build();
// If needed, configure Forwarded Headers with explicit trusted proxies
// before this middleware. Never trust arbitrary forwarded headers.
app.UseMiddleware<CountryMiddleware>();
app.MapGet("/protected", () => "Allowed content");
app.Run();// Node.js 20+ server-side policy helper. Keep this key off the browser.
async function countryPolicy(visitorIp) {
const response = await fetch(
'https://orig.ooo/v1/ip/' + encodeURIComponent(visitorIp), {
headers: {Authorization: 'Bearer ' + process.env.ORIGOOO_API_KEY},
signal: AbortSignal.timeout(2000)
});
const body = await response.json();
if (!response.ok) throw new Error(body.error?.code || body.code || 'lookup_failed');
const country = body.country_code;
return {country, allowed: !!country && !['US', 'GB'].includes(country)};
}
// Validate visitorIp as a public literal IP in your server framework.
// Apply this before rendering protected content:
// try { const result = await countryPolicy(visitorIp);
// if (!result.allowed) return a403Response(); }
// catch { return yourExplicitUnknownCountryFallback(); }Direct HTTP helper for your server framework.
3. Verify your request path
- Verify an allowed country reaches your application handler.
- Verify a blocked country returns 403 before protected content is rendered.
- Simulate a timeout, 429, missing country and invalid IP; verify your explicit unknown policy.
- Confirm untrusted forwarded headers cannot change the visitor IP.
- Keep administrator/health-route exceptions in trusted application code.
Choose when to use this
Use server policies for regional service availability and applications with a defined country policy. For an offer or message that merely appears or disappears, use the browser decision element. Browser hiding does not prevent downloading content already sent to the client.
The API supplies approximate geography. VPNs, mobile networks and proxies affect the result. Treat a country rule as one input to your application, not proof of residence.
Complete Python reference → · Error handling · Request speed and credits
