Server-side country blocking: SDKs and HTTP
The API supplies an approximate country. Your backend enforces an allowlist, blocklist or explicit unknown-country policy before sending protected content.
Country-blocking overview and SDK downloads
<?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.
For Python, Java, .NET or direct HTTP, open the dedicated implementation guide. Browser decision elements are for controlling your interface; use the server policy when content must not be returned.
