Skip to main content

FX API - Foreign Exchange

Foreign exchange and currency conversion services powered by USDC routing. Supports fiat-to-fiat conversions via USDC bridge, direct USDC conversions, and real-time ticker data from Coinbase.

Key Features:

  • FIAT ↔ FIAT: Currency conversion via USDC routing (e.g., IDR → USDC → USD)
  • USDC ↔ FIAT: Direct conversions without routing
  • Real-time Rates: Live ticker data with price changes
  • Manual Updates: Trigger rate updates from Coinbase

FIAT Routes Conversion

GET/api/fx/convert

FIAT to FIAT Conversion via USDC

Convert between fiat currencies using USDC as an intermediate bridge. Supports multi-step routing for currency pairs that don't have direct conversion rates.

Parameters

fromstringrequired

Source currency code (e.g., IDR, USD, SGD)

tostringrequired

Target currency code (e.g., USD, IDR, SGD)

amountnumberrequired

Amount to convert

Response

200Conversion completed successfully
{
  "route": "IDR → USDC → USD",
  "result": 67.45,
  "usdcIntermediate": 0.000064
}
400Missing required parameters
{
  "error": "from, to, and amount are required"
}
400_conversionConversion error
{
  "error": "Unsupported currency pair: XYZ to ABC"
}
curl -X GET "https://api.brdz.link/api/fx/convert?from=IDR&to=USD&amount=1000000" \
-H "x-api-key: YOUR_API_KEY"

USDC Direct Conversion

GET/api/fx/usdc

USDC to FIAT Direct Conversion

Direct conversion between USDC and fiat currencies without routing through other currencies. Supports bidirectional conversion with specific rates for each direction.

Parameters

fiatstringrequired

Fiat currency code (e.g., IDR, USD, SGD)

directionstringrequired

Conversion direction: 'toFiat' (USDC → Fiat) or 'fromFiat' (Fiat → USDC)

amountnumberrequired

Amount to convert

Response

200USDC conversion completed
{
  "route": "USDC → IDR",
  "rate": 15750.5,
  "result": 157505
}
400Missing required parameters
{
  "error": "fiat, direction, and amount are required"
}
500Internal error
{
  "error": "Internal error"
}
400_currencyUnsupported currency
{
  "error": "Unsupported fiat currency: XYZ"
}
400_directionInvalid direction
{
  "error": "Invalid direction: must be \"toFiat\" or \"fromFiat\""
}
# Convert USDC to IDR
curl -X GET "https://api.brdz.link/api/fx/usdc?fiat=IDR&direction=toFiat&amount=10" \
-H "x-api-key: YOUR_API_KEY"

# Convert IDR to USDC  
curl -X GET "https://api.brdz.link/api/fx/usdc?fiat=IDR&direction=fromFiat&amount=157500" \
-H "x-api-key: YOUR_API_KEY"

Get USDC Ticker

GET/api/fx/usdc-ticker

Get USDC Ticker Data

Retrieve real-time USDC ticker data including current rates, price changes, and percentage movements. Data is sourced from Coinbase and updated periodically.

Response

200Ticker data retrieved successfully
{
  "success": true,
  "data": {
    "USD": {
      "rate": 1,
      "change": 0,
      "percent": 0,
      "isUp": true
    },
    "IDR": {
      "rate": 15750.5,
      "change": -125.25,
      "percent": -0.79,
      "isUp": false
    },
    "SGD": {
      "rate": 1.3456,
      "change": 0.0012,
      "percent": 0.09,
      "isUp": true
    }
  }
}
500Failed to load ticker data
{
  "success": false,
  "error": "Failed to load ticker data"
}
curl -X GET https://api.brdz.link/api/fx/usdc-ticker \
-H "x-api-key: YOUR_API_KEY"

Update USDC Ticker

POST/api/fx/usdc-ticker/update

Update USDC Ticker Manually

Trigger manual update of USDC ticker data from Coinbase. Useful for getting the latest rates on-demand or for testing purposes.

Request Body

{}

Response

200Ticker updated successfully
{
  "success": true,
  "message": "Rates updated successfully"
}
500Update failed
{
  "success": false,
  "error": "Failed to update ticker data"
}
curl -X POST https://api.brdz.link/api/fx/usdc-ticker/update \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{}'

Convert All with Details

GET/api/fx/convertall

Convert Currency with Detailed Route

Convert between currencies with detailed routing information, intermediate USDC amounts, and exchange rates. Provides comprehensive conversion data for tracking and auditing.

Parameters

fromstringrequired

