Skip to main content

Migrate from Wallets v.1 to v.2

The Wallets API v.2 replaces v.1 endpoints, offering a simpler request model, more detailed responses, advanced Lucene-based filtering, and enhanced wallet lifecycle management. Migrating to v.2 streamlines your integration, reduces complexity, provides better reporting data, and enables more flexible wallet operations. This guide walks you through the required changes for a successful migration.

Endpoint mapping

Operationv.1 endpointv.2 endpoint
Create walletPOST /ledger/v1/walletsPOST /ledger/v2/wallets
List walletsGET /ledger/v1/walletsGET /ledger/v2/wallets
Get walletGET /ledger/v1/wallets/{id}GET /ledger/v2/wallets/{id}
Get profilesGET /ledger/v1/wallets/profilesGET /ledger/v2/wallets/profiles
Manage walletPOST /ledger/v2/wallets/{id}/actions

What changed

Create wallet

The v.2 wallet create request now uses simple, top-level fields instead of the nested instruction object.

{
"currencyCode": "USD",
"name": "USD SWIFT",
"customerReference": "09c04f1b-77b2-42cc-a0c0-da9748a3be11",
"instruction": {
"walletProfile": "18f9a1bf-0d77-45f5-b5ff-1e90411d88ce",
"type": "FIAT",
"virtualAccountRequired": true
}
}

Field changes:

v.1 fieldv.2 fieldNotes
currencyCodecurrencySame currency codes, renamed field.
customerReferencecustomerIdNow optional: omit for direct (non-customer) wallets.
'instruction.walletProfile''profileId'Moved to top level. 'profileId' replaces 'walletProfile', and profile IDs changed formats. See the Wallet profiles section.
'instruction.type'Removed. The wallet type is determined by the selected 'profileId'.
'instruction.virtualAccountRequired'Removed. Virtual accounts are automatically provisioned for fiat profiles.

Create wallet response

The response format now uses clearer names and gives you more useful details.

{
"id": "a:25032877416178:1PL2yxP:1",
"accountReference": "5bc49988-fe25-408f-bccc-3e0fe96cf322",
"customerReference": "fb8c0b12-6552-429e-955e-70af0873331",
"name": "USD SWIFT",
"status": "ACTIVE",
"balance": {
"value": 0.00,
"currencyCode": "USD"
},
"ledgers": [
{
"type": "FIAT",
"accountHolderName": "Embedded customer A",
"accountNumber": "900768107004",
"code": "101019644",
"accountNumberFormat": "ABA",
"paymentReference": null
}
]
}

Response field changes:

v.1 fieldv.2 fieldNotes
accountReferenceRemoved.
customerReferencecustomer.idNow a nested object with id and name.
balance.valuebalance.amountRenamed.
balance.currencyCodebalance.currencyRenamed.
ledgerspaymentInstrumentsRenamed; includes richer bankDetails for fiat and address/network for crypto.
:createdAtNew. ISO 8601 timestamp.
:updatedAtNew. ISO 8601 timestamp.
New wallet status behavior

In v.2, newly created wallets start as INACTIVE and transition to ACTIVE asynchronously. Listen to the ledger:v2:wallet:status-change webhook to know when the wallet is ready.

Wallet profiles

Profile IDs now use descriptive string identifiers instead of UUIDs.

Request: GET /ledger/v1/wallets/profiles?currencyCodes=USD&paymentMethods=SWIFT

{
"profiles": [
{
"reference": "18f9a1bf-0d77-45f5-b5ff-1e90411d88ce",
"currencyCodes": ["USD"],
"paymentMethods": ["SWIFT"]
}
]
}

Profile field changes:

v.1 fieldv.2 fieldNotes
referenceidRenamed. Format changed from UUID to descriptive string (e.g., fiat:usd:141d6bae).
currencyCodescurrenciesRenamed.
paymentMethodsmethodsRenamed.

Filtering: v.1 uses query parameters (currencyCodes, paymentMethods). Wallets v.2 use the q parameter with Lucene query syntax (e.g., currency:USD AND method:SWIFT).

List wallets

Filtering moved from dedicated query parameters to a single q parameter with Lucene syntax.

GET /ledger/v1/wallets?customerReference=09c04f1b-77b2-42cc-a0c0-da9748a3be11&currencyCode=USD

Available v.2 filters via q:

  • customerId: UUID of the customer
  • status: ACTIVE, INACTIVE, or TERMINATED
  • currency: currency code (e.g., USD, USDT)
  • currencyType: FIAT or CRYPTO

Combine filters with AND/OR operators.

List response does not include payment instruments

GET /ledger/v2/wallets returns wallet summaries only. To get full details, including paymentInstruments, send the GET /ledger/v2/wallets/{id} request for each wallet.

Wallet lifecycle management (new in v.2)

Wallets v.2 introduce POST /ledger/v2/wallets/{id}/actions for managing wallet states. In v.1, wallet termination required contacting support.

Available actions:

  • TERMINATE: permanently closes the wallet.
  • BLOCK: temporarily suspends all wallet activity.
  • UNBLOCK: reactivates a blocked wallet.
{
"action": "TERMINATE",
"comment": "CLIENT_REQUEST"
}

Webhooks

v.1 webhookv.2 webhookNotes
ledger:wallet:createledger:v2:wallet:status-changev.2 fires on every status transition (creation, activation, termination, block/unblock), not only on creation.

Migration checklist

  1. Update profile retrieval: replace GET /ledger/v1/wallets/profiles with GET /ledger/v2/wallets/profiles. Map the new id field (replaces reference) into your wallet creation flow.

  2. Update wallet creation: replace POST /ledger/v1/wallets with POST /ledger/v2/wallets. Flatten the request body: use currency, customerId, and profileId instead of the nested instruction object.

  3. Update response parsing: adapt to the new response schema:

    • balance.valuebalance.amount
    • balance.currencyCodebalance.currency
    • customerReferencecustomer.id
    • ledgerspaymentInstruments
  4. Update wallet listing: replace GET /ledger/v1/wallets with GET /ledger/v2/wallets. Convert query parameters to Lucene syntax in the q parameter.

  5. Update wallet retrieval: replace GET /ledger/v1/wallets/{id} with GET /ledger/v2/wallets/{id}.

  6. Subscribe to the v.2 webhook: replace ledger:wallet:create with ledger:v2:wallet:status-change. Update your webhook handler to process status transitions (INACTIVEACTIVE, ACTIVETERMINATED, etc.).

  7. Adopt lifecycle management: if you previously contacted support to terminate wallets, use POST /ledger/v2/wallets/{id}/actions directly.


Related guides:

Was this page helpful?