The Balansas Customer API is versioned at the URL level. Every request resolves to exactly one version — v1 or v2 — and the resolved version is echoed back in an X-API-Version response header. This page documents the three ways to select a version, the precedence rule between them, and the forward-compatibility promise.

Selecting a version

You can pin a request to a version three ways. The first that matches wins.
1

Path prefix (most explicit)

Prepend /v1/ or /v2/ to the resource path:
https://stagingapi.balansas.com/functions/v1/customer-api/v2/fiat-accounts
The path is visible in logs, curl examples, and Postman collections, so this is the most reliable signal of intent.
2

X-API-Version header

Send X-API-Version: v1 or X-API-Version: v2. Case is ignored; whitespace is trimmed.
X-API-Version: v2
3

Unversioned request (defaults to v1)

A request without a path prefix and without the header resolves to v1. Existing integrations that have never specified a version will keep working on v1 forever — we will not silently flip the default.

Path wins over header

If the path says one version and the header says another, the path wins. The path is what is stored in client code, examples, and tooling; the header is a softer override. The header only takes effect when no path prefix is present.
Path beats header
# Resolves to v2 — the path prefix wins, X-API-Version: v1 is ignored.
curl https://stagingapi.balansas.com/functions/v1/customer-api/v2/fiat-accounts \
  -H "x-api-key: sk_test_xxxxxxxxxxxxxxxxxxxx" \
  -H "X-API-Version: v1"

Confirming the resolved version

Every customer-API response — success and error — carries an X-API-Version header set to the version that handled the request, once the version has been resolved. (CORS preflight OPTIONS responses and the last-resort 500 for a catastrophic internal failure are emitted before version resolution and do not include it.) Inspect the header to confirm your routing worked as intended:
$ curl -i https://stagingapi.balansas.com/functions/v1/customer-api/v2/fiat-accounts \
    -H "x-api-key: sk_test_xxxxxxxxxxxxxxxxxxxx"
HTTP/2 200
content-type: application/json
x-api-version: v2
...

Today: v1 and v2 are behaviourally identical

v2 is registered as a supported version, but it does not yet diverge from v1. Every endpoint you call under /v2/ currently routes through the v1 handler and returns the v1 response byte-for-byte. You can begin pointing integrations at /v2/ today with zero risk of behavioural drift. When the first v2-specific change ships, this page will document exactly which endpoints differ and how, and the API Reference will gain a version switcher.
Until that happens, choose whichever path style your tooling prefers. There is no functional difference between /v1/fiat-accounts, /v2/fiat-accounts, and unversioned /fiat-accounts.

Forward-compatibility promise

  • v1 is stable. Bug fixes, additive fields, and new endpoints may land on v1, but no existing endpoint’s request or response contract will change in a way that breaks correctly-written clients.
  • Breaking changes — renamed fields, removed endpoints, altered semantics — will only ever appear under a new version (v2, v3, …).
  • A deprecation will be announced on this page and in release notes before its successor version becomes the default. The default version (v1) will not flip without a migration window.

Unsupported versions

Requesting a version that does not exist — for example /v3/fiat-accounts or X-API-Version: v9 — returns HTTP 400 and the X-API-Version response header is set to the rejected token so you can see what was parsed:
400 response
{
  "error": "Unsupported API version: 'v3'. Supported versions: v1, v2."
}
This particular 400 uses a flat-string error field, not the { error: { code, message } } envelope documented under Errors. The unsupported-version check runs before request dispatch, in a separate layer from the per-endpoint error envelope. Branch on HTTP status 400 and inspect whether error is a string before parsing it as an object.

Logging and observability

The resolved version is persisted to the api_request_logs.api_version column for requests that reach logging — successful, failed, rate-limited, unsupported-version, and invalid-key requests — so the operator dashboard can track adoption of newer versions as they ship. (Requests that short-circuit before logging — a missing API key, or a catastrophic internal failure — are not recorded.)

Errors

The full error envelope used by per-endpoint failures.