Migrating from v1
The v2 API is a ground-up rebuild. It runs alongside v1 until September 10, 2026, when v1 is retired.
Key changes
Authentication (breaking change)
The old scheme (X-API-KEY + RSA x509 signature) is gone in v2. In its
place, we use the two-tier scheme: skp_live_…
bearer keys for reads, and EdDSA-signed JWTs to move money. Onboarding is
self-service (no more certificate sent by email).
Errors
v2 always returns application/problem+json (RFC 9457) with
a stable code, instead of inconsistent error formats.
Route renames
| v1 | v2 |
|---|---|
/convert_orders | /orders |
/converts | ⚠️ /fills — one row per execution, not per order (see the warning below) |
/converts/quotations | /quotes |
/converts/quotations:confirm | POST /orders |
/currencies | /balances |
/historical_balances/{currencyId} | /balances/{assetSymbol}/history |
/ledger_movements/{currencyId} | /ledger?assetSymbol= |
/supported_currencies | /assets |
/supported_markets | /markets |
/users/current | /account |
/convert_orders/id/{id} | GET /orders/{id} |
/converts/id/{id} | ⚠️ no 1:1 equivalent — see Lookups by id |
/…/clOrdId/{clOrdId} | ⚠️ no equivalent — see Lookups by id |
/converts maps to /fills, not /ordersIn v1, /converts returns one row per execution and /convert_orders one row per
order. Their v2 equivalents are /fills and /orders respectively. If you point what
today reads /converts at /orders, your row counts change: an order with several
executions returns a single row from /orders where v1 returned several.
The resource is called an order, not a "conversion": Convert is the product brand, but
the model is exchange-shaped (an order carrying a type), so future order types can be added
without a breaking restructure.
Lookups by id that change shape
Three v1 routes have no 1:1 equivalent in v2:
| v1 | v2 | What changes in your code |
|---|---|---|
/convert_orders/id/{id} | GET /v2/orders/{id} | Nothing: still one row. |
/converts/id/{id} | GET /v2/orders/{id}/fills or GET /v2/fills?orderId={id} | The cardinality changes: you get a list of executions, not a row. There is no GET /v2/fills/{id}. |
/convert_orders/clOrdId/{clOrdId} | — | There is no lookup by clientOrderId in v2. That field is returned only on the POST /v2/quotes response, alongside the orderId you can query later. Persist that mapping on your side when you quote. |
?sourceId= exists only on the ledger?orderId= is available on /v2/fills and /v2/ledger. ?sourceId= is on
/v2/ledger only — it does not filter orders or fills. See
ids and correlation.
Parameter and field renames
Route renames announce themselves with a 404. Query-parameter renames and
response-field renames do not behave the same way as each other, so they are split
below.
Query parameters — v2 rejects the ones it does not recognize
v2 does not ignore an unknown parameter: it returns 400
validation_error naming the offending parameter
(property take should not exist). This is deliberate — on a money API an ignored
filter returns the wrong answer with no warning — and in practice it means a rename
you miss shows up on the first call, not in the month-end reconciliation.
| v1 | v2 |
|---|---|
take= | limit= |
currencyId= | assetSymbol= |
currencyBase= / currencyQuote= | baseAsset= / quoteAsset= |
Response fields — these do fail silently
No safety net here: reading a field that no longer exists yields undefined, not
an error.
| v1 | v2 | If you miss it |
|---|---|---|
meta.currentSize | pagination.limit | All four change at once, so a pagination loop written for v1 finds no totals and stops after the first page. |
meta.totalCount | pagination.totalItems | ⬑ |
meta.totalPages | pagination.totalPages | ⬑ |
meta.currentPage | pagination.page | ⬑ |
quantity | amount | Null amount. Watch the sign too — see below. |
date | createdAt | Null timestamp. |
currencyId | assetSymbol | Null asset. |
transactionId | source.id (with source.type) | ⚠️ Not id. id exists in both v1 and v2 and is a different field: the entry's own. See ids and correlation. |
qtyCumBase / qtyCumQuote | filledBaseAmount / filledQuoteAmount | Null filled quantity. |
currencyBase / currencyQuote | baseAsset / quoteAsset | Unidentified market. |
Changes of meaning, not of name
Two changes keep a reasonable name but change the value. No error announces them — check for them explicitly.
Public amounts are positive magnitudes
In v1, quantity carried a sign (a withdrawal was negative). In v2 amount,
fee and total are always positive: direction comes from the entry's type,
and from the resource itself (a withdrawal debits, a deposit credits).
If you sum movements to compute a net, the same code produces a different
answer: in v2 debits add instead of subtracting. Branch on type before you
accumulate.
assetFormat defaults to rebased
/orders, /fills and /withdrawals accept assetFormat, and its default is
rebased — a deliberate change from the previous behaviour, which returned
base. For tokenised equities that changes the
amounts you see relative to v1, with no error signal. For every other asset the
multiplier is 1 and nothing changes.
This is an accounting decision before it is a technical one: if your integration
depends on settled figures, ask for assetFormat=base explicitly.
New in v2
- Fills as a first-class resource —
GET /v2/fillsandGET /v2/orders/{id}/fills. - A traceable ledger —
GET /v2/ledger, withsource: {type, id}and?sourceId=/?orderId=filters (guide). - Indicative pricing —
GET /v2/markets/{market}/price, a non-binding rate that reserves nothing and needs no signature. (Market and asset listings already existed in v1 as/supported_marketsand/supported_currencies; what is new here is the price.) - Signed webhooks (guide).
- Per-account and per-key rate limits with
RateLimit-*headers.
Timeline
v1 is retired on September 10, 2026 (2026-09-10). From that date its
endpoints stop serving traffic — complete your migration to v2 before then.
Ahead of the shutdown, v1 will start returning Deprecation / Sunset headers
announcing that same date, and we may run brownouts — short, announced windows
where v1 returns errors — so you can confirm your migration is complete.