Purchase and recover
Create a purchase for one business order, then track its delivery. You need an API key, sufficient available balance, a Steam trade URL supplied by the recipient, and a durable order record in your system. Requests here spend real balance.
1. Choose a purchase method
| Method | Use when | Initial result |
|---|---|---|
POST /buy | You selected an item_id and process status asynchronously. | Accepted purchase; follow its state through REST or webhooks. |
POST /buy-sync | You selected an item and want to wait for the provider’s response. | Provider result, or a processing response when the wait ends. |
POST /buy-by-name | You want the server to try suitable offers for a market_hash_name. | Current/final attempt after a bounded search and retry cycle. |
These paths are relative to /api/v1/merchant. Provider acknowledgement is not Steam delivery.
The purchase reference defines the exact status codes and limits.
2. Save intent before sending the request
Create a stable custom_id from your business order ID and save it with the chosen method,
request fields, recipient trade URL, and approved max_price before the first POST.
Reuse that intent on every retry; generating a new ID can create another purchase.
max_price is your consent ceiling in USD. The purchase debits the actual item price, which
must fit under the ceiling. For example, an $18.40 item with max_price: 20 costs $18.40;
there is no initial $20 debit followed by a $1.60 refund.
The trade URL is required. target_steam_id is optional; if supplied, it must match the
URL’s partner. The minimal request example
omits it to avoid conflicting recipient fields.
3. Resolve an uncertain HTTP result
If the connection times out or a response is lost, do not assume the purchase failed.
Read GET /purchases?custom_id=YOUR_ORDER_ID
using the saved ID, URL-encoded, and follow pagination. A found purchase lets you resume tracking. An initial empty result
can race a request still in progress; retry with backoff and the same intent/ID if necessary.
For buy and buy-sync, repeating an accepted custom_id returns the existing purchase.
Response status and balance fields may reflect current state, so do not expect a byte-identical
response. For buy-by-name, a repeat while the original retry cycle is running may expose
its current attempt; a later attempt can have a different purchase_id. Use custom_id
for the business operation and retain each observed purchase ID for reconciliation.
Honor Retry-After on 429. Correct definitive validation/authentication errors before
retrying; see Errors. Never raise the price ceiling or change the
recipient as an automatic network-retry action.
4. Track delivery and later reversals
Use purchase status/history and signed webhooks to update your order. Durably accept incoming notifications and make their business effects idempotent. Events may repeat and arrive out of order.
purchase.completed means delivery completed. Continue accepting later reversal events,
including a protection rollback after completion. Reconcile conflicting notifications through
REST; occurred_at alone is not a sequence number. See the event catalog
and delivery recovery.