# Sample Apps and End-to-End Patterns

> Five small, runnable patterns: checkout quoting, PPP pricing, a dashboard proxy, a backtest, and an MCP agent setup.

Canonical: https://currency-core.com/docs/guides/sample-apps/
Updated: 2026-11-12
Published: 2026-11-11

---
These are deliberately small. Each one is a complete path from a request to a decision, not a framework scaffold. Copy the part that matches your product, then add the validation, storage, and tests your environment requires.

Official SDKs exist for TypeScript, Python, Dart, Kotlin/JVM and Swift. The TypeScript examples below use `@currencycore/sdk`; the raw HTTP pages exist for the frameworks without an official client and for cases where a framework needs its own fetch or async options.

Install the TypeScript SDK once for the JavaScript examples:

```bash
npm install @currencycore/sdk
```

All examples use `CURRENCYCORE_API_KEY` and the shared error envelope. Free includes 1,000 requests per month at 60 per minute. Live keys require a paid plan; test keys use the same reference data and quota, capped at 60 per minute.

## 1. Checkout quote

Convert the cart once, store the rate date with the order, and round with a documented policy. Do not refetch at capture time.

```js

const api = createClient(); // reads CURRENCYCORE_API_KEY

async function quoteCart(cartTotal, from, to) {
  const body = await api.convert({ from, to, amount: cartTotal });
  const row = body.results[0];
  return {
    chargeAmount: Math.round(row.result * 100) / 100,
    rate: row.rate,
    rateDate: body.date,
    requestedDate: body.requestedDate ?? body.date,
  };
}
```

Persist `rateDate` and `rate`. On refund, re-run the same dated query instead of using today's rate.

The function returns:

```json
{
  "chargeAmount": 45.15,
  "rate": 0.9214,
  "rateDate": "2026-11-10",
  "requestedDate": "2026-11-10"
}
```

## 2. PPP local price

PPP is a price-level comparison, not a market conversion. Read `ppp.result`, then apply your own floor and ceiling.

```js

const api = createClient();

async function localPrice(baseUsd, to, country) {
  const body = await api.convert({
    from: "USD:USA",
    to: `${to}:${country}`,
    amount: baseUsd,
    ppp: true,
  });

  const ppp = body.results[0].ppp;
  if (!ppp || !("result" in ppp)) throw new Error("PPP unavailable for that pair");

  return Math.max(baseUsd * 0.4, Math.min(ppp.result, baseUsd * 1.2));
}
```

Record the country, factor year, and resulting price. Charge the local price you set, not a second market conversion of it.

## 3. Dashboard proxy

The browser cannot call the API directly from your origin, and it must not hold the key. A tiny Node server can serve the page and proxy one route.

```js

const api = createClient(); // reads CURRENCYCORE_API_KEY

http.createServer(async (req, res) => {
  const url = new URL(req.url, "http://localhost");
  if (url.pathname !== "/api/rates") {
    res.writeHead(404).end();
    return;
  }

  const base = (url.searchParams.get("base") ?? "USD").toUpperCase();
  if (!/^[A-Z]{3}$/.test(base)) {
    res.writeHead(400, { "content-type": "application/json" });
    res.end(JSON.stringify({ error: { code: "invalid_input" } }));
    return;
  }

  try {
    const body = await api.ratesByBase({ base });
    res.writeHead(200, {
      "content-type": "application/json",
      "cache-control": "public, max-age=300",
    });
    res.end(JSON.stringify(body));
  } catch (error) {
    const status = error instanceof ResponseError ? error.response.status : 502;
    res.writeHead(status, { "content-type": "application/json" });
    res.end(JSON.stringify({ error: { code: "internal_error" } }));
  }
}).listen(8787);
```

The page calls `/api/rates?base=EUR` on its own origin. See [React with a backend proxy](/docs/guides/react/) for the client side.

## 4. Backtest a signal

History is dense, so carry-forward rows are not new observations. This example fetches one pair and reports a simple moving-average crossover. It is a starting point, not investment advice.

```js

const api = createClient();

async function backtest(currency, base) {
  const body = await api.history({
    currency,
    base,
    from: "2015-01-01",
  });

  const rows = Object.entries(body.rates).sort(([a], [b]) => a.localeCompare(b));
  const closes = rows.map(([, rate]) => rate);
  const sma = (end, n) => closes.slice(end - n, end).reduce((a, b) => a + b, 0) / n;

  let position = 0;
  let trades = 0;
  for (let i = 200; i < closes.length; i++) {
    const fast = sma(i, 50);
    const slow = sma(i, 200);
    const next = fast > slow ? 1 : 0;
    if (next !== position) trades++;
    position = next;
  }
  return { observations: closes.length, trades, finalPosition: position };
}
```

Store the observation date with each value, and check the currency's first quote before assuming the window is covered. A 2015 start needs Starter or above; Free history is limited to the last 30 days.

## 5. MCP agent setup

For an interactive agent, add the remote server instead of writing a client. The current Claude path is **Settings > Connectors > Add custom connector** with `https://mcp.currency-core.com/mcp`. Cursor uses **Customize > MCP**; VS Code uses `.mcp.json` with `type: "http"`.

A prompt that names the tool is more reliable than a vague question:

> Use the CurrencyCore convert tool to convert 500 USD to INR. Include the rate date and the rate.

MCP uses OAuth and an organization selection. One successful keyed tool call counts as one API request, and MCP uses no AI credits. See [MCP tools](/docs/mcp-tools/) and [MCP OAuth](/docs/mcp-oauth/).

## Related

- [API reference](/docs/api/) and [OpenAPI](/docs/openapi/)
- [E-commerce guide](/docs/guides/ecommerce/), [SaaS pricing](/docs/guides/saas-pricing/), [dashboards](/docs/guides/dashboards/), [backtesting](/docs/guides/backtesting/)
- [All developer guides](/docs/guides/)
