Prerequisites
- Payward Services API credentials (see Authentication Guide)
- A verified user with at least one account
Only cryptocurrency deposits are currently available through the Payward Services API. Cryptocurrency withdrawals,
fiat deposits, and fiat withdrawals are not yet available.
Crypto deposits
Deposit workflow
1
List deposit methods
Query available deposit methods for the target asset.
GET /v1/accounts/{account_id}/funds/deposits/methods/{asset_symbol}2
List deposit addresses
Check whether the account already has an address for the selected method.
GET /v1/accounts/{account_id}/funds/deposits/addresses3
Claim deposit address
If needed, claim an address for the selected method.
POST /v1/accounts/{account_id}/funds/deposits/addresses4
Display address to user
Display the address and any required tag or memo. The user sends crypto from their external wallet to this address.
5
Track the deposit
Subscribe to
funds.deposit_* webhook events, then reconcile deposits on the receiving account through GET /v1/accounts/{account_id}/portfolio/transactions?types=deposit.Bitcoin Lightning uses one-time, amount-bound invoices instead of reusable deposit addresses. After listing methods,
replace the address steps above with the Bitcoin Lightning invoice flow.
The examples below use the signing helpers from the Authentication
Guide. For GET requests, sign the same ordered query
parameters that you send.
Step 1: list deposit methods
Query available deposit methods for a crypto asset. Use the method’sid from the response as method_id when listing or claiming an address.
Most cryptocurrency deposits are free, with minimum deposit amounts varying by asset. A few cryptocurrencies are
charged an
address_setup_fee (a one-time fee on the user’s first deposit to a new address) or a per-deposit fee.page_token from next_page_token to request the next page. Omit it for the first page.
Response example
network, method when present, fee, minimum, and
network_info.est_confirmation_time. Pass the method’s id back as method_id when listing or claiming an address.
Optional fee, limit, and network fields are omitted when they do not apply.
Each asset can have a maximum of five deposit addresses. Some funding methods share an address space, so the same
address can be returned for different assets or networks.
method_id selects a context in which the returned address
is valid; it does not say how the address was originally claimed. List and reuse an existing address before claiming
another.Step 2: list deposit addresses
Retrieve deposit addresses available for the selected funding method. Reuse a returned address instead of creating a new one each time.Response example
page_token from next_page_token to retrieve the next page. Optional tag, memo, and expire_time fields are
omitted when they do not apply.
Completed deposits appear in
GET /v1/accounts/{account_id}/portfolio/transactions?types=deposit. Portfolio
visibility is asynchronous.Step 3: claim a deposit address
If Step 2 returns no suitable address, claim one using the methodid from Step 1 as method_id. Display the address
to the user so they can send crypto from an external wallet.
You can claim a maximum of five deposit addresses per asset. List the account’s existing addresses before claiming
another one.
Some networks (e.g., XRP, XLM) require a tag or memo in addition to the address. If
tag or memo is present in the
response, your UI must display it and instruct the user to include it when sending funds. Deposits sent without the
required tag/memo may be lost.Bitcoin Lightning invoice flow
For the Bitcoin Lightning deposit method, create a BOLT11 invoice for the exact BTC amount the user intends to deposit. Use the limits from the deposit-methods response to validate the amount before requesting the invoice. The selectedaccount_id is the account that receives the completed deposit.
Reusable-address UI flow
Best practices
- Always display tag/memo: For networks that require a tag or memo (XRP, XLM, etc.), prominently display it alongside the address. Missing tags/memos can result in lost funds.
- Set expectations: Show
minimumamounts andest_confirmation_timefrom the methods response so users know what to expect before sending funds. - Use fresh responses: Available methods, addresses and limits are user-specific and may change based on account standing, remaining limits, or regional regulations. Fetch fresh data before displaying options rather than relying on cached results.
Deposit webhook events
Register a webhook throughPOST /v1/webhooks and subscribe to the deposit lifecycle events your integration needs:
All deposit lifecycle events contain
type, transaction_id, user_id, and account_id. They can also contain
amount and fee:
amount is the total deposit amount, inclusive of the fee. PWS includes it when both the source value and its asset can
be resolved.
fee is optional. PWS includes it only when the source provides both the fee value and its asset and the asset can be
resolved. This includes an explicitly provided zero fee. If the fee or its asset is unavailable, PWS omits fee rather
than assuming that it is zero or that it uses the deposit amount’s asset.
The availability of amount and fee is independent of the lifecycle event type. Treat absent fields as unavailable;
PWS does not return them as null.
Returned and failed deposits also contain a required reason field. PWS normalizes it to one of
account_details_mismatch, limit_exceeded, duplicate, account_restricted, or other. Other deposit lifecycle
events do not contain reason.
A deposit can produce multiple lifecycle events as it progresses. Treat each webhook as a notification and use the
Portfolio Transactions endpoint for reconciliation. Deliveries can be repeated, so use the svix-id header as the
deduplication key and return a 2xx response after accepting the event.
These events describe the lifecycle of a deposit. They are distinct from conversion.deposit_* events, which describe
the inbound funding leg of a conversion.
Crypto withdrawals
Withdrawals are key-based: you save an address once, then use itskey in each withdrawal request.
Withdrawal workflow
1
List withdrawal methods
Query available withdrawal methods for the target asset.
GET /v1/accounts/{account_id}/funds/withdrawals/methods/ {asset_symbol}2
Validate address (optional)
Verify the destination address is valid before saving.
POST /v1/funds/withdrawals/addresses/validate3
Save address (create key)
Store the validated withdrawal address for the user.
POST /v1/accounts/{account_id}/funds/withdrawals/addresses4
Preview / submit withdrawal
Submit the withdrawal request.
POST /v1/accounts/{account_id}/funds/withdrawals5
Monitor status (webhook / polling)
Track the withdrawal through
withdrawal.status_updated webhooks and reconcile it through GET /v1/accounts/ {account_id}/portfolio/transactions?types=withdrawal.Step 1: list withdrawal methods
Call this first to determine the method’sid (passed as method_id in later requests), fee estimates, limits, and optional fee_token.
Response example
Step 2: validate withdrawal address (recommended)
This endpoint validates the destination before you save it.Step 3: save withdrawal address
Save the address once and keep the returnedkey for future withdrawals.
Step 4: preview and submit a withdrawal
Usepreview=true to quote fees and totals without creating a withdrawal, then submit with preview=false.
Statuses
Withdrawal best practices
- Use idempotency keys: Always generate a unique UUIDv4 and send it as the
Idempotency-KeyHTTP header per intended withdrawal to avoid duplicate sends on retries. Replayed responses includeIdempotent-Replayed: true. - Preview first: Run a preview request immediately before submit so users can confirm
amount,fee, andtotal. - Refresh expired fee tokens:
fee_tokenvalues are short-lived. If a withdrawal is rejected due to an expired/invalid token, fetch withdrawal methods again (or run a fresh preview) to get a newfee_tokenand retry. - Persist key ownership: Store which
keybelongs to each user and enforce access checks in your app. - Handle memo/tag networks: For XRP/XLM-like networks, capture and persist memo/tag fields when addresses are saved.
- Monitor and reconcile: Subscribe to
withdrawal.status_updatedand pollGET /v1/accounts/{account_id}/portfolio/transactions?types=withdrawalfor recovery and reconciliation.