> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cotizave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Integration best practices

> Recommendations for integrating Cotizave rates, conversions, history, and webhooks in production.

This guide covers integration decisions for V2. If you maintain a V1 integration, see the [migration guide](https://docs.cotizave.com/en/api/v2/migration.md) before changing its routes or responses.

## Keep the API key on your server

Send `X-API-Key` only from your backend. Never place a key in browser JavaScript, a distributed application, a URL, or logs. Expose your own endpoint to the user interface with only the fields it actually needs.

## Discover a rate before using it

Do not derive an identifier from a name or substitute a rate just because it shares a currency with another rate.

Query `GET /v2/fx/{CC}/rates`, retain the returned `id`, and use it for detail, history, or conversion where the endpoint accepts it.

A registered rate can have no current observation. Read [data and historical coverage](https://docs.cotizave.com/en/api/coverage.md) and the [V2 per-plan matrix](https://docs.cotizave.com/en/api/v2/rates-by-plan.md) before relying on a market.

## Cache with an explicit age limit

Avoid calling Cotizave once per visitor. Share a cache in your backend and decide how long your product may show an older value. In V2, retain the `ETag` and use `If-None-Match` for a conditional read; responses are private and vary by API key, so do not share an authenticated response between accounts.

Caching does not replace freshness validation. Inspect `updated_at` and, when the endpoint and plan include them, `effective_date`, `stale`, `staleness_sec`, and `stale_after_sec`.

## Retain each calculation's context

When saving a conversion, price, or invoiced amount, retain the applied ID or market, currencies, amount, `updated_at`, and, where present, value date and freshness fields. The API calculates with the published rate: it does not include fees or guarantee transaction execution.

For a reference with a value date, do not replace `effective_date` with `updated_at`. An observation updated on a non-business day can still have an earlier value date.

## Query history without inventing days

Pro can query up to 365 days back; other plans have a shorter window. You can request a one-year range when your plan allows it, but the result does not guarantee 365 points: a series may not publish on weekends, holidays, or other days.

Use the same ID returned by the collection. Do not automatically fill missing dates or assume one rate's history represents another's. `403 history_out_of_retention` means the range exceeds your plan; `404 history_not_available` means that series does not expose history; and `404 rate_not_found` can mean the date had no observation. See [coverage](https://docs.cotizave.com/en/api/coverage.md) and [V2 history](https://docs.cotizave.com/en/api/v2/history.md).

## Handle errors by code, not text

Do not retry unchanged input, credential, or plan errors: `400`, `401`, `402`, `403`, and `404`s for absent resources require resolving their cause. For transient read failures, bound retries, use increasing delays, and set a total deadline.

For `429`, honour `Retry-After` and inspect available quota headers. Distinguish monthly exhaustion from a requests-per-minute limit: repeating a request does not resolve the former. Do not automatically repeat a `POST` if you cannot tell whether the server processed it.

Read [errors](https://docs.cotizave.com/en/api/errors.md) and [quotas and limits](https://docs.cotizave.com/en/api/rate-limits.md) for codes and headers.

## Treat usage as shared consumption

V1 and V2 share an account's monthly quota. Count retries, background jobs, and parallel processes too. Frequent polling per process can exhaust quota even if every individual request is valid.

## Process webhooks idempotently

When using webhooks, verify their signature, persist the event idempotently, and return `2xx` only after storing it durably. A `2xx` confirms delivery; do not send it before your system can process the event. See [webhooks](https://docs.cotizave.com/en/guides/webhooks.md) for signatures, retries, and pauses.

## Test the cases that change the outcome

Before deploying, test at least a rate restricted by plan, a date outside retention, a date without an observation, a response marked `stale`, a `429`, and a transient network failure. Also verify that an invalid key never reaches the browser or application logs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.