# FX Cross-Rate & Triangular Arbitrage API
> Live cross-rate, triangular-arbitrage and conversion-path maths that FX desks and trading bots run on a set of quoted rates, computed on demand from the legs you pass in — no key, no cache, nothing stored. The cross endpoint chains two pairs that share a currency into the implied third rate (EUR/USD x USD/JPY gives EUR/JPY) and, if you supply the quoted cross, returns the discrepancy in basis points and whether it is arbitrageable. The triangular endpoint takes a closed loop of three rates and detects a triangular-arbitrage opportunity — the cycle product, the profit in percent, the winning direction (forward or reverse) and the payout on a notional. The chain endpoint converts an amount along a path of pairs and returns the amount at every hop with the effective rate. Each leg is written FROMTO:rate, meaning one unit of FROM buys that many of TO (e.g. EURUSD:1.08). This is an FX cross-rate and arbitrage engine that reasons across several pairs at once, distinct from pip/lot calculators and single-pair converters. Computed locally and deterministically, so it is instant and private. Ideal for FX arbitrage scanners, multi-currency pricing, treasury routing and trading dashboards. Live, nothing stored. 3 compute endpoints. For live quotes feed in rates from an FX or exchange API.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/fxcross-api/..."
```

## Pricing
- **Free** (Free) — 4,500 calls/Mo, 2 req/s
- **Starter** ($8/Mo) — 88,000 calls/Mo, 6 req/s
- **Pro** ($23/Mo) — 465,000 calls/Mo, 18 req/s
- **Business** ($53/Mo) — 2,850,000 calls/Mo, 45 req/s

## Endpoints

### FX

#### `GET /v1/chain` — Convert an amount along a path of pairs

**Parameters:**
- `legs` (query, required, string) — Chained pairs FROMTO:rate Example: `EURUSD:1.08,USDJPY:150`
- `amount` (query, required, string) — Amount in the first currency Example: `1000`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/fxcross-api/v1/chain?legs=EURUSD%3A1.08%2CUSDJPY%3A150&amount=1000"
```

**Response:**
```json
{
    "data": {
        "hops": [
            {
                "pair": "EUR/USD",
                "rate": 1.08,
                "to_amount": 1080,
                "from_amount": 1000,
                "to_currency": "USD",
                "from_currency": "EUR"
            },
            {
                "pair": "USD/JPY",
                "rate": 150,
                "to_amount": 162000,
                "from_amount": 1080,
                "to_currency": "JPY",
                "from_currency": "USD"
            }
        ],
        "path": "EUR -> USD -> JPY",
        "source": "FX-CROSS",
        "final_amount": 162000,
        "start_amount": 1000,
        "effective_rate": 162,
        "final_currency": "JPY",
        "start_currency": "EUR"
    },
    "meta": {
        "timestamp": "2026-06-11T07:49:27.931Z",
        "request_id": "f38d62ed-930e-4e91-b297-d5a2ef15c5be"
    },
    "status": "ok",
    "message": "Conversion chain computed",
    "success": true
}
```

#### `GET /v1/cross` — Implied cross rate from chained pairs

**Parameters:**
- `legs` (query, required, string) — Chained pairs FROMTO:rate, comma-separated Example: `EURUSD:1.08,USDJPY:150`
- `quoted` (query, optional, string) — Quoted cross to compare against Example: `163`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/fxcross-api/v1/cross?legs=EURUSD%3A1.08%2CUSDJPY%3A150&quoted=163"
```

**Response:**
```json
{
    "data": {
        "base": "EUR",
        "legs": [
            {
                "pair": "EUR/USD",
                "rate": 1.08
            },
            {
                "pair": "USD/JPY",
                "rate": 150
            }
        ],
        "pair": "EUR/JPY",
        "path": "EUR -> USD -> JPY",
        "quote": "JPY",
        "source": "FX-CROSS",
        "arbitrage": true,
        "discrepancy": 1,
        "quoted_rate": 163,
        "implied_rate": 162,
        "inverse_rate": 0.0061728395,
        "discrepancy_bps": 61.73
    },
    "meta": {
        "timestamp": "2026-06-11T07:49:28.023Z",
        "request_id": "51be726c-6bda-439a-bb9b-556acd55f42e"
    },
    "status": "ok",
    "message": "Cross rate computed",
    "success": true
}
```

#### `GET /v1/triangular` — Triangular-arbitrage detection

**Parameters:**
- `legs` (query, required, string) — Closed 3-rate loop FROMTO:rate Example: `EURUSD:1.08,USDJPY:150,JPYEUR:0.00617`
- `notional` (query, optional, string) — Notional to compute payout on (default 1) Example: `10000`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/fxcross-api/v1/triangular?legs=EURUSD%3A1.08%2CUSDJPY%3A150%2CJPYEUR%3A0.00617&notional=10000"
```

**Response:**
```json
{
    "data": {
        "legs": [
            {
                "pair": "EUR/USD",
                "rate": 1.08
            },
            {
                "pair": "USD/JPY",
                "rate": 150
            },
            {
                "pair": "JPY/EUR",
                "rate": 0.00617
            }
        ],
        "note": "product>1 means cycling in the given (forward) direction profits; otherwise the reverse cycle does. Edge below 1 bp is treated as no arbitrage.",
        "source": "FX-CROSS",
        "notional": 10000,
        "arbitrage": true,
        "direction": "reverse",
        "currencies": [
            "EUR",
            "USD",
            "JPY"
        ],
        "profit_pct": 0.046021,
        "cycle_product": 0.99954,
        "forward_cycle": "EUR -> USD -> JPY -> EUR",
        "start_currency": "EUR",
        "profit_on_notional": 4.60211697
    },
    "meta": {
        "timestamp": "2026-06-11T07:49:28.122Z",
        "request_id": "0c4b6c24-4e99-4036-a3dc-178f7567005a"
    },
    "status": "ok",
    "message": "Triangular arbitrage computed",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/fxcross-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "note": "Each leg is FROMTO:rate, where 1 FROM = rate TO (e.g. EURUSD:1.08). Legs must chain (each TO matches the next FROM).",
        "source": "Computed in-process from caller-supplied quoted rates (no upstream)",
        "service": "fxcross-api",
        "endpoints": {
            "GET /v1/meta": "This document.",
            "GET /v1/chain": "Convert an amount along a path of pairs, per hop (legs=EURUSD:1.08,USDJPY:150&amount=1000).",
            "GET /v1/cross": "Implied cross from chained pairs + discrepancy vs a quoted cross (legs=EURUSD:1.08,USDJPY:150&quoted=163).",
            "GET /v1/triangular": "Triangular-arbitrage detection on a closed 3-rate loop (legs=EURUSD:1.08,USDJPY:150,JPYEUR:0.00617)."
        },
        "description": "Live cross-rate, triangular-arbitrage and conversion-path maths computed on demand from the quoted rates you pass in. The cross endpoint chains two pairs sharing a currency into the implied third rate plus the discrepancy vs a quoted cross; the triangular endpoint detects a triangular-arbitrage opportunity in a closed loop of three rates (cycle product, profit %, winning direction, payout on a notional); the chain endpoint converts an amount along a path of pairs with a per-hop breakdown. An FX cross-rate and arbitrage engine that reasons across several pairs at once, distinct from pip/lot calculators and single-pair converters. Computed locally, nothing stored.",
        "upstream_status": "ok"
    },
    "meta
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/fxcross-api
OpenAPI spec: https://www.oanor.com/api/fxcross-api/openapi.json