Source currency code

tostringrequired

Target currency code

amountnumberrequired

Amount to convert

Response

200Detailed conversion completed
{
  "from": "IDR",
  "to": "USD",
  "original_amount": 1000000,
  "route": "IDR → USDC → USD",
  "usdc_intermediate": 63.456,
  "converted_amount": 63.45,
  "exchange_rate": 0.00006345
}
400Missing parameters
{
  "error": "Missing required parameters: from, to, amount"
}
500Conversion failed
{
  "error": "Conversion failed",
  "detail": "Rate source unavailable"
}
400_amountInvalid amount
{
  "error": "Invalid amount"
}
curl -X GET "https://api.brdz.link/api/fx/convertall?from=IDR&to=USD&amount=1000000" \
-H "x-api-key: YOUR_API_KEY"

Currency Conversion Flow

USDC Bridge Architecture

The FX API uses USDC as a bridge currency for all conversions:

graph LR
A[IDR] --> B[USDC]
B --> C[USD]
B --> D[SGD]
B --> E[EUR]
F[Any Fiat] --> B
B --> G[Any Fiat]

Conversion Types

  1. Direct USDC ↔ Fiat: Single-step conversion with dedicated rates
  2. Fiat ↔ Fiat via USDC: Two-step conversion using USDC as intermediate
  3. Route Optimization: Automatic selection of most efficient conversion path

Rate Sources

  • Primary: Coinbase Pro API for real-time rates
  • Fallback: Cached rates for service continuity
  • Update Frequency: Configurable (default: every 15 minutes)
  • Manual Updates: Available via API for immediate rate refresh

Integration Examples

React FX Component

import React, { useState, useEffect } from 'react';

const FXConverter = () => {
const [rates, setRates] = useState({});
const [conversion, setConversion] = useState(null);
const [amount, setAmount] = useState(100);
const [fromCurrency, setFromCurrency] = useState('IDR');
const [toCurrency, setToCurrency] = useState('USD');

useEffect(() => {
// Load ticker data
fetch('https://api.brdz.link/api/fx/usdc-ticker', {
headers: { 'x-api-key': 'YOUR_API_KEY' }
})
.then(res => res.json())
.then(data => {
if (data.success) {
setRates(data.data);
}
});
}, []);

const handleConvert = async () => {
const response = await fetch(
`https://api.brdz.link/api/fx/convertall?from=${fromCurrency}&to=${toCurrency}&amount=${amount}`,
{ headers: { 'x-api-key': 'YOUR_API_KEY' } }
);
const result = await response.json();
setConversion(result);
};

return (
<div className="fx-converter">
<h2>Currency Converter</h2>

{/* Ticker Display */}
<div className="ticker-strip">
{Object.entries(rates).map(([currency, data]) => (
<div key={currency} className={`ticker-item ${data.isUp ? 'up' : 'down'}`}>
<span>{currency}/USDC</span>
<span>{data.rate}</span>
<span>{data.change >= 0 ? '+' : ''}{data.percent}%</span>
</div>
))}
</div>

{/* Conversion Form */}
<div className="converter-form">
<input
type="number"
value={amount}
onChange={(e) => setAmount(e.target.value)}
placeholder="Amount"
/>

<select value={fromCurrency} onChange={(e) => setFromCurrency(e.target.value)}>
<option value="IDR">IDR</option>
<option value="USD">USD</option>
<option value="SGD">SGD</option>
<option value="USDC">USDC</option>
</select>

<span>to</span>

<select value={toCurrency} onChange={(e) => setToCurrency(e.target.value)}>
<option value="USD">USD</option>
<option value="IDR">IDR</option>
<option value="SGD">SGD</option>
<option value="USDC">USDC</option>
</select>

<button onClick={handleConvert}>Convert</button>
</div>

{/* Results */}
{conversion && (
<div className="conversion-result">
<h3>Conversion Result</h3>
<p>{conversion.from} {conversion.original_amount} = {conversion.to} {conversion.converted_amount}</p>
<p>Route: {conversion.route}</p>
<p>Exchange Rate: {conversion.exchange_rate}</p>
</div>
)}
</div>
);
};

export default FXConverter;

Portfolio Value Calculator

class PortfolioCalculator {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://api.brdz.link/api/fx';
}

