Prerequisites
- An API key from the Portal. All requests require the
x-api-keyheader. - A Solana wallet. Every step that moves funds (deposit, withdrawal) is signed client-side by the wallet owner.
Integration at a Glance
A trigger order moves through authentication, a one-time vault setup, the deposit-and-create flow, then monitoring and an optional cancel-and-withdraw. The key to integrating is the data hand-off: each call produces the value the next call needs.https://api.jup.ag/trigger/v2.
Step by Step
1. Authenticate
CallPOST /auth/challenge with your walletPubkey and a type of message (standard wallets) or transaction (hardware wallets). Sign the returned challenge, then submit it to POST /auth/verify to receive a JWT token. Include the token as Authorization: Bearer <token> on every subsequent call.
The token is valid for 24 hours. There is no refresh endpoint: when it expires, repeat the challenge-response flow.
See Authentication for the message and transaction flows and the full token lifecycle.
2. Get or register your vault
CallGET /vault to resolve your vault, or GET /vault/register on first use. The vault is a Privy-managed custodial account that holds deposits for your orders. The vault address is resolved from your JWT, so you do not pass it into later calls.
See Create Order.
3. Craft and sign a deposit
CallPOST /deposit/craft with the input/output mints, amount, orderType: "price", and the orderSubType that matches the order you will create (single, oco, or otoco). It returns an unsigned transaction and a requestId. Sign the transaction client-side to produce depositSignedTx.
The API stores the deposit’s token accounts against the requestId, so you carry only the requestId and depositSignedTx into the next step.
See Create Order.
4. Create the order
CallPOST /orders/price with depositRequestId, depositSignedTx, and your order parameters. The orderType determines which fields are required:
| Order type | Behaviour |
|---|---|
single | One price order that triggers when triggerMint crosses the target price |
oco | A take-profit and stop-loss pair sharing one deposit. When one side fills, the other cancels |
otoco | A parent trigger that, once filled, activates an OCO pair on the output tokens |
id (the ocoId, your primary identifier for the order or group) and a txSignature confirming the deposit landed. The order is now active.
See Create Order.
5. Monitor order state
CallGET /orders/history to track an order through its lifecycle. Each order carries an orderState (human-friendly) and rawState (exact internal state), plus an events array of deposits, fills, withdrawals, cancellations, and expirations.
See Order History and the Order State Lifecycle below.
6. Update or cancel
While an order isopen you can:
- Update it in place with
PATCH /orders/price/{id}to change the trigger price, slippage, or expiry. No new deposit is needed. - Cancel it with
POST /orders/price/cancel/{id}, which returns a withdrawal transaction to sign.
7. Confirm cancellation
Sign the withdrawal transaction from step 6 and submit it toPOST /orders/price/confirm-cancel/{id} with the cancelRequestId. This returns the funds to your wallet and moves the order to cancelled.
See Cancellation and Recovery for what happens if this step is interrupted.
Order State Lifecycle
An order moves through a state machine from creation to completion.GET /orders/history reports both an orderState (display) and a rawState (internal). The high-level flow:
openorders can be updated or cancelled. Updates and cancellation are only valid from this state.executingcovers the swap from trigger detection to output withdrawal, including partial fills.expiredorders did not fill beforeexpiresAt. The deposit is still in the vault and is retrieved with the same cancel flow (see below).
cancelled automatically (shown as oco_cancelled in the raw state).
OTOCO orders: the child OCO pair only activates after the parent order reaches filled. If the parent expires or fails, the children are never created.
For the complete orderState ↔ rawState mapping and the events schema, see Order History.
Cancellation and Recovery
Cancellation is a two-step process designed so funds are never at risk mid-flow:- Initiate with
POST /orders/price/cancel/{id}. The order moves fromopentoready_to_cancel(display:pending_withdraw) immediately, so it can no longer be filled. The call returns an unsigned withdrawal transaction and acancelRequestId. - Confirm by signing that transaction and submitting it to
POST /orders/price/confirm-cancel/{id}. The funds return to your wallet and the order becomescancelled.
ready_to_cancel: fills are stopped and the deposit remains in the vault.
If the second step is interrupted (the tab closes, or the transaction does not land):
- You still have the withdrawal transaction and
cancelRequestId: retryPOST /orders/price/confirm-cancel/{id}with the samecancelRequestId. - You lost the withdrawal transaction: call
POST /orders/price/cancel/{id}again. The order is already inready_to_cancel, so the call simply crafts and returns a fresh withdrawal transaction to sign.
ready_to_cancel until a withdrawal confirms on-chain, so funds are never stranded.expired order: initiate cancellation, sign, and confirm.
Related
Authentication
Challenge-response signing and the JWT token lifecycle.
Create Order
The vault, deposit, and order-creation request shapes.
Manage Orders
Update orders and the two-step cancel-and-withdraw flow.
Order History
Full order state mapping and the events schema.
Best Practices
Expiry, slippage, and integration guidance.
API Reference
Full endpoint specifications.
