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

# Integration patterns

> When to use the two-step /quote + /submit flow versus the one-step /execute call.

The DEX Aggregator API supports two integration shapes. They produce equivalent on-chain transactions; the difference is when the routing engine runs.

<CardGroup cols={2}>
  <Card title="Two-step" icon="layer-group">
    `/quote` → human reviews price → `/submit` → broadcast.

    Best for swap UIs.
  </Card>

  <Card title="One-step" icon="bolt">
    `/execute` → broadcast.

    Best for one-click flows and bots.
  </Card>
</CardGroup>

## Two-step (recommended for swap UIs)

Use this flow when a user reviews the quoted price before they commit.

```mermaid theme={null} theme={null}
sequenceDiagram
  participant U as User
  participant C as Client
  participant A as o1 API
  participant W as Wallet
  participant R as Router

  U->>C: Pick tokens, enter amount
  C->>A: POST /quote
  A-->>C: quoteId + routePlan
  C->>U: Display price + route
  U->>C: Click "Swap"
  C->>A: POST /submit (quoteId, user)
  A-->>C: { to, data, value }
  C->>W: sendTransaction
  W->>R: swapExactIn(...)
  R-->>W: tx hash
```

```ts theme={null} theme={null}
// 1. Quote
const quote = await fetch(`${API_URL}/quote`, {
  method: "POST",
  headers: { "x-api-key": API_KEY, "content-type": "application/json" },
  body: JSON.stringify({
    chainId: 8453,
    tokenIn: USDC,
    tokenOut: WETH,
    amountIn: "1000000000",
    slippageBps: 100,
  }),
}).then((r) => r.json());

// 2. Display to user
showQuote({
  output: formatUnits(BigInt(quote.routePlan.expectedAmountOut), 18),
  minOutput: formatUnits(BigInt(quote.routePlan.minAmountOut), 18),
  route: quote.routePlan.routes
    .map((r) => r.legs.map((l) => l.dex).join(" → "))
    .join(" | "),
  fee: `${(quote.routePlan.feeBps ?? 0) / 100}%`,
});

// 3. User clicks "Swap" → build tx
const submit = await fetch(`${API_URL}/submit`, {
  method: "POST",
  headers: { "x-api-key": API_KEY, "content-type": "application/json" },
  body: JSON.stringify({
    quoteId: quote.quoteId,
    user: walletAddress,
  }),
}).then((r) => r.json());

// 4. Send to wallet
const txHash = await walletClient.sendTransaction({
  to: submit.to as `0x${string}`,
  data: submit.data as `0x${string}`,
  value: BigInt(submit.value),
});
```

### Pros

* User confirms the price they see; no last-second surprise.
* You can run validation between quote and submit (e.g. "is this trade > \$X? require a confirm dialog").
* Clean separation between read (quote) and write (submit) for caching, analytics, and rate limiting.

### Cons

* Quotes have a TTL (\~10 seconds). If the user takes too long, `/submit` returns `404` and you must re-quote. See [Quote freshness](/api/dex-aggregator/guides/quote-freshness).
* Two API calls per swap.

***

## One-step (instant swap)

Use this flow when there's no preview step.

```mermaid theme={null} theme={null}
sequenceDiagram
  participant C as Client
  participant A as o1 API
  participant W as Wallet
  participant R as Router

  C->>A: POST /execute
  A-->>C: routePlan + { to, data, value }
  C->>W: sendTransaction
  W->>R: swapExactIn(...)
  R-->>W: tx hash
```

```ts theme={null} theme={null}
const exec = await fetch(`${API_URL}/execute`, {
  method: "POST",
  headers: { "x-api-key": API_KEY, "content-type": "application/json" },
  body: JSON.stringify({
    chainId: 8453,
    tokenIn: USDC,
    tokenOut: WETH,
    amountIn: "1000000000",
    slippageBps: 100,
    user: walletAddress,
  }),
}).then((r) => r.json());

const txHash = await walletClient.sendTransaction({
  to: exec.to as `0x${string}`,
  data: exec.data as `0x${string}`,
  value: BigInt(exec.value),
});
```

### Pros

* Single round trip.
* No `quoteId` to track, no expiry to handle.

### Cons

* The user (or bot) doesn't see the price before signing. If you still want to show it, log `exec.routePlan.expectedAmountOut` after the fact.
* Less flexibility for caching and analytics, since each call rebuilds the full route plan server-side.

***

## Choosing the right pattern

| Use case                                      | Pattern                          |
| --------------------------------------------- | -------------------------------- |
| Standard swap UI with confirm dialog          | Two-step                         |
| One-click "swap now" button                   | One-step                         |
| Server-side market-maker / bot                | One-step                         |
| Limit-order style flow with delayed execution | Two-step (re-quote on each tick) |
| Mobile UI with poor connectivity              | One-step (fewer round trips)     |

<Tip>
  Even when you use `/execute` for the user-facing call, you can still hit `/quote` separately for live price display in the modal. Just be aware they consume separate rate-limit budget.
</Tip>

## Always: handle expired quotes

Whichever pattern you pick, treat `404 quote not found or expired` from `/submit` as recoverable: re-fetch `/quote` with the same parameters and retry. Don't surface this as a user-facing error unless it happens repeatedly.

See [Quote freshness](/api/dex-aggregator/guides/quote-freshness) for the full pattern.
