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

# Creating Swap Orders

> How to create market orders using the CoW Protocol SDK's postSwapOrder method

# Creating Swap Orders

Swap orders are market orders that automatically fetch a quote and create an order in one step. The SDK handles all the complexity of parameters, calculations, and signing.

## Prerequisites

Before creating a swap order, make sure the following conditions are met:

* **Token approval**: The sell token must be approved to the CoW Protocol Vault Relayer contract before the order can settle. Without approval, solvers cannot pull tokens from your wallet. See [Token Approvals](/cow-sdk/guides/token-approvals) for full details.
* **Sufficient balance**: Your wallet must hold enough of the sell token to cover the trade amount.
* **Buy order amounts**: For buy orders, the actual sell amount will be higher than the raw exchange rate because it includes protocol fees and slippage tolerance. Always check the quote's `amountsAndCosts` to see the real cost.

Use the check-and-approve pattern before posting an order:

```typescript theme={null}
// Check current allowance
const allowance = await sdk.getCowProtocolAllowance({ tokenAddress: sellToken, owner })

// Approve if needed
if (allowance < requiredAmount) {
  await sdk.approveCowProtocol({ tokenAddress: sellToken, amount: requiredAmount })
}
```

<Warning>
  If you skip the approval step, the order will be created successfully but solvers will not be able to settle it. The order will eventually expire unfilled.
</Warning>

## Basic Flow

The basic trading flow consists of three steps:

<Steps>
  <Step title="Get a quote (price) for a trade">
    The SDK fetches the current market price from the CoW Protocol API
  </Step>

  <Step title="Sign the order">
    Sign the order using EIP-712 signature
  </Step>

  <Step title="Post the order to the order-book">
    Submit the signed order to the CoW Protocol order book
  </Step>
</Steps>

## Using postSwapOrder

The `postSwapOrder` method combines all three steps into one convenient function.

### Required Parameters

* `kind` - The order kind (`OrderKind.SELL` or `OrderKind.BUY`)
* `sellToken` - The sell token address
* `sellTokenDecimals` - The sell token decimals
* `buyToken` - The buy token address
* `buyTokenDecimals` - The buy token decimals
* `amount` - The amount to sell/buy in atoms (smallest unit)

### Example

<CodeGroup>
  ```typescript Viem Adapter theme={null}
  import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/sdk-trading'
  import { ViemAdapter } from '@cowprotocol/sdk-viem-adapter'
  import { createPublicClient, http, privateKeyToAccount } from 'viem'
  import { sepolia } from 'viem/chains'

  const adapter = new ViemAdapter({
    provider: createPublicClient({
      chain: sepolia,
      transport: http('YOUR_RPC_URL')
    }),
    signer: privateKeyToAccount('YOUR_PRIVATE_KEY' as `0x${string}`)
  })

  const sdk = new TradingSdk(
    {
      appCode: 'YOUR_APP_CODE',
    },
    {
      chainId: SupportedChainId.SEPOLIA,
    },
    adapter,
  )

  const parameters: TradeParameters = {
    kind: OrderKind.BUY,
    sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
    sellTokenDecimals: 18,
    buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
    buyTokenDecimals: 18,
    amount: '120000000000000000',
  }

  const { orderId } = await sdk.postSwapOrder(parameters)

  console.log('Order created, id: ', orderId)
  ```

  ```typescript Ethers v6 theme={null}
  import { SupportedChainId, OrderKind, TradeParameters, TradingSdk } from '@cowprotocol/sdk-trading'
  import { EthersV6Adapter } from '@cowprotocol/sdk-ethers-v6-adapter'
  import { ethers } from 'ethers'

  const provider = new ethers.JsonRpcProvider('YOUR_RPC_URL')
  const signer = new ethers.Wallet('YOUR_PRIVATE_KEY', provider)

  const adapter = new EthersV6Adapter({ provider, signer })

  const sdk = new TradingSdk(
    {
      chainId: SupportedChainId.SEPOLIA,
      appCode: 'YOUR_APP_CODE',
    },
    {},
    adapter,
  )

  const parameters: TradeParameters = {
    kind: OrderKind.BUY,
    sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
    sellTokenDecimals: 18,
    buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
    buyTokenDecimals: 18,
    amount: '120000000000000000',
  }

  const { orderId } = await sdk.postSwapOrder(parameters)

  console.log('Order created, id: ', orderId)
  ```