async calculatePortfolioValue(holdings, targetCurrency = 'USD') {
const conversions = [];
let totalValue = 0;

for (const holding of holdings) {
if (holding.currency === targetCurrency) {
totalValue += holding.amount;
conversions.push({
...holding,
convertedAmount: holding.amount,
rate: 1,
route: 'Direct'
});
} else {
const response = await fetch(
`${this.baseUrl}/convertall?from=${holding.currency}&to=${targetCurrency}&amount=${holding.amount}`,
{ headers: { 'x-api-key': this.apiKey } }
);

const conversion = await response.json();
totalValue += conversion.converted_amount;

conversions.push({
...holding,
convertedAmount: conversion.converted_amount,
rate: conversion.exchange_rate,
route: conversion.route
});
}
}

return {
totalValue,
targetCurrency,
conversions,
timestamp: new Date().toISOString()
};
}

async getHistoricalValue(holdings, targetCurrency, days = 30) {
// Implementation would require historical rate endpoints
// This is a placeholder for the concept
const historicalData = [];

for (let i = 0; i < days; i++) {
const date = new Date();
date.setDate(date.getDate() - i);

// In real implementation, use historical rates
const value = await this.calculatePortfolioValue(holdings, targetCurrency);
historicalData.push({
date: date.toISOString().split('T')[0],
value: value.totalValue
});
}

return historicalData.reverse();
}
}

// Usage
const calculator = new PortfolioCalculator('YOUR_API_KEY');

const portfolio = [
{ currency: 'IDR', amount: 10000000, asset: 'Cash' },
{ currency: 'USD', amount: 500, asset: 'Savings' },
{ currency: 'USDC', amount: 1000, asset: 'Crypto' },
{ currency: 'SGD', amount: 200, asset: 'Investment' }
];

const valuation = await calculator.calculatePortfolioValue(portfolio, 'USD');
console.log(`Total Portfolio Value: $${valuation.totalValue.toFixed(2)} USD`);

valuation.conversions.forEach(conv => {
console.log(`${conv.asset}: ${conv.currency} ${conv.amount} → $${conv.convertedAmount.toFixed(2)} (${conv.route})`);
});

Error Handling

Common Errors

// Comprehensive error handling
async function safeConversion(from, to, amount) {
try {
const response = await fetch(
`https://api.brdz.link/api/fx/convertall?from=${from}&to=${to}&amount=${amount}`,
{ headers: { 'x-api-key': 'YOUR_API_KEY' } }
);

if (!response.ok) {
throw new Error(`HTTP ${response.status}: ${response.statusText}`);
}

const data = await response.json();

if (data.error) {
throw new Error(data.error);
}

return data;
} catch (error) {
if (error.message.includes('Missing required parameters')) {
console.error('Invalid parameters provided');
return null;
} else if (error.message.includes('Invalid amount')) {
console.error('Amount must be a positive number');
return null;
} else if (error.message.includes('Conversion failed')) {
console.error('Rate source unavailable, try again later');
return null;
} else {
console.error('Unexpected error:', error.message);
return null;
}
}
}

Rate Availability

// Check rate availability before conversion
async function checkRateAvailability(currencies) {
const ticker = await fetch('https://api.brdz.link/api/fx/usdc-ticker', {
headers: { 'x-api-key': 'YOUR_API_KEY' }
});

const tickerData = await ticker.json();

if (!tickerData.success) {
return { available: false, reason: 'Ticker service unavailable' };
}

const unavailable = currencies.filter(curr =>
curr !== 'USDC' && !tickerData.data[curr]
);

if (unavailable.length > 0) {
return {
available: false,
reason: `Unsupported currencies: ${unavailable.join(', ')}`
};
}

return { available: true };
}

// Usage
const availability = await checkRateAvailability(['IDR', 'USD', 'SGD']);
if (availability.available) {
// Proceed with conversion
} else {
console.error('Cannot convert:', availability.reason);
}

Supported Currencies

Primary Fiat Currencies

  • IDR: Indonesian Rupiah
  • USD: US Dollar
  • SGD: Singapore Dollar
  • EUR: Euro (if configured)

Digital Assets

  • USDC: USD Coin (bridge currency)

Rate Characteristics

  • USDC/USD: ~1.0000 (stable)
  • USDC/IDR: ~15,000-16,000 (volatile)
  • USDC/SGD: ~1.30-1.40 (moderate)
  • Update Frequency: Every 15 minutes
  • Precision: 6 decimal places

USDC Bridge

All conversions use USDC as an intermediate currency, ensuring consistent pricing and reducing rate complexity.

Rate Volatility

Cryptocurrency and fiat exchange rates can be volatile. Use ticker data to monitor current rates and changes.

Manual Updates

Use the update ticker endpoint to get the latest rates immediately, especially during high volatility periods.