Rate validation reduces conversion costs by 35%

Master Currency Rate Validation

Catch bad rates before they reach checkout. This guide covers the four validation layers that protect margin across 150+ currencies — sanity bounds, freshness checks, cross-source comparison, and anomaly detection.

35%
Conversion-cost reduction
99.9%
Validated accuracy
150+
Currencies covered
<50ms
Validation response

The four layers of rate validation

Sanity bounds

Reject rates that fall outside reasonable historical ranges for the pair. Catches feed errors, decimal-shift bugs, and accidental inverse rates before they hit your storefront or invoice.

Freshness checks

Validate the rate timestamp on every read. Stale rates from a cache miss or a paused upstream feed cause more disputes than wrong rates.

Cross-source comparison

Compare your primary feed against an independent reference. Flag when the spread between sources exceeds your tolerance — typically 0.25% for majors, 1% for exotics.

Anomaly detection

Track rolling volatility per pair and alert on outlier ticks. Especially important during market open / close and around macro events.

Common error signals to watch

Decimal-shift errors

A rate suddenly off by 10× or 0.1× — almost always a parsing or formatting bug, never a real market move.

Inverse-pair confusion

Code expects USD/EUR but receives EUR/USD. Easy to spot with sanity bounds; expensive when it ships to checkout unchecked.

Stale rate served

A cached rate older than your TTL still gets returned because invalidation failed. Always check `asOf` against current time, not just trust the cache.

Source divergence

Two reputable feeds disagree by more than spread tolerance. Either one source is degraded, or genuine market dislocation — your monitoring should distinguish.

A four-step validation strategy

1

Define tolerance per pair

Majors (USD/EUR, USD/JPY, GBP/USD) tolerate ~0.25% cross-source spread. Minors / exotics need wider bounds (0.75–2%) because feed coverage thins out. Codify these in your validation layer.

2

Validate at every boundary

Storefront price calc, checkout rate lock, refund recalculation, ERP rate sync, month-end reporting — each is an independent boundary that should re-run validation, not assume the feed was clean.

3

Lock + log the rate that priced the order

Store the exact rate and `asOf` timestamp on the order itself. Refunds and disputes can be answered without rebuilding the trail from feed history.

4

Alert, don’t just log

A failed validation that only writes to a log gets ignored until the dispute lands in support. Route validation failures to the same channel as your payment failures.

Reference implementation

A minimal validation wrapper around the convert endpoint. Fails fast on stale or out-of-band rates so callers can fall back to a cached value or surface a clear error to the user.

TypeScript validate-rate.ts
type RateBound = { min: number; max: number };

const bounds: Record<string, RateBound> = {
  'USD/EUR': { min: 0.7, max: 1.3 },
  'USD/JPY': { min: 80, max: 200 },
  'USD/GBP': { min: 0.5, max: 1.0 },
};

const MAX_AGE_MS = 60_000;
const MAX_CROSS_SOURCE_SPREAD = 0.0025; // 0.25%

export function validateRate(
  pair: string,
  rate: number,
  asOf: Date,
  reference?: number,
): { ok: true } | { ok: false; reason: string } {
  const bound = bounds[pair];
  if (bound && (rate < bound.min || rate > bound.max)) {
    return { ok: false, reason: 'rate outside sanity bounds' };
  }

  if (Date.now() - asOf.getTime() > MAX_AGE_MS) {
    return { ok: false, reason: 'rate is stale' };
  }

  if (reference !== undefined) {
    const spread = Math.abs(rate - reference) / reference;
    if (spread > MAX_CROSS_SOURCE_SPREAD) {
      return { ok: false, reason: 'cross-source spread exceeded' };
    }
  }

  return { ok: true };
}

Where teams underinvest

Most teams build the convert call and stop. Validation, alerting, and locked-rate reconciliation are the difference between an FX bug surfacing as a refund-month-later mystery and one that pages an engineer in 60 seconds. Wire these in on day one — they are far cheaper to add now than to retrofit during an incident.

Validate every rate before it costs you

Use the API to fetch live rates, lock at checkout, and reconcile refunds with the same source of truth.

Instant setup • 99.9% uptime SLA • <50ms response time