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

# Execution Types

> The one field your integration branches on.

RAVN spans three execution models. `POST /execute` returns exactly one of them, tagged by
`executionType`. Your integration reads that single field and branches. Nothing else about the
flow changes.

<CardGroup cols={3}>
  <Card title="TRANSACTION" icon="signature">
    Sign and broadcast the returned transaction.
    <br />**Across, Relay, Mayan, Eco Routes, THORChain, Jupiter, 0x Swap, 0x Solana, Nordstern, Fly Trade, KyberSwap, OKX DEX, Bebop (self-executed)**
  </Card>

  <Card title="SIGNATURE" icon="pen-nib">
    Sign typed data, with no gas and no send. RAVN submits it.
    <br />**0x Gasless, Bebop (gasless), CoW, Relay (gasless permit)**
  </Card>

  <Card title="DEPOSIT" icon="paper-plane">
    Send the origin asset to an address.
    <br />**NEAR Intents, Chainflip, Rift, Houdini Swap, Layerswap, Relay (BTC source)**
  </Card>
</CardGroup>

<Note>
  A few venues return different types depending on the source chain or execution mode. See the
  `Execution` column on [Supported Chains & Venues](/supported) for exactly which.
</Note>

## The payloads

<CodeGroup>
  ```json TRANSACTION theme={null}
  {
    "executionType": "TRANSACTION",
    "quoteToken": "...opaque...",
    "approval": { "to": "0x...", "data": "0x095ea7b3...", "value": "0", "chainId": 1 },
    "transaction": { "to": "0x...", "data": "0x...", "value": "0", "chainId": 1 }
  }
  ```

  ```json SIGNATURE theme={null}
  {
    "executionType": "SIGNATURE",
    "quoteToken": "...opaque...",
    "approval": { "to": "0x...", "data": "0x095ea7b3...", "value": "0", "chainId": 1 },
    "typedData": { },
    "approvalData": { },
    "submit": { "url": "/api/v1/submit-signature" }
  }
  ```

  ```json DEPOSIT theme={null}
  {
    "executionType": "DEPOSIT",
    "quoteToken": "...opaque...",
    "deposit": { "address": "0x...", "amount": "1000000000000000000", "chainId": 1 },
    "statusRef": "0x..."
  }
  ```
</CodeGroup>

Every payload carries a `quoteToken`. Pass **that** one, not the token from `/quote`, to
`/submit-signature` and `/status`: a two-hop RAVN route is rebound to its second hop at execute, and
`/submit-signature` refuses its original token.

## Branch logic

```mermaid theme={null}
flowchart TD
  E["POST /execute"] --> T{"executionType"}

  T -->|TRANSACTION| TA{"approval present?"}
  TA -->|yes| TA1["send approval,\nwait for receipt"] --> TA2["send transaction"]
  TA -->|no| TA2
  TA2 --> TR["poll /status with\nref = statusRef if present,\nelse your tx hash"]

  T -->|SIGNATURE| SA{"approval present?"}
  SA -->|yes| SA1["send approval,\nwait for receipt"] --> SA2["sign typedData"]
  SA -->|no| SA2
  SA2 --> SUB["POST /submit-signature"] --> SR["poll GET /status"]

  T -->|DEPOSIT| D1["send input asset\nto deposit address"] --> DR["poll GET /status\n(statusRef from /execute)"]
```

```js theme={null}
switch (res.data.executionType) {
  case "TRANSACTION": {
    if (res.data.approval) {
      const hash = await wallet.sendTransaction(res.data.approval);
      await wallet.waitForTransactionReceipt({ hash });  // must be mined first
    }
    const hash = await wallet.sendTransaction(res.data.transaction);
    await pollStatus(res.data.quoteToken, res.data.statusRef ?? hash);  // see below
    break;
  }
  case "SIGNATURE": {
    // Gasless still needs an allowance. Without it the order never fills, silently.
    if (res.data.approval) {
      const hash = await wallet.sendTransaction(res.data.approval);
      await wallet.waitForTransactionReceipt({ hash });
    }
    const sig = await wallet.signTypedData(res.data.typedData);
    await submitSignature(res.data.quoteToken, sig);  // execute's token, not /quote's
    break;
  }
  case "DEPOSIT":     await wallet.send(res.data.deposit.address, res.data.deposit.amount); break;
}
```

