Using the APIStatuses & Lifecycles

Statuses & Lifecycles

Every state machine in one place: what each status means, which are terminal, and which webhook fires on each transition.

Status values are stable API contract, and the same vocabulary is used in GET responses, in webhook payloads, and throughout these docs. Resources move forward through their chains. The endorsement is the exception, noted below: it returns to pending when a change is resubmitted after issues, to incomplete when something only you can supply is owed, and it can move from approved back to issues when the review asks for more.

A status marked reserved is part of the vocabulary but not produced today. Handle it in your code so a later release needs no change.

Endorsement

The public verification reading: the review of the customer for one currency, which is the verification. See Verification & Endorsements.

StatusTerminalMeaningWebhook on entry
incompletenoNot requested, not yet submitted, or something it needs is outstanding. The missing bucket lists what you oweendorsement.request_for_information when the review hands it back to you; none on creation
pendingnoRequested and under review. Nothing is owed right nownone
issuesnoThe review asked for more, or something received is not usable. The buckets name it, and a PATCH with the fix resubmitsendorsement.request_for_information, except when the only code is unavailable
approvednoThe customer can use this currency's featuresendorsement.approved
rejectedyesFinally refused for this currencyendorsement.rejected

approved is not permanent. The review's word stands in both directions, and it can ask for more on an endorsement it approved, which moves it to issues.

issues with the single code unavailable means we could not reach the review. No webhook fires, we retry automatically, and you need not act.

Verification round

One submission to one endorsement's review, listed at GET /api/customers/{customer_id}/verifications. A submit, or a PATCH that resubmits, opens one round per endorsement it sends, and each round names its endorsement.

StatusTerminalMeaning
submittednoSent for review
under_reviewnoUnder review
approvedyesThis round passed
request_for_informationyesThis round asked for something. rejection_reasons names it
rejectedyesThis round refused
expiredyesA round that will never be decided: an old one, or one that never reached the review. The retry opens a new round

Rounds carry no webhooks of their own. Decisions surface on the customer's endorsements, which is the reading to build on.

Customer

StatusTerminalMeaning
pendingnoCreated and not yet approved
activenoNormal
rejectedyesRefused
frozennoSet by Rasto. Contact support

Deposit

StatusTerminalMeaningWebhook
detectednoThe bank credit was seennone
confirmednoReservednone
orchestratingnoConversion in progress. Also where a deposit waits when corridor inventory is momentarily shortdeposit.received
completedyesConverted and deliverednone
returnedyesSent back to the senderdeposit.returned
failedyesReservednone
on_holdnoCompliance hold, needs review before it proceedsdeposit.on_hold

Today returned and on_hold are produced in sandbox, through the simulation amounts. In live, a credit the bank reverses or holds is resolved by our team, who contact you.

Conversion

StatusTerminalMeaningWebhook
creatednoOpened for a depositconversion.created
routingnoRoute and rate being fixednone
executingnoExecuting the conversionnone
settlingnoDelivery in flightnone
completedyesFees and FX settled, delivered_amount finalconversion.completed
failedyesReservednone
refundingnoReservednone
refundedyesReservednone
requires_attentionnoParked for our team's review, for example a delivery that failed on chain. Nothing more moves until it is resolvednone

Payout

StatusTerminalMeaningWebhook
creatednoDelivery preparednone
submittednoReservednone
completedyesConfirmed on chain. tx_hash is the proof. conversion.completed fires alongside itpayout.completed
failedyesReservednone
returnedyesReservednone

Virtual account

StatusTerminalMeaningWebhook
pendingnoProvisioning at the banking railnone
activenoLive. Deposit instructions are validvirtual_account.activated
frozennoReservednone
closedyesPermanently closednone

Wallet

StatusTerminalMeaning
activenoLive: receives and sends
frozennoReserved
closedyesPermanently closed

A send against a non-active wallet returns 400 wallet_not_active.

Wallet operation

The lifecycle of every send from a wallet, the only way funds leave one.

StatusTerminalMeaningWebhook on entry
authorization_requirednoBuilt, waiting for your signature. Nothing has moved. The authorization and signing objects ride the response only in this statenone
authorizednoYour signature was accepted. Execution beginsnone
signingnoObtaining the signature from the signing networknone
signednoSignature obtainednone
submittingnoAssembling and broadcastingnone
submittednoOn chain, awaiting confirmationnone
completedyesLanded. tx_hash is the proofwallet_operation.completed
failedyesNothing moved. Creating a replacement is safewallet_operation.failed
expiredyesAuthorize was called after the 30-second window. Nothing movednone
returnedyesReserved: moved, then reversed on chain. Reconcile before re-sendingnone

An operation does not expire on its own. Past expires_at it still reads authorization_required, and it moves to expired only when you call authorize, which returns 400 operation_expired. Treat any operation past its expires_at as dead and create a new one.

failed and returned are not interchangeable. failed means the money never moved, so a retry is safe. returned means it moved and came back, so retrying blindly can send twice.

Not every status has a webhook. A conversion parked in requires_attention shows only on a GET, so poll any resource that stays in an intermediate status longer than you expect.