Documentation

Observability and Logging

Log endpoint, base, date, status and latency with your own correlation ID, since the API does not return a request ID.


When a rate looks wrong, a log line without the endpoint, base, and date cannot tell you whether the API or your own cache produced the value. Emit one structured record per outgoing call with those fields, the response status, latency, and a correlation ID that you generate. The API does not return a request ID header today, so your ID is the only thread that follows one request across your services.

FieldExampleWhy it matters
correlation_id7f3c...Joins this call to your own logs and traces
endpoint/v1/rates/EURSeparates routes in dashboards
baseEURExplains which snapshot was requested
date2026-11-10Distinguishes a live view from a backfill
status200Supports error-rate and quota reconciliation
latency_ms184Shows upstream or network drift

Include requestedDate when the response carries it, so a carry-forward from a weekend or holiday is visible. Never log the key itself. Log a key alias or the last four characters at most, and keep the secret out of URLs, since the API has no query-string authentication.

type CallLog = {
  correlationId: string;
  endpoint: string;
  base: string | null;
  date: string | null;
  status: number | null;
  latencyMs: number;
};

export async function call(url: URL, key: string, base: string | null = null) {
  const log: CallLog = {
    correlationId: crypto.randomUUID(),
    endpoint: url.pathname,
    base,
    date: url.searchParams.get("date"),
    status: null,
    latencyMs: 0,
  };
  const started = performance.now();

  try {
    const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
    log.status = res.status;
    return res;
  } finally {
    log.latencyMs = Math.round(performance.now() - started);
    console.info(JSON.stringify(log));
  }
}

Propagate the same correlation ID into your own job records and support responses. Do not assume the API echoes it: the header is not part of the API contract today. Correlating your ID with the response date and status helps you trace a cache or carry-forward dispute.

Status helps you reconcile usage: the per-minute limit counts every request, while the monthly quota counts only successful billable requests. The public status page at /status/ exposes health and a 90-day uptime history. It is useful during an incident, but it is not an SLA document, so alert on your own service level objectives.