Create and Track a Transfer
Create a transfer, handle its creation result, and check its status.
Before you start
API access
Set up your API key and host with the
Internal transfersorPartner transfersscope, and implement request signing. Verify your setup once with Send Your First Request.Request limits
Keep creation requests, retries, and status checks within the limits for each operation and API key. Include requests from all applications and workers using that API key. See API Configuration and Limits.
Saved records
Your application must save the transfer request body, idempotency key, state, and attempt times before sending, and restore them after a restart. Allow only one sender per record. See the record states in Recovery and Idempotency.
A created transfer cannot be cancelled or reversed through the API. If you sent it to the wrong account, contact Customer Support.
Recommended flow
- 1Check the source account balance (optional). Read the balance before starting a new transfer. You can skip this request if your application already tracks the account balance.
- 2Prepare the transfer request. Choose and check the destination account and amount. Follow Between Your Own Accounts or To Another Client.
- 3Save the request and its idempotency key. Generate a random UUID for each new transfer. Store the idempotency key with the transfer request body before sending. If you are continuing an earlier attempt, load the same saved body and idempotency key.
- 4Send the transfer request. Create a fresh timestamp and signature for every attempt, then call
POST /v1/transfers. On201with a validtransfer_id, save that ID. For an unknown result or an error, follow Recovery and Idempotency before sending again. - 5Check the transfer status. Use the saved
transfer_idwithGET /v1/transfers/{transfer_id}. We recommend checking every 2 seconds. Return the final status when it isdoneorrejected, or the latestprocessingstatus if your chosen waiting time ends first. See Check a Transfer Status.
transfer_id must be a non-empty string containing only digits 0–9. Keep it exactly as returned; do not convert it to a number. A 201 without a valid transfer_id leaves the creation result unknown.
Flow summary
Example pseudo-code
Use this logic in any programming language. See Record states and What to expect in return in Recovery and Idempotency. A Python implementation is in Code Examples.
if starting a new transfer:
optionally read the source account balance
idempotency_key = new random UUID
record = save request and idempotency_key, with state new
else:
record = load saved request, idempotency key, state, and attempt times
send only records whose state is new or reserved
repeat up to the chosen creation attempt limit:
was_reserved = record.state is reserved
save attempt time and record.state reserved together
if saving fails: stop without sending
generate a fresh timestamp and signature
result = send the saved request body with its saved idempotency key
if result is 201 with a valid transfer_id:
save transfer_id and mark record as created
break
if the creation result is unknown:
if another creation attempt is allowed:
wait with exponential backoff
continue
return unknown_result with record still reserved
update record using Recovery and Idempotency rules and was_reserved
return creation_error with the updated record
status_check_deadline = now + chosen waiting time
repeat:
transfer = read status using transfer_id
if the status request fails:
return status_error with transfer_id
if transfer.status is done or rejected:
return transfer
if the next check would exceed status_check_deadline:
return transfer with status still processing
wait 2 seconds
What to do next
| Situation | What to do |
|---|---|
201 with a valid transfer_id | Save the ID and check the transfer status. Creation is confirmed; the transfer can still be processing. |
processing | Check the status every 2 seconds within your chosen waiting time. Transfers usually complete within a few seconds, but the processing time is not guaranteed. |
done or rejected | Stop status checks. These statuses do not change. For details of a rejected transfer, see Transaction History in the Payments & wallet section of your Personal Area. |
| Unknown creation result or an API error | Follow Recovery and Idempotency. Never resend the same transfer with a new idempotency key while an earlier creation result is unknown. |
| Creation attempts exhausted | Continue later with the saved request and idempotency key, or close the record if you decide to stop sending permanently. Closing a record does not prove that no transfer was created. |
| Status waiting time reached | Report the latest status as processing, with its transfer_id. The transfer is still in progress; this does not mean it failed or was cancelled. If it stays processing beyond the waiting time chosen for your application, contact Customer Support with that transfer_id. |
| Status request failed | Keep the transfer_id and check the same transfer later. Do not repeat creation. |
Related pages
Core Concepts · Recovery and idempotency · Troubleshooting Your API Requests · Code Examples