> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobula.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Triggers

> Create Solana trigger orders with Mobula Advanced Orders. Execute swaps from Token Details conditions such as volume, holders, liquidity, security flags, and token metadata.

<Warning>
  **Alpha feature**: Advanced Order Triggers are gated and not publicly available yet. Reach out to the Mobula team to enable access for your account.
</Warning>

Trigger Advanced Orders execute when a Token Details condition becomes true, then quote and route the swap through Mobula. Use them for token security checks, liquidity thresholds, volume conditions, holder concentration limits, metadata checks, or custom automated trading rules based on `getTokenData`.

Mobula confirms the trigger through Token Details first, then builds a fresh swap quote and still enforces `minAmountOutRaw` before sending.

## POST / GET

| Method | Path                                          | Purpose                                       |
| ------ | --------------------------------------------- | --------------------------------------------- |
| `POST` | `/api/2/swap/advanced-orders/intent`          | Build the canonical intent message to sign.   |
| `POST` | `/api/2/swap/advanced-orders`                 | Create the signed order.                      |
| `GET`  | `/api/2/swap/advanced-orders`                 | List owner orders. Requires a read signature. |
| `GET`  | `/api/2/swap/advanced-orders/:orderId`        | Read one order. Requires a read signature.    |
| `POST` | `/api/2/swap/advanced-orders/:orderId/cancel` | Cancel an open or triggered order.            |

## End-to-End Flow

Advanced Orders are deposit-backed intents. The user keeps custody of their wallet keys and never gives Mobula a reusable approval, session key, or delegated signing power. The only funds Mobula can execute with are the exact tokens the user transfers to the Mobula deposit wallet for that order.

<Note>
  The deposited amount is held in the Mobula deposit wallet while the order is open. If the order is cancelled, expires, or cannot execute, the settlement flow refunds the confirmed deposit to the owner.
</Note>

| Step | Actor                   | What happens                                                                                                                                                                                                                |
| ---- | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 1    | Integrator              | Use the Mobula-provided deposit wallet for the environment. The end user must not choose this address.                                                                                                                      |
| 2    | User wallet             | Transfer exactly `amountRaw` of `tokenIn` from `ownerAddress` to the Mobula deposit wallet.                                                                                                                                 |
| 3    | Client                  | Call `POST /api/2/swap/advanced-orders/intent` with the deposit transaction hash and all order parameters.                                                                                                                  |
| 4    | Mobula API              | Normalizes the payload, resolves the server deposit wallet, validates addresses and amounts, then returns the canonical `message` to sign.                                                                                  |
| 5    | User wallet             | Signs the canonical `message`. This signature covers the chain, owner, recipient, tokens, amounts, trigger settings, expiry, deposit transaction, routing restrictions, and fees.                                           |
| 6    | Client                  | Call `POST /api/2/swap/advanced-orders` with the same fields plus `intentSignature`.                                                                                                                                        |
| 7    | Mobula API              | Verifies the owner signature and stores the order idempotently by intent hash.                                                                                                                                              |
| 8    | Mobula worker           | Polls open orders every few seconds and verifies the deposit transaction on-chain. The deposit must be finalized, successful, sent by `ownerAddress`, sent to the Mobula deposit wallet, and match `tokenIn` + `amountRaw`. |
| 9    | Mobula worker           | Watches `swaps-stream` for relevant token/pair updates. For TP/SL it pre-checks quote movement; for Triggers it confirms the configured Token Details fields through `getTokenData`.                                        |
| 10   | Mobula execution engine | Claims the order, builds a fresh quote with the order constraints, checks `minAmountOutRaw`, signs only the swap transaction for the deposit wallet, and broadcasts it.                                                     |
| 11   | Mobula settlement       | Confirms the broadcasted transaction. If filled, output funds are sent to `recipientAddress`. If cancelled, expired, or non-executable, the confirmed deposit is refunded to `ownerAddress`.                                |

## Non-Custodial Guarantees

| Guarantee                                    | How it is enforced                                                                                                                          |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| Mobula cannot trade from the user's wallet   | The user only signs an intent message, not a transaction spending future wallet balances.                                                   |
| Mobula cannot mutate the order after signing | The canonical message includes the full order payload. Changing any signed field changes the intent hash and invalidates the signature.     |
| Mobula cannot use a different deposit        | Deposit verification checks the exact finalized transfer: owner, deposit wallet, token, and raw amount.                                     |
| Mobula cannot bypass the output guard        | Execution always checks the fresh quote against `minAmountOutRaw` before sending.                                                           |
| The user can exit before execution           | The owner can cancel open/triggered orders with a signed cancel message. Confirmed deposits are then handled by the refund settlement flow. |

## Client Checklist

1. Build and send the token transfer to the Mobula deposit wallet.
2. Wait for the deposit transaction signature.
3. Call `POST /advanced-orders/intent`.
4. Ask the owner wallet to sign `data.message`.
5. Call `POST /advanced-orders` with `intentSignature`.
6. Poll `GET /advanced-orders` or `GET /advanced-orders/:orderId`.
7. To cancel, sign the canonical cancel message and call `POST /advanced-orders/:orderId/cancel`.

## Trigger Order Model

```ts theme={null}
type AdvancedOrderTriggerOperator =
  | "equals"
  | "not"
  | "gt"
  | "gte"
  | "lt"
  | "lte"
  | "in"
  | "contains"
  | "startsWith"
  | "endsWith"
  | "exists";

type AdvancedOrderFieldTrigger = {
  token?: "in" | "out"; // defaults to "in"
  field: string;
  operator: AdvancedOrderTriggerOperator;
  value?: string | number | boolean | null | Array<string | number | boolean | null>;
};

type AdvancedOrderTriggerExpression =
  | AdvancedOrderFieldTrigger
  | { all: AdvancedOrderTriggerExpression[] }
  | { any: AdvancedOrderTriggerExpression[] }
  | { not: AdvancedOrderTriggerExpression };
```

