- Create a quote to lock the exchange rate and amounts.
- Commit the quote to execute the trade.
Prerequisites
Before creating trades:- The user must have completed onboarding.
- The user must have the
tradescapability enabled. - UK retail users must clear a mandatory 24-hour financial-promotion cooldown after onboarding before they can trade. Until it elapses,
POST /core/transactions/quotereturns409 user_capability_failurewithrestrictions: ["financial-promotion-cooldown-running"]— surface this state explicitly in your UI rather than treating it as a generic failure.
Walkthrough
Select the origin and destination accounts
A trade requires two accounts under the sameownerId:
- Origin account — the asset being sold.
- Destination account — the asset being purchased.
The origin account must have enough available balance to cover the trade.Only
balance.available can be traded. Funds that are still pending settlement (balance.total > balance.available) cannot be used.Create a quote
Create a quote to lock the exchange rate and determine the exact trade amounts. Specify the side you want to lock usingdenomination.target (origin or destination) and the amount using denomination.amount. Uphold calculates the corresponding amount on the opposite side.
The quote response indicates which side was locked through denomination.target:
| denomination.asset | denomination.target | Meaning |
|---|---|---|
origin.asset | origin | Sell exactly the specified amount of the origin asset |
destination.asset | destination | Buy exactly the specified amount of the destination asset |
Honor the quote expiration.Each quote is valid only until the
expiresAt timestamp in the response. Display the quote, collect the user’s confirmation, and commit before it expires.If the quote has expired, creating the transaction returns 404 entity_not_found. Create a new quote and ask the user to confirm again.Commit the quote
After the user accepts the quoted rate, commit the quote by creating a transaction. ThequoteId becomes the transactionId, allowing you to use a single identifier throughout the trade lifecycle.
Confirm settlement
Trades typically reach a final state within a few hundred milliseconds.Recommended: Webhooks
Subscribe to:core.transaction.status-changed
When the trade completes, you’ll receive a webhook containing the updated transaction status.
Alternative: Polling
Retrieve the transaction and poll until it reaches a terminal state.Trade transaction statuses
| Status | Meaning |
|---|---|
processing | Trade has been accepted and is being settled. This is the expected immediate state after commit. |
completed | Trade settled successfully and balances have been updated. |
failed | Trade could not be completed. Contact support and provide the transaction id. |
Notify the user
Once settlement completes:- Display a trade confirmation.
- Show both sides of the conversion.
- Refresh account balances.
Sold 100.00 USD and received 0.00154883 BTC.Refresh balances using Get account.
You now support asset-to-asset trades using the Uphold Enterprise API Suite.
Common errors
| Status | Code | Cause | Recommended action |
|---|---|---|---|
409 | user_capability_failure (restrictions: ["financial-promotion-cooldown-running"]) | UK retail user is still in the mandatory cooldown period. | Inform the user that trading becomes available after the cooldown expires. |
409 | user_capability_failure (capability.code: "trades") | User does not have the trades capability enabled. | Verify onboarding status and capability requirements. |
404 | entity_not_found (entity: "quote") | Quote expired or no longer exists. | Request a new quote and ask the user to confirm again. |
409 | insufficient_balance | Origin account does not have sufficient available funds. | Refresh balances and prompt the user to enter a lower amount. |