</CodeGroup>

## Optional Parameters

You can customize your swap order with these optional parameters:

| Parameter           | Type         | Default        | Description                                                       |
| ------------------- | ------------ | -------------- | ----------------------------------------------------------------- |
| `env`               | `Env`        | `prod`         | The environment to use (`prod` or `staging`)                      |
| `partiallyFillable` | `boolean`    | `false`        | Whether the order can be partially filled                         |
| `slippageBps`       | `number`     | 50             | Slippage tolerance in basis points (BPS). One basis point = 0.01% |
| `receiver`          | `string`     | order creator  | The address that will receive the tokens                          |
| `validFor`          | `number`     | 1800 (30 mins) | Order expiration time in seconds                                  |
| `partnerFee`        | `PartnerFee` | -              | Partner fee configuration (fee in BPS and recipient address)      |

### Example with Optional Parameters

```typescript theme={null}
const parameters: TradeParameters = {
  kind: OrderKind.BUY,
  sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
  sellTokenDecimals: 18,
  buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
  buyTokenDecimals: 18,
  amount: '120000000000000000',
  // Optional parameters
  slippageBps: 200, // 2% slippage
  validFor: 1200, // 20 minutes
  receiver: '0xdef1ca1fb7f1232777520aa7f396b4e015f497ab',
  partiallyFillable: true,
}

const { orderId } = await sdk.postSwapOrder(parameters)
```

<Note>
  Slippage is expressed in basis points (BPS). For example:

  * 50 BPS = 0.5%
  * 100 BPS = 1%
  * 200 BPS = 2%
</Note>

## Advanced Settings

For more control over the order creation process, use `SwapAdvancedSettings`:

### Quote Request Customization

```typescript theme={null}
import { SwapAdvancedSettings, PriceQuality } from '@cowprotocol/sdk-trading'

const advancedSettings: SwapAdvancedSettings = {
  quoteRequest: {
    priceQuality: PriceQuality.FAST,
    validFor: 120,
  },
}

const { orderId } = await sdk.postSwapOrder(parameters, advancedSettings)
```

### Adding Hooks

You can add pre-hooks that execute before your order is settled:

```typescript theme={null}
const advancedSettings: SwapAdvancedSettings = {
  appData: {
    hooks: {
      version: 1,
      pre: [
        {
          target: '0xdef1ca1fb7fbcdc777520aa7f396b4e015f497ab',
          callData: '0x70a08231000000000000000000000000d8da6bf26964af9d7eed9e03e53415d37aa96045',
          gasLimit: 21000,
        },
      ],
    },
  },
}

const { orderId } = await sdk.postSwapOrder(parameters, advancedSettings)
```

## Two-Step Process: getQuote + postSwapOrderFromQuote

If you want to show the quote to users before creating an order, use the two-step approach:

```typescript theme={null}
// Step 1: Get quote
const { quoteResults, postSwapOrderFromQuote } = await sdk.getQuote(parameters)

const buyAmount = quoteResults.amountsAndCosts.afterSlippage.buyAmount

console.log(`You will get at least: ${buyAmount}`)

// Show quote to user and wait for confirmation
if (confirm(`You will get at least: ${buyAmount}, ok?`)) {
  // Step 2: Create order from quote
  const orderId = await postSwapOrderFromQuote()

  console.log('Order created, id: ', orderId)
}
```

### Quote Results

The `quoteResults` object contains:

* `tradeParameters` - Trade type, assets, amounts and optional parameters
* `amountsAndCosts` - Order sell/buy amounts including network costs, fees and slippage
* `orderToSign` - Order parameters ready for signing
* `quoteResponse` - Raw DTO from the Quote API
* `appDataInfo` - Order's metadata
* `orderTypedData` - EIP-712 typed data for signing

<Warning>
  Quotes are time-sensitive and typically valid for 30 minutes. Make sure to post the order within the validity period.
</Warning>

## Order Kinds

The SDK supports two order kinds:

