IP to Currency API: Free, Keyless Visitor Currency Detection
Free, keyless IP-to-currency API. GET /api/open/geo returns the visitor's country and local currency from their IP, CORS-open for the browser. Pair it with live rates to show prices in local currency.
To show prices in a visitor's own currency you need two things: their currency, and today's rate.
AllRatesToday gives you both. GET /api/open/geo maps the caller's IP address to a
country and its currency. It needs no API key, sends
Access-Control-Allow-Origin: * so you can call it straight from the browser, and covers
every ISO 3166 country. Live rates then come from /api/v1/rates with your key.
Request
curl "https://allratestoday.com/api/open/geo" Response
{
"country": "GB",
"currency": "GBP",
"source": "cloudflare"
} | Field | Meaning |
|---|---|
country | ISO 3166-1 alpha-2 country of the calling IP, or null when it can't be located (Tor, some VPNs) |
currency | ISO 4217 code of that country's currency, or null with an unknown country |
source | Where the location came from. Always cloudflare: the country Cloudflare's edge assigns to the connecting IP |
The endpoint reads the IP of whoever calls it. Call it from the visitor's browser, not
from your server, or you'll get your server's country. Responses are sent with
Cache-Control: no-store because the answer differs per visitor.
Show prices in local currency
Detect the currency in the browser, then convert on your server so your API key never reaches the page:
// 1. Which currency does this visitor use? (keyless, CORS-open)
const { currency } = await fetch('https://allratestoday.com/api/open/geo')
.then(r => r.json());
// 2. Convert your EUR price on your server (keeps the API key private)
const price = await fetch(`/my-api/local-price?eur=49.99&to=${currency ?? 'USD'}`)
.then(r => r.json()); // Node / Workers: convert with your key, server side
app.get('/my-api/local-price', async (req, res) => {
const { eur, to } = req.query;
const r = await fetch(
`https://allratestoday.com/api/v1/rates?source=EUR&target=${to}`,
{ headers: { Authorization: `Bearer ${process.env.ALLRATES_KEY}` } }
);
const [{ rate }] = await r.json();
res.json({ currency: to, amount: Math.round(eur * rate * 100) / 100 });
});
Using React? The react-currency-localizer-realtime
package uses the same geo endpoint and renders the converted price for you. With no key it
converts at the daily ECB reference rate. Pass apiKey for live rates.
npm install react-currency-localizer-realtime
import { LocalizedPrice } from 'react-currency-localizer-realtime';
<LocalizedPrice basePrice={49.99} baseCurrency="EUR" /> Is it free?
Yes. The geo lookup is free and keyless, and it doesn't count against any quota. Converting
amounts uses /api/v1/rates, which needs a free API key (300
requests, rates refreshed every 60 seconds). Paid plans start at €4.99/mo for 5,000 requests and
commercial use. Cache the rate for a few minutes and one call serves many page views.
Accuracy and limits
- Country-level only. No city, region or coordinates, which is all you need to pick a currency.
- One currency per country. Countries that use several currencies get the main one (for example Panama → PAB, Zimbabwe → ZWG). Let users override it.
- VPNs and travellers show up as the country they connect from. Always give visitors a currency picker.
- Prices shown are estimates if you still charge in your own currency. Say so near the price.
FAQ
Do I need an API key for IP-to-currency?
No. /api/open/geo is keyless. Only the rate conversion needs a key.
Can I pass an IP address as a parameter?
No. It always resolves the caller's own IP, which keeps it accurate and private. For server-side lookups of stored IPs, use a dedicated geo-IP database.
Which currencies can I convert to?
Every currency the geo endpoint returns is one /api/v1/rates serves. See the supported currencies list.
Localise your prices today
Geo lookup is free. Get a key for live rates in 30 seconds.
Get free API key Read the docs