FAIR PRICES
FOR THE
ENTIRE WORLD.

One API call. Country detection. PPP data. Suggested discount. Local currency. Done.

GET YOUR API KEY READ THE DOCS
INDIA 70% OFF — BRAZIL 50% OFF — NIGERIA 60% OFF — POLAND 40% OFF — JAPAN 10% OFF — SWITZERLAND 0% OFF — EGYPT 80% OFF — MEXICO 50% OFF —  INDIA 70% OFF — BRAZIL 50% OFF — NIGERIA 60% OFF — POLAND 40% OFF — JAPAN 10% OFF — SWITZERLAND 0% OFF — EGYPT 80% OFF — MEXICO 50% OFF — 

TRY IT.

// HIT CALCULATE.

HOW IT WORKS.

01

CALL THE API

One API call from your backend with the visitor's country. Get the adjusted price, local currency, and discount. Your API key stays on the server.

02

CHARGE THE RIGHT PRICE

Pass the adjusted price to your payment processor. Works with Stripe, Paddle, LemonSqueezy, anything.

03

CONVERT MORE

Customers see fair prices, get charged fair prices. VPN detection prevents discount abuse. International conversions go up.

ONE API CALL. SERVER-SIDE.

Call /v1/pricing from your backend with the visitor's country. Your API key never touches the client. Works with any framework — Next.js, Express, Cloudflare Workers, Rails, Django, anything with HTTP.

NEXT.JS

// app/api/pricing/route.ts
export async function POST(req) {
  const { price } = await req.json();

  // Get visitor info from headers (Cloudflare, Vercel, etc.)
  const country = req.headers.get('CF-IPCountry')
    || req.headers.get('X-Vercel-IP-Country') || 'US';
  const ip = req.headers.get('CF-Connecting-IP')
    || req.headers.get('X-Forwarded-For')?.split(',')[0] || '';

  const parity = await fetch(
    `https://api.getparity.dev/v1/pricing?base_price=${price}&client_country=${country}`,
    { headers: {
      'X-API-Key': process.env.PARITY_KEY,
      'X-Client-IP': ip,
    }}
  ).then(r => r.json());

  return Response.json({
    adjustedPrice: parity.pricing.adjustedPrice,
    localPrice: parity.pricing.localPrice,
    currency: parity.currency,
    discount: parity.pricing.discountPercent,
  });
}
EXPRESS
app.post('/checkout', async (req, res) => {
  const ip = req.headers['x-forwarded-for']?.split(',')[0] || req.ip;

  // 1. Get PPP-adjusted price
  const parity = await fetch(
    `https://api.getparity.dev/v1/pricing?base_price=${req.body.price}&client_country=${req.body.country}`,
    { headers: {
      'X-API-Key': process.env.PARITY_KEY,
      'X-Client-IP': ip,
    }}
  ).then(r => r.json());

  // 2. Create Stripe checkout with adjusted price
  const session = await stripe.checkout.sessions.create({
    line_items: [{
      price_data: {
        currency: parity.currency.code.toLowerCase(),
        unit_amount: Math.round(parity.pricing.localPrice * 100),
        product_data: { name: 'Your Product' },
      },
      quantity: 1,
    }],
    mode: 'payment',
  });

  res.json({ url: session.url });
});
CLOUDFLARE WORKERS
export default {
  async fetch(request, env) {
    const country = request.cf?.country || 'US';
    const ip = request.headers.get('CF-Connecting-IP') || '';

    const parity = await fetch(
      `https://api.getparity.dev/v1/pricing?base_price=99&client_country=${country}&client_timezone=${request.cf?.timezone}`,
      { headers: {
        'X-API-Key': env.PARITY_KEY,
        'X-Client-IP': ip,
      }}
    ).then(r => r.json());

    return Response.json(parity);
  }
};

Pass client_timezone and client_asn for VPN detection. The X-Client-IP header ensures distinct-IP tracking uses the visitor's real IP, not your server's.

API REFERENCE.

Base URL: https://api.getparity.dev/v1
All authenticated endpoints require the X-API-Key header. Hit GET /v1 for machine-readable docs.

GET /v1/pricing AUTH

Calculate PPP-adjusted pricing. Supports a single price or multiple prices in one call (ideal for shops with many products).

PARAMTYPEREQDESCRIPTION
base_pricenumber*Single product price in USD. Use this OR prices.
pricesstring*Comma-separated prices in USD (max 100). Use this OR base_price.
countrystringNOISO 3166 country code (auto-detected from IP if omitted)
tokenstringNOSigned visitor token from /v1/detect (enables server-side calls with accurate VPN detection)
vpn_overridestringNOSet to "true" to flag this request as VPN-detected. Use with your own VPN detection service (e.g. IPinfo).
presetstringNOPreset ID or name for custom discount rules. Uses active preset or defaults if omitted.
client_countrystringNOVisitor's country code for server-side flow. Overrides auto-detection.
client_timezonestringNOVisitor's IANA timezone (e.g. Asia/Kolkata) for server-side VPN detection.
client_asnnumberNOVisitor's ASN for server-side VPN detection.