<Tabs>
  <Tab title="SELL Orders">
    **Sell orders** specify the exact amount you want to sell:

    ```typescript theme={null}
    const parameters: TradeParameters = {
      kind: OrderKind.SELL,
      sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
      sellTokenDecimals: 18,
      buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
      buyTokenDecimals: 18,
      amount: '1000000000000000000', // Selling exactly 1 token
    }
    ```

    You'll receive at least the quoted buy amount (minus slippage).
  </Tab>

  <Tab title="BUY Orders">
    **Buy orders** specify the exact amount you want to buy:

    ```typescript theme={null}
    const parameters: TradeParameters = {
      kind: OrderKind.BUY,
      sellToken: '0xfff9976782d46cc05630d1f6ebab18b2324d6b14',
      sellTokenDecimals: 18,
      buyToken: '0x0625afb445c3b6b7b929342a04a22599fd5dbb59',
      buyTokenDecimals: 18,
      amount: '1000000000000000000', // Buying exactly 1 token
    }
    ```

    You'll pay at most the quoted sell amount (plus slippage).
  </Tab>
</Tabs>

## After Order Creation

Once `postSwapOrder` returns successfully, the order has been signed and submitted to the CoW Protocol order book. Here is what happens next:

1. **Solvers compete**: The order enters the CoW Protocol auction where solvers compete to find the best execution path for your trade.
2. **Settlement**: The winning solver settles the order on-chain, transferring tokens between parties.
3. **Surplus**: If solvers find a better price than your limit, the surplus goes back to you.

### Checking Order Status

Use the order UID returned by `postSwapOrder` to check the current status:

```typescript theme={null}
const order = await sdk.getOrder({ orderUid: orderId })

console.log('Status:', order.status)
```

Order status values:

| Status                | Meaning                                                        |
| --------------------- | -------------------------------------------------------------- |
| `open`                | Order is in the order book, waiting to be filled               |
| `fulfilled`           | Order has been fully executed on-chain                         |
| `cancelled`           | Order was cancelled by the owner                               |
| `expired`             | Order passed its `validTo` timestamp without being filled      |
| `presignaturePending` | Order requires an on-chain pre-signature (smart contract flow) |

### Polling for Completion

If you need to wait for the order to fill:

```typescript theme={null}
const { orderId } = await sdk.postSwapOrder(parameters)

const pollInterval = 5000 // 5 seconds

const checkOrder = async () => {
  const order = await sdk.getOrder({ orderUid: orderId })

  if (order.status === 'fulfilled') {
    console.log('Order filled! TX hash:', order.executedTransactionHash)
    return
  }

  if (order.status === 'cancelled' || order.status === 'expired') {
    console.log('Order did not fill. Status:', order.status)
    return
  }

  console.log('Order still open, checking again...')
  setTimeout(checkOrder, pollInterval)
}

checkOrder()
```

### Cancelling an Order

If you need to cancel a pending order, use off-chain cancellation:

```typescript theme={null}
await sdk.offChainCancelOrder({ orderUid: orderId })

console.log('Order cancelled')
```

<Note>
  Off-chain cancellation asks solvers to stop filling the order. It takes effect almost immediately but is not enforced on-chain. For guaranteed cancellation of smart contract orders, see [Order Management](/cow-sdk/guides/order-management).
</Note>

## Pre-Flight Checklist

Before calling `postSwapOrder`, verify:

* Sell token approved to the Vault Relayer contract
* Wallet has sufficient sell token balance
* Token addresses are correct for the target chain
* Amount is in the token's smallest unit (atoms, e.g. wei for 18-decimal tokens)
* `slippageBps` is set appropriately (default 50 = 0.5%)

## Troubleshooting

Common issues when creating swap orders:

| Problem                        | Likely Cause                                   | Fix                                                      |
| ------------------------------ | ---------------------------------------------- | -------------------------------------------------------- |
| `InsufficientAllowance` error  | Sell token not approved to Vault Relayer       | Call `sdk.approveCowProtocol()` before posting the order |
| `InsufficientBalance` error    | Wallet doesn't hold enough sell token          | Check balance before posting                             |
| Order created but never fills  | Low liquidity or tight slippage tolerance      | Increase `slippageBps`, try more common token pairs      |
| Order expires immediately      | `validFor` too short                           | Use at least 300 seconds (5 minutes)                     |
| Quote fails with `NoLiquidity` | Token pair not supported or no available pools | Verify token addresses are correct, try larger amounts   |

## Next Steps

* Learn about [Token Approvals](/cow-sdk/guides/token-approvals) before trading
* Explore [Limit Orders](/cow-sdk/guides/creating-limit-orders) for price-specific trades
* See [Order Management](/cow-sdk/guides/order-management) to track and cancel orders
