Integrations

Purchasing Power Parity

Read IMF PPP factors correctly, convert an amount at price levels, and keep the result separate from a market exchange rate.


The job

Compare what money buys in different countries, or adjust an amount for local price levels. Use /v1/ppp for one factor, /v1/ppp/analysis for trends and country comparisons, and /v1/convert?ppp=true for a PPP-adjusted amount.

The result is a price-level comparison. It is not a currency quote, and it is not a substitute for the market rate.

What the factor means

A PPP factor is local currency units per international dollar. The data comes from the IMF World Economic Outlook PPPEX series, which covers 197 countries from 1980 to 2031. The configured factor year is 2024, and projected years are flagged.

{
  "year": 2024,
  "countryCode": "IND",
  "pppFactor": 20.397,
  "projected": false
}

A factor of 20.397 for India means goods costing one international dollar in the United States would cost about 20.4 units of Indian currency in India at PPP. The market FX rate can be very different. Do not use this number as a currency quote.

Three ways to use it

QuestionEndpointWhat you get
Price level for one country/v1/pppA single pppFactor
Compare countries or years/v1/ppp/analysisFactors over time, changes, rankings
PPP-adjusted amount/v1/convert?ppp=trueA converted amount in ppp.result
Nominal market conversion/v1/convertThe FX amount in result

/v1/ppp takes one country and one year. Use /v1/ppp/analysis when you need a range, a comparison, or a ranking.

The country and currency gap

The country reference has 236 entries. PPP factors cover 197 countries, so not every country in /v1/countries has a factor. Check the country’s currencies array before you build a currency:country pair.

/v1/ppp has no currency parameter. The response identifies the country, and the factor is denominated in that country’s local currency. For a converted amount, use /v1/convert?ppp=true with an explicit INR:IND style pair when the currency is used in more than one country.

A complete example

This example fetches one factor and one PPP-adjusted amount, then returns both numbers together. Run it server-side with a secret key.

type PppFactor = {
  year: number;
  countryCode: string;
  pppFactor: number;
  projected: boolean;
};

type PppConvert = {
  from: string;
  fromCountry: string;
  amount: number;
  date: string;
  results: {
    to: string;
    toCountry: string;
    result: number;
    rate: number;
    ppp: {
      fromFactor: number;
      toFactor: number;
      result: number;
      year: number;
      source: string;
    };
  }[];
};

async function fetchPpp(country: string, year = 2024): Promise<PppFactor> {
  const url = new URL("https://api.currency-core.com/v1/ppp");
  url.searchParams.set("country", country);
  url.searchParams.set("year", String(year));

  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.CURRENCECORE_API_KEY}` },
    signal: AbortSignal.timeout(8000),
  });
  const body = await res.json();

  if (!res.ok) {
    throw Object.assign(new Error(body.error?.message ?? `HTTP ${res.status}`), {
      status: res.status,
      code: body.error?.code,
    });
  }
  return body as PppFactor;
}

async function pppConvert(
  from: string,
  fromCountry: string,
  to: string,
  toCountry: string,
  amount: number,
): Promise<PppConvert> {
  const url = new URL("https://api.currency-core.com/v1/convert");
  url.searchParams.set("from", `${from}:${fromCountry}`);
  url.searchParams.set("to", `${to}:${toCountry}`);
  url.searchParams.set("amount", String(amount));
  url.searchParams.set("ppp", "true");

  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.CURRENCECORE_API_KEY}` },
    signal: AbortSignal.timeout(8000),
  });
  const body = await res.json();

  if (!res.ok) {
    throw Object.assign(new Error(body.error?.message ?? `HTTP ${res.status}`), {
      status: res.status,
      code: body.error?.code,
    });
  }
  return body as PppConvert;
}

export async function comparePriceLevels(amount = 100) {
  const india = await fetchPpp("IND", 2024);
  const converted = await pppConvert("USD", "USA", "INR", "IND", amount);
  const result = converted.results[0];

  return {
    country: india.countryCode,
    factorYear: india.year,
    factor: india.pppFactor,
    projected: india.projected,
    nominal: result.result,
    pppAdjusted: result.ppp.result,
    source: result.ppp.source,
  };
}

What the response means

For $100 from the United States to India with ppp=true:

{
  "from": "USD",
  "fromCountry": "USA",
  "amount": 100,
  "date": "2026-11-10",
  "results": [
    {
      "to": "INR",
      "toCountry": "IND",
      "result": 8345.0,
      "rate": 83.45,
      "ppp": {
        "fromFactor": 1.0,
        "toFactor": 20.4,
        "result": 2040.0,
        "year": 2024,
        "source": "IMF World Economic Outlook"
      }
    }
  ]
}

There are two different answers in one response:

FieldMeaningValue
resultMarket conversion at the FX rate₹8,345
ppp.resultPrice-level conversion through the international dollar₹2,040

The PPP amount is amount * (toFactor / fromFactor). It deliberately does not use the FX rate. ppp.result is a price-level conversion of your amount, not a market quote.

Actual years versus projections

/v1/ppp and /v1/ppp/analysis can return projected years. Read the projected flag before treating a value as observed history.

/v1/convert?ppp=true uses actual years only, not projections. When date is omitted, it uses the latest actual year. When date is supplied, it follows that date’s year and still uses only actual data.

For historical analysis, prefer actual values. If you use a projection, label it as a scenario.

Worked example

Compare what $100 buys in India against the market rate:

  1. Fetch /v1/ppp?country=IND&year=2024 and read pppFactor = 20.397.
  2. Convert 100 USD:USA to INR:IND with ppp=true.
  3. Read result = 8345.0 for the market amount.
  4. Read ppp.result = 2040.0 for the price-level amount.
  5. Keep both numbers. Do not replace the market amount with the PPP amount, and do not multiply the two.
  6. Store the factor year and the source with the result.

Failure handling

StatusWhat to do
400 invalid_inputCheck the alpha-3 country code and the four-digit year
400 unknown_pppThe country or year has no PPP factor
401 unauthorizedCheck the server-side key
429 rate_limitedHonor Retry-After; PPP factors change annually, so cache them
5xxRetry with backoff, or use the last known factor with a visible date

/v1/ppp requires a key but has no Growth gate. /v1/ppp/analysis requires Growth or higher. See rate limits.

Next steps