Header: X-Client-IP — Visitor's real IP for distinct-IP tracking in server-side integrations.

// Single price
curl "https://api.getparity.dev/v1/pricing?base_price=99&country=IN" \
     -H "X-API-Key: parity_live_YOUR_KEY"

// Multiple prices (one API call for your entire catalog)
curl "https://api.getparity.dev/v1/pricing?prices=9,29,49&country=IN" \
     -H "X-API-Key: parity_live_YOUR_KEY"
SINGLE PRICE RESPONSE
{
  "country": { "code": "IN", "name": "India", "incomeLevel": "Lower middle income" },
  "currency": { "code": "INR", "name": "Indian Rupee", "symbol": "₹" },
  "ppp": { "priceLevelRatio": 0.255, "dataYear": 2022, "source": "World Bank ICP" },
  "pricing": {
    "originalPrice": 99,
    "discountPercent": 70,
    "adjustedPrice": 29.70,
    "localPrice": 2468.06,
    "localCurrency": "INR"
  },
  "discount": { "percent": 70, "source": "default" },
  "exchange": { "rate": 83.1, "updatedAt": "2025-01-01T00:00:00.000Z" },
  "confidence": { "vpnDetected": false, "vpnConfidence": "none", "vpnSignals": [], "dataFresh": true }
}
SINGLE PRICE WITH CUSTOM PRESET
// GET /v1/pricing?base_price=99&country=IN&preset=aggressive
{
  ...
  "pricing": {
    "originalPrice": 99,
    "discountPercent": 65,
    "adjustedPrice": 34.65,
    "localPrice": 2879.42,
    "localCurrency": "INR"
  },
  "discount": { "percent": 65, "source": "custom", "preset": "aggressive" },
  ...
}
BULK PRICES RESPONSE
{
  "country": { "code": "IN", "name": "India", "incomeLevel": "Lower middle income" },
  "currency": { "code": "INR", "name": "Indian Rupee", "symbol": "₹" },
  "ppp": { "priceLevelRatio": 0.255, "dataYear": 2022, "source": "World Bank ICP" },
  "pricing": [
    { "originalPrice": 9, "discountPercent": 70, "adjustedPrice": 2.70, "localPrice": 224.42, "localCurrency": "INR" },
    { "originalPrice": 29, "discountPercent": 70, "adjustedPrice": 8.70, "localPrice": 723.14, "localCurrency": "INR" },
    { "originalPrice": 49, "discountPercent": 70, "adjustedPrice": 14.70, "localPrice": 1221.86, "localCurrency": "INR" }
  ],
  "discount": { "percent": 70, "source": "default" },
  "exchange": { "rate": 83.1, "updatedAt": "2025-01-01T00:00:00.000Z" },
  "confidence": { "vpnDetected": false, "vpnConfidence": "none", "vpnSignals": [], "dataFresh": true }
}
GET /v1/detect PUBLIC

Get a signed visitor token. Call this from the visitor's browser, then pass the token to /v1/pricing from your server. This gives you server-side API key security with accurate client-side VPN detection.

// Client-side (visitor's browser)
const res = await fetch("https://api.getparity.dev/v1/detect");
const { token } = await res.json();

// Server-side (your backend, API key stays secret)
const pricing = await fetch(
  `https://api.getparity.dev/v1/pricing?base_price=99&token=${token}`,
  { headers: { "X-API-Key": "parity_live_YOUR_KEY" } }
);
EXAMPLE RESPONSE
{
  "token": "eyJjb3VudHJ5IjoiSU4i...",
  "country": "IN",
  "expires_in": 300
}
GET /v1/countries PUBLIC

List all supported countries with currency metadata.

curl "https://api.getparity.dev/v1/countries"
POST /v1/signup PUBLIC

Create a free account and receive an API key.

BODYTYPEREQDESCRIPTION
emailstringYESYour email address
curl -X POST "https://api.getparity.dev/v1/signup" \
     -H "Content-Type: application/json" \
     -d '{"email": "you@example.com"}'
EXAMPLE RESPONSE
{
  "apiKey": "parity_live_abc123...",
  "plan": "free"
}
GET /v1/usage AUTH

Check your current month's request count and limits.

curl "https://api.getparity.dev/v1/usage" \
     -H "X-API-Key: parity_live_YOUR_KEY"
EXAMPLE RESPONSE
{
  "plan": "free",
  "used": 42,
  "limit": 1000,
  "period": "2025-01"
}
POST /v1/checkout AUTH

Create a Stripe checkout session to upgrade to a paid plan.

BODYTYPEREQDESCRIPTION
planstringYES"starter" or "pro"
curl -X POST "https://api.getparity.dev/v1/checkout" \
     -H "X-API-Key: parity_live_YOUR_KEY" \
     -H "Content-Type: application/json" \
     -d '{"plan": "starter"}'
GET /v1/health PUBLIC

Health check. Returns API status and version.

curl "https://api.getparity.dev/v1/health"
POST /v1/presets AUTH

Create a named discount preset with per-country rules. Starter: 5 presets, Pro: 20 presets. Not available on Free plan.

BODYTYPEREQDESCRIPTION
namestringYESPreset name (max 64 chars, unique per account)
rulesobjectYESCountry code to discount % map. E.g. {"IN": 65, "BR": 45}
curl -X POST "https://api.getparity.dev/v1/presets" \
     -H "X-API-Key: parity_live_YOUR_KEY" \
     -H "Content-Type: application/json" \
     -d '{"name": "aggressive", "rules": {"IN": 65, "BR": 45, "NG": 80}}'
EXAMPLE RESPONSE
{
  "id": "abc123",
  "name": "aggressive",
  "isActive": false,
  "rules": { "IN": 65, "BR": 45, "NG": 80 },
  "createdAt": "2026-03-15T00:00:00.000Z",
  "updatedAt": "2026-03-15T00:00:00.000Z"
}
GET /v1/presets AUTH

List all your discount presets.

curl "https://api.getparity.dev/v1/presets" \
     -H "X-API-Key: parity_live_YOUR_KEY"
GET /v1/presets/:id AUTH

Get a single preset with its rules.

curl "https://api.getparity.dev/v1/presets/abc123" \
     -H "X-API-Key: parity_live_YOUR_KEY"
PUT /v1/presets/:id AUTH

Update a preset. Full replace of name and rules.

BODYTYPEREQDESCRIPTION
namestringYESPreset name (max 64 chars, unique per account)
rulesobjectYESCountry code to discount % map. E.g. {"IN": 65, "BR": 45}
curl -X PUT "https://api.getparity.dev/v1/presets/abc123" \
     -H "X-API-Key: parity_live_YOUR_KEY" \
     -H "Content-Type: application/json" \
     -d '{"name": "conservative", "rules": {"IN": 40, "BR": 30}}'
DELETE /v1/presets/:id AUTH

Delete a preset and its rules. If the preset was active, discounts revert to defaults.

curl -X DELETE "https://api.getparity.dev/v1/presets/abc123" \
     -H "X-API-Key: parity_live_YOUR_KEY"
POST /v1/presets/:id/activate AUTH

Set a preset as active. All future pricing calls will use its discount rules automatically. Countries not in the preset fall back to PPP defaults.

curl -X POST "https://api.getparity.dev/v1/presets/abc123/activate" \
     -H "X-API-Key: parity_live_YOUR_KEY"
POST /v1/presets/deactivate AUTH

Deactivate all presets, reverting to default PPP-based discounts.

curl -X POST "https://api.getparity.dev/v1/presets/deactivate" \
     -H "X-API-Key: parity_live_YOUR_KEY"

ERRORS

All errors return { "error": "message", "code": "ERROR_CODE" }

CODEMEANING
MISSING_PARAMA required parameter is missing
INVALID_PARAMA parameter value is invalid
MISSING_API_KEYX-API-Key header not provided
INVALID_API_KEYAPI key is not valid
RATE_LIMIT_EXCEEDEDMonthly request limit reached
IP_LIMIT_EXCEEDEDToo many distinct IPs for this API key
INVALID_TOKENVisitor token is invalid or expired
COUNTRY_NOT_FOUNDNo PPP data for the requested country
PRESET_NOT_FOUNDPreset ID or name not found
PLAN_LIMITFeature not available on current plan
PRESET_LIMIT_EXCEEDEDMaximum presets reached for plan

VPN DETECTION

Every pricing response includes a confidence object with VPN detection signals:

FIELDTYPEDESCRIPTION
vpnDetectedbooleanWhether any VPN signal was detected
vpnConfidencestring"high", "medium", "low", "none", or "external"
vpnSignalsarraySignals triggered: "asn_match", "timezone_mismatch", "external_override"
dataFreshbooleanWhether exchange rate data is current

BRING YOUR OWN VPN DETECTION

Need more accurate VPN detection? Use your own provider (e.g. IPinfo, ipgeolocation.io) and pass the result to ParityAPI via the vpn_override parameter.

// Your server — check VPN with your preferred provider
const ipinfo = await fetch(`https://ipinfo.io/${visitorIp}?token=YOUR_IPINFO_TOKEN`);
const { privacy } = await ipinfo.json();

// Pass the result to ParityAPI
const parity = await fetch(
  `https://api.getparity.dev/v1/pricing?base_price=99&token=${token}&vpn_override=${privacy.vpn}`,
  { headers: { "X-API-Key": process.env.PARITY_KEY } }
);

// Response will have vpnConfidence: "external" and vpnSignals: ["external_override"]

PICK A PLAN.

ALL CORE FEATURES INCLUDED ON EVERY PLAN. CUSTOM PRESETS ON STARTER+. NO CREDIT CARD FOR FREE TIER.

GET YOUR KEY.