No `source` field is used. A trigger can only reference fields returned by Token Details for `tokenIn` or `tokenOut`.

## Supported Token Details Fields

Use top-level fields returned by `GET /api/2/token/details`, plus the explicit `security.*` fields below.

| Category          | Fields                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Identity          | `address`, `chainId`, `symbol`, `name`, `decimals`, `id`, `tokenType`                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| Price / liquidity | `priceUSD`, `priceToken`, `approximateReserveUSD`, `approximateReserveToken`, `liquidityUSD`, `liquidityMaxUSD`, `marketCapUSD`, `marketCapDilutedUSD`                                                                                                                                                                                                                                                                                                                                                         |
| Price change      | `priceChange1minPercentage`, `priceChange5minPercentage`, `priceChange1hPercentage`, `priceChange4hPercentage`, `priceChange6hPercentage`, `priceChange12hPercentage`, `priceChange24hPercentage`                                                                                                                                                                                                                                                                                                              |
| Volume            | `volume1minUSD`, `volume5minUSD`, `volume15minUSD`, `volume1hUSD`, `volume4hUSD`, `volume6hUSD`, `volume12hUSD`, `volume24hUSD`, `volumeBuy*USD`, `volumeSell*USD`                                                                                                                                                                                                                                                                                                                                             |
| Trades            | `trades*`, `buys*`, `sells*`, `buyers*`, `sellers*`, `traders*` for supported timeframes                                                                                                                                                                                                                                                                                                                                                                                                                       |
| Organic           | `organicTrades*`, `organicVolume*USD`, `organicBuys*`, `organicSells*`, `organicBuyers*`, `organicSellers*`, `organicTraders*`                                                                                                                                                                                                                                                                                                                                                                                 |
| Fees / trending   | `feesPaid*USD`, `totalFeesPaidUSD`, `trendingScore*`, `surgeScore`                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| Holders           | `holdersCount`, `top10HoldingsPercentage`, `top50HoldingsPercentage`, `top100HoldingsPercentage`, `top200HoldingsPercentage`, `devHoldingsPercentage`, `insidersHoldingsPercentage`, `bundlersHoldingsPercentage`, `snipersHoldingsPercentage`                                                                                                                                                                                                                                                                 |
| Token state       | `bonded`, `bondingPercentage`, `bondingCurveAddress`, `poolAddress`, `source`, `factory`, `sourceFactory`, `deployer`, `createdAt`, `latestTradeDate`, `bondedAt`                                                                                                                                                                                                                                                                                                                                              |
| Social / listing  | `socials.twitter`, `socials.website`, `socials.telegram`, `twitterReusesCount`, `twitterRenameCount`, `dexscreenerListed`, `dexscreenerAdPaid`, `dexscreenerSocialPaid`, `dexscreenerBoosted`                                                                                                                                                                                                                                                                                                                  |
| Security          | `security.buyTax`, `security.sellTax`, `security.transferTax`, `security.transferPausable`, `security.top10Holders`, `security.isBlacklisted`, `security.isHoneypot`, `security.isNotOpenSource`, `security.renounced`, `security.locked`, `security.isWhitelisted`, `security.balanceMutable`, `security.lowLiquidity`, `security.burnRate`, `security.isMintable`, `security.modifyableTax`, `security.selfDestruct`, `security.liquidityBurnPercentage`, `security.noMintAuthority`, `security.isFreezable` |

<Note>
  Fields that are not returned by `getTokenData` are not accepted. This excludes `pool.*` filters, Pulse aliases, and Token Filters-only fields that do not exist in Token Details.
</Note>

## Trigger Intent Body

```json theme={null}
{
  "chainId": "solana:solana",
  "ownerAddress": "<OWNER>",
  "recipientAddress": "<OWNER>",
  "tokenIn": "<TOKEN_MINT>",
  "tokenOut": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "amountRaw": "1000000000",
  "minAmountOutRaw": "830000",
  "triggerAmountOutRaw": "1",
  "triggerDirection": "gte",
  "orderKind": "limit",
  "slippage": 2,
  "depositTransactionHash": "<DEPOSIT_TX_SIGNATURE>",
  "expiresAt": "2026-08-01T00:00:00.000Z",
  "onlyRouters": ["mobula"],
  "triggers": {
    "all": [
      { "field": "volume24hUSD", "operator": "gte", "value": 10000 },
      { "field": "security.noMintAuthority", "operator": "equals", "value": true },
      { "field": "security.isFreezable", "operator": "equals", "value": false }
    ]
  }
}
```

`triggerAmountOutRaw` and `triggerDirection` remain required for compatibility, but when `triggers` is present the trigger condition is the `triggers` expression. `minAmountOutRaw` remains the final quote guard.

## Create a Trigger Order

```ts theme={null}
const intent = await fetch("https://api.mobula.io/api/2/swap/advanced-orders/intent", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": "<YOUR_API_KEY>",
  },
  body: JSON.stringify(intentBody),
}).then((res) => res.json());

const intentSignature = await wallet.signMessage(intent.data.message);

await fetch("https://api.mobula.io/api/2/swap/advanced-orders", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "x-api-key": "<YOUR_API_KEY>",
  },
  body: JSON.stringify({ ...intentBody, intentSignature }),
});
```

## Read

```bash theme={null}
curl "https://api.mobula.io/api/2/swap/advanced-orders?ownerAddress=<OWNER>&readSignature=<SIGNATURE>" \
  -H "x-api-key: <YOUR_API_KEY>"
```
