Wallet Whitelisting
Wallet Whitelisting API Guide
This guide explains how to create and manage whitelisted cryptocurrency wallets through the Ledger Service API.
Wallet lifecycle
A wallet moves through the following customer-visible statuses:
| Status | Meaning |
|---|---|
COOLDOWN | The wallet is in its security waiting period. startedAt and expiresAt indicate the cooldown window. |
PROCESSING | Verification and activation checks are in progress. This may include a microtransaction test. |
ACTIVE | Whitelisting is complete and the wallet can be selected for eligible payouts. |
FAILED | Whitelisting could not be completed. Do not use the wallet for a payout. |
The normal progression is:
COOLDOWN -> PROCESSING -> ACTIVE
-> FAILEDPROCESSING covers the verification period between cooldown and the final ACTIVE or FAILED result. Continue checking the wallet status until it changes.
Create a whitelisted wallet
POST /whitelist/walletRequired request fields:
walletAddresscurrencynetworkbeneficiary
Optional fields:
walletAddressTag— destination tag or memo when required by the networkwalletFriendlyName— a customer-defined name of up to 32 characters
The beneficiary object describes who controls the destination wallet:
| Field | Supported values or purpose |
|---|---|
type | SELF, INDIVIDUAL, or BUSINESS |
walletType | CUSTODIAL or NON_CUSTODIAL |
individual | Provide only when type is INDIVIDUAL. When present, phone is required; countryOfBirth is optional and may be null. |
business | Provide only when type is BUSINESS. When present, name, registrationNumber, phone, and email are required by the API schema. |
vaspDid | Identifier of the wallet provider, where applicable |
proof | Ownership proof; the supported proof type is SELF_DECLARATION |
When type is SELF, omit both individual and business. The customer information associated with the authenticated account is used for a self-owned wallet.
Example request for a self-owned wallet:
curl --request POST \
'https://api.sandbox.op-digital.com/whitelist/wallet' \
--header 'Authorization: Bearer <access-token>' \
--header 'X-Merchant-ID: <merchant-uuid>' \
--header 'Content-Type: application/json' \
--data '{
"walletAddress": "0x1111111111111111111111111111111111111111",
"walletFriendlyName": "Treasury wallet",
"currency": "USDC",
"network": "ETHEREUM",
"beneficiary": {
"type": "SELF",
"walletType": "NON_CUSTODIAL",
"proof": {
"type": "SELF_DECLARATION",
"attestation": "I confirm that I control this wallet."
}
}
}'A successful request returns 201 Created without a response body or wallet ID. To find the newly created record, query the list endpoint using the same walletAddress, currency, and network, sort by createdDate:desc, and verify the returned address, currency, network, merchant, and cooldown timestamps before storing the ID.
curl --get \
'https://api.sandbox.op-digital.com/whitelist/wallet' \
--header 'Authorization: Bearer <access-token>' \
--header 'X-Merchant-ID: <merchant-uuid>' \
--data-urlencode 'walletAddress=0x1111111111111111111111111111111111111111' \
--data-urlencode 'currency=USDC' \
--data-urlencode 'network=ETHEREUM' \
--data-urlencode 'orderBy=createdDate:desc'More than one record may exist for the same address, currency, and network. Do not select a wallet based only on its position in the result. Match all returned details and cooldown timestamps. If the new record cannot be identified unambiguously, do not use a candidate wallet ID and contact support with the creation time and request details.
Always verify that the currency, network, address, and optional tag belong together. Sending assets on an incompatible network can result in permanent loss.
List whitelisted wallets
GET /whitelist/walletSupported filters:
| Parameter | Purpose |
|---|---|
currency | Filter by currency. |
accountId | Derive and filter by the currency and network of an account. |
walletAddress | Match a specific wallet address. |
network | Filter by blockchain network. |
status | Filter by COOLDOWN, PROCESSING, ACTIVE, or FAILED. |
friendlyName | Filter by friendly name. |
searchTerm | Search by wallet address or friendly name. |
pageNumber | Zero-based page number; default 0. |
pageSize | Number of results; default 20, maximum 200. |
orderBy | Sort expression such as createdDate:desc. |
Example:
curl --get \
'https://api.sandbox.op-digital.com/whitelist/wallet' \
--header 'Authorization: Bearer <access-token>' \
--header 'X-Merchant-ID: <merchant-uuid>' \
--data-urlencode 'status=PROCESSING' \
--data-urlencode 'network=ETHEREUM' \
--data-urlencode 'pageNumber=0' \
--data-urlencode 'pageSize=20' \
--data-urlencode 'orderBy=createdDate:desc'The response is paginated:
{
"pageNumber": 0,
"pageSize": 20,
"content": [
{
"id": "c50c2a8e-ffbb-4cdb-87da-dc46ecad40c9",
"merchantId": "e59cefe9-d65f-46c3-91f8-bf426cf31cf7",
"walletAddress": "0x1111111111111111111111111111111111111111",
"currency": "USDC",
"network": "ETHEREUM",
"status": "COOLDOWN",
"startedAt": "2026-09-30T10:00:00",
"expiresAt": "2026-10-01T10:00:00",
"friendlyName": "Treasury wallet"
}
]
}startedAt and expiresAt are UTC timestamps without a timezone suffix.
Get wallet details
GET /whitelist/wallet/{id}curl \
'https://api.sandbox.op-digital.com/whitelist/wallet/<wallet-id>' \
--header 'Authorization: Bearer <access-token>' \
--header 'X-Merchant-ID: <merchant-uuid>'The response can include the wallet data, beneficiary information, cooldown timestamps, and microtransaction fields.
Check whether a wallet is active
GET /whitelist/wallet/statusProvide the wallet ID in the JSON request body:
curl --request GET \
'https://api.sandbox.op-digital.com/whitelist/wallet/status' \
--header 'Authorization: Bearer <access-token>' \
--header 'X-Merchant-ID: <merchant-uuid>' \
--header 'Content-Type: application/json' \
--data '{
"walletId": "c50c2a8e-ffbb-4cdb-87da-dc46ecad40c9"
}'Example response:
{
"isActive": true
}This endpoint provides an informational status check. An isActive value of true does not reserve the wallet's status or guarantee that a later payout request will succeed.
Microtransaction verification
During PROCESSING, the platform may send a small test amount to the wallet and wait for its return. A return is required only when you receive penny-test instructions.
When instructed to complete a penny test:
- Wait until the outgoing test transfer is confirmed.
- Follow the supplied return instructions exactly, including the amount, asset, network, and destination address.
- Send the return transfer from the wallet address being verified.
- Allow for network confirmation time and continue monitoring the wallet status.
Do not infer the return amount or destination solely from a transaction hash or blockchain explorer. If return instructions are missing or unclear, do not send funds and contact support.
The wallet detail response can include:
outgoingTransactionHash— hash of the amount sent to the walletoutgoingTransactionStatus— processing status of the outgoing transferincomingTransactionHash— hash of the returned amountincomingTransactionStatus— processing status of the return transfer
Interpretation:
| Fields | Meaning |
|---|---|
Outgoing hash with COMPLETED status | The test amount was sent successfully. |
Incoming hash with COMPLETED status | The returned amount was detected successfully. |
Both directions are COMPLETED | The microtransaction round trip is complete. The wallet may remain in PROCESSING until verification finishes. |
| Fields are absent | The test has not started, has not reached that direction, or is not required for this wallet. |
PROCESSING alone does not prove that the microtransaction has completed. Always inspect the transaction fields when confirmation is required.
Delete a whitelisted wallet
DELETE /whitelist/wallet/{id}curl --request DELETE \
'https://api.sandbox.op-digital.com/whitelist/wallet/<wallet-id>' \
--header 'Authorization: Bearer <access-token>' \
--header 'X-Merchant-ID: <merchant-uuid>'A successful deletion returns 204 No Content. Stop referencing the wallet ID after deletion.
Errors
The documented authentication and authorization responses are:
| HTTP status | Meaning |
|---|---|
401 | The access token is missing, invalid, or expired. |
403 | The caller is not allowed to perform the operation. |
Other errors use the standard response structure:
{
"message": "BAD_REQUEST",
"code": 4010,
"id": "error-correlation-uuid"
}code is an application error code; it is not the HTTP response status. message may be a symbolic error name rather than a human-readable sentence. The optional id is the error correlation ID and should be retained when contacting support.
Do not retry validation or authorization errors without correcting the request. For transient server errors, use bounded retries with exponential backoff and retain the error correlation ID for support.
Integration checklist
- Use the correct
X-Merchant-IDon every request. - Validate the address, network, currency, and destination tag before creation.
- Store the returned wallet ID after retrieving the newly created wallet.
- Treat only
ACTIVEwallets as payout-ready. - Treat
PROCESSINGas a potentially long-running state. - Do not rely on transaction fields being present in every response.
- Protect beneficiary information as sensitive personal data.
- Use pagination when listing wallets.
- Stop using a wallet immediately after deletion.
Updated about 1 month ago
