Trade Lifecycle
Every trade follows a state machine. Understanding the status transitions is critical for correctly handling callbacks and updating your users.Trade Statuses
| Status | Description |
|---|---|
initiated | Trade created. For deposits, the Steam offer has not been sent yet. For withdrawals, this is the approval gate — the merchant wallet has not been debited yet. |
pending | Withdrawals only. The supplier is sourcing the item / creating the purchase. |
active | Steam trade offer has been sent to the user — awaiting their acceptance. |
hold | User accepted and the items are in Steam’s hold window (typically 7 days). Carries offerID and holdEndDate. |
completed | Trade finished successfully (hold expired with no reversal). |
canceled | Trade was canceled before completion — admin/user cancel, or a deposit offer that was auto-canceled after sitting unaccepted past its window. |
declined | The end user actively declined (or let expire) the Steam trade offer. Deposits: no items received, no credit. Withdrawals: delivery didn’t happen; your merchant wallet is refunded minus a 2% buyer-decline penalty (capped at $9). |
failed | Trade failed at some point in the process (offer expired, merchant rejected the initiated callback, supplier purchase failed, error). |
reverted | A previously completed trade was reversed by the upstream supplier or the end user (see revertedBy). |
There is no
partial status. pending and active are emitted on withdrawals as the supplier sources the item and the Steam offer is sent. Statuses are atomic per trade — for multi-item withdrawals, each item carries its own status field but the trade-level status is always one of the values above.Deposit Status Flow
What triggers each transition:
- initiated → active: Steam trade offer sent to the user — sitting in their Steam inbox, awaiting acceptance
- initiated → failed / canceled: Bot dispatch failed or the trade was canceled before the offer left
- active → hold: User accepted, items received, Steam hold period started
- active → failed: Trade offer expired or the user’s account has restrictions
- active → declined: User actively declined the Steam trade offer
- active → canceled: Offer auto-canceled after sitting unaccepted past its window, or an admin/user canceled it
- hold → completed: 7-day hold ended, no reversal detected
- hold → failed: Items reversed by Steam during the hold period
- completed → reverted: Trade was reversed after completion (uncommon; check
revertedBy)
active ≠ “user accepted”. active means we sent the trade offer and it’s sitting in the user’s Steam inbox. The user-accepted moment is active → hold.Rust deposits skip the
hold step. Rust items don’t have a 7-day Steam protection window, so a successful Rust deposit transitions active → completed directly.Withdrawal Status Flow
What triggers each transition:
- initiated → pending: Merchant approved via the
initiatedcallback; AssetPay starts sourcing the item from the supplier - initiated → failed: Merchant rejected via callback (4xx response or rejection body), the merchant has no callback URL configured (
MERCHANT_NO_CALLBACK_URL), or the supplier purchase failed - initiated → canceled: Trade explicitly canceled before processing
- pending → active: Item sourced, Steam trade offer sent to the user — awaiting acceptance
- pending → failed: Supplier purchase could not be completed
- active → hold: User accepted the Steam trade offer, Steam hold period started
- active → failed: The Steam offer expired or the recipient’s account is restricted
- active → declined: The end user actively declined the Steam offer (your merchant wallet is refunded)
- hold → completed: 7-day hold ended, no reversal detected
- hold → failed: Items reversed by Steam during the hold period
- hold → reverted: Trade was reversed by the supplier or user during the hold period (check
revertedBy) - completed → reverted: Trade was reversed after the hold completed
A withdrawal moves
initiated → pending → active → hold → completed. Not every trade emits every intermediate status, so treat pending and active as progress signals and drive balance changes off initiated (deduct) and the terminal states.Rust withdrawals normally skip the
hold step. Rust items have no 7-day reversal-protection window, so a successful Rust withdrawal usually transitions active → completed directly, with no holdEndDate. The exception is a Steam security escrow (recipient has no mobile authenticator), which surfaces as hold. CS2 withdrawals always go through hold, which carries offerID + holdEndDate.The 7-Day Hold
Steam enforces a 7-day reversal window on CS2 trades. During this window, items can be clawed back. This affects how you should handle balance credits. TheholdEndDate field on the trade object tells you exactly when the hold expires.
Without instant deposits:
Don’t credit any balance until completed. Simple and safe.
With instant deposits (recommended):
When a deposit enters hold, the trade includes:
preCredit: amount to credit immediately (calculated from collateral)pendingCredit: remaining amount to credit after the hold
preCredit on hold, then credit pendingCredit on completed. If the trade gets reverted, reverse both.
Rust deposits skip the hold entirely — credit the full amount on completed.
Terminal States
These statuses are final and won’t change:completed: The trade is done. Balance has been settled. (Can still transition torevertedif Steam reverses the trade afterward.)canceled: The trade was canceled before processing started. No balance settlement.declined: The end user declined the trade offer. Deposits: no items received, no settlement. Withdrawals: delivery didn’t happen — your merchant wallet is auto-refunded minus a 2% buyer-decline penalty (capped at $9), so this refunds slightly less thanfailed.failed: The trade didn’t go through. For withdrawals where you previously deducted the user’s balance, refund it.reverted: The trade was reversed after being settled. CheckrevertedByto understand who initiated it.
The revertedBy Field
When a trade reaches reverted, the revertedBy field tells you who caused it:
| Value | Meaning |
|---|---|
supplier | The marketplace supplier reversed the trade (withdrawals only) |
user | The end user reversed the trade |
revertedBy is set to user in that case. For withdrawals, either party can reverse after acceptance.
Bot Info
During certain stages, the trade object includesbotInfo with details about the Steam bot handling the trade:
Recommended UI Mapping
You probably don’t want to expose all internal statuses to your users. Here’s a suggested mapping:| Internal Status | User-facing Label | Description to Show |
|---|---|---|
initiated | Processing | Your trade is being set up |
pending | Processing | Sourcing your item |
active | In Progress | Trade offer sent, waiting for you to accept it |
hold | Held (7 days) | Item held for Steam’s protection period |
completed | Completed | Trade finished |
canceled | Cancelled | Trade was cancelled before processing |
declined | Declined | You declined the trade offer |
failed | Failed | Trade didn’t go through |
reverted | Reversed | Trade was reversed |