# JavaScript and the CurrencyCore API

> Call the API from a Node.js script or serverless function with fetch, a timeout, a small error class, and no build step.

Canonical: https://currency-core.com/docs/guides/javascript/
Updated: 2026-11-11
Published: 2026-11-11

---
Plain JavaScript is enough for a script, a scheduled job, or a serverless function. Node.js 18 and later provide global `fetch`, `AbortSignal.timeout`, and `URL`, so there is no dependency to install. Keep the file as an ES module and read the key from the environment.

If you already use npm, the official TypeScript SDK also runs from JavaScript and gives you typed models. This page stays dependency-free so it can run as a single file.

Do not run this in a browser. The key would be public, and the API's CORS policy does not allow arbitrary customer origins. Use a server or a serverless function, then call that from the browser.

```js
const BASE = "https://api.currency-core.com/v1";

class ApiError extends Error {
  constructor(status, code, message) {
    super(message);
    this.status = status;
    this.code = code;
  }
}

export async function getJson(path, params = {}) {
  const key = process.env.CURRENCYCORE_API_KEY;
  if (!key) throw new Error("Set CURRENCYCORE_API_KEY");

  const url = new URL(BASE + path);
  for (const [name, value] of Object.entries(params)) {
    url.searchParams.set(name, String(value));
  }

  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${key}`, Accept: "application/json" },
    signal: AbortSignal.timeout(10_000),
  });
  const body = await res.json();

  if (!res.ok) {
    throw new ApiError(
      res.status,
      body.error?.code ?? "http_error",
      body.error?.message ?? `HTTP ${res.status}`,
    );
  }
  return body;
}

const rates = await getJson("/rates/EUR");
console.log(rates.date, rates.rates.USD);
```

Top-level await works in an ES module. If you target CommonJS, wrap the last two lines in an async `main()` function.

`/v1/convert` returns `results[]`, while `/v1/rates/{base}` returns a `rates` map with the base at `1`. Free includes 1,000 requests per month at 60 per minute. Test keys share the data and quota, capped at 60 per minute; live keys require a paid plan.

Catch `ApiError` and branch on `code`. Retry only `429` and `5xx`, and do not retry a `400` or `403`. Cache by `date` and base; past dates are stable enough for long caching.

## Next steps

- [TypeScript guide](/docs/guides/typescript/) for typed responses
- [Node and Express](/docs/guides/node-express/) for an HTTP service
- [API reference](/docs/api/) and [error codes](/docs/errors/)
- [All developer guides](/docs/guides/)