<Warning>
  **On `TRANSACTION`, the ref is the transaction hash you broadcast, unless `/execute` returned a
  `statusRef`: then use that.** Poll [`/status`](/api-reference/status) with it until a terminal
  state. This is not optional if you charge a fee: on same-chain venues (0x Swap, 0x Solana, Nordstern,
  Fly Trade, KyberSwap, OKX DEX, Jupiter, Mayan same-chain) RAVN only marks a swap settled, and only pays
  you on it, after it has verified that hash on-chain. A swap you never report never becomes
  payable. See [Settlement](/api-reference/status#settlement).
</Warning>

<Tip>
  On JavaScript or TypeScript, [`@ravnexchange/sdk`](/sdks/core)'s `executeAndTrack` already sequences all
  of this, including the approval wait below, given your own sign/send functions. The raw flow
  above is still the full contract for every other language.
</Tip>

### The `approval` step

Both `TRANSACTION` and `SIGNATURE` payloads can carry an optional `approval`, a ready-to-send
ERC-20 `approve()` call.

```json theme={null}
"approval": {
  "to": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",  // the TOKEN contract
  "data": "0x095ea7b3…",                                // encoded approve(spender, amount)
  "value": "0",
  "chainId": 8453,
  "spender": "0x337685fdaB40D39bd02028545a4FfA7D287cC3E2",
  "amount": "25000000",
  "unlimitedRecommended": true                          // optional, see below
}
```

| When it appears | When it does not |
| - | - |
| Selling an ERC-20 that needs an allowance for this venue | Selling a native coin (ETH, BNB, AVAX…) |
| Gasless venues too (they still pull tokens via `transferFrom`) | Native BTC or SOL as the input |
| | `DEPOSIT` routes |

**On `TRANSACTION`:** send `approval`, wait for it to be **mined**, then send `transaction`. The
swap moves your tokens with `transferFrom`, so an allowance that is merely broadcast, and not yet
in a block, still reverts, and the user pays gas for a failed transaction.

**On `SIGNATURE`:** land the allowance before you submit the signed order. Gasless does not mean
allowance-free: CoW settles through its vault relayer and Bebop through Permit2. Skip it and the
order is accepted and then **silently never fills**, with no error to debug.

Read the on-chain allowance for `spender` first and skip the approval when it already covers
`amount`. RAVN does not check the chain for you, so `approval` can be present on a token you
have already approved.

<Tip>
  `unlimitedRecommended: true` means the venue would rather you approve once for a large amount than
  per swap. It is set for CoW, whose relayer needs an on-chain allowance for every token regardless,
  so an exact approval costs gas on every single swap and cancels out the gasless route. `data` still
  encodes the exact `amount`; raising it to an unlimited approval is your call. Both work.
</Tip>

<Warning>
  Do not assume the spender is `transaction.to`, and do not decode the `quoteToken` to find it.
  The `quoteToken` is opaque and its internals change without notice. If `approval` is absent, no
  allowance is needed.
</Warning>

<Tip>
  A `DEPOSIT` can be fulfilled automatically, by building a wallet transfer to the address as an
  EVM or Solana wallet does, or manually, by showing the address and a QR code as a native-BTC
  send does. Both are the same execution type, so you choose the UX. RAVN's own app does the
  former for NEAR Intents, Rift, and Houdini Swap on EVM and Solana sources, so the user confirms
  one wallet transfer: native coin straight to the address, or an ERC-20 or SPL `transfer` of
  exactly `deposit.amount`, with no approval needed.
</Tip>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.