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

# API Cookbook

> End-to-end recipes for building calldata, executing transactions, and monitoring cross-chain buys

## Overview

Use this cookbook when you want 1tx to handle:

* instrument discovery,
* quote generation,
* source-chain selection,
* calldata generation,
* and cross-chain relay tracking.

This is the recommended integration path for most apps.

## Prerequisites

* an API key for discovery and monitoring endpoints,
* a bearer token for transaction-building endpoints,
* a wallet connection in your frontend,
* a way to send EVM transactions, such as `viem` or `wagmi`.

## Recipe 1: Build and Execute a Same-Chain Buy

### Step 1: Fetch the instrument

```typescript theme={null}
const API_BASE = 'https://api.1tx.fi/api/v1';

const instrumentsResponse = await fetch(`${API_BASE}/instruments`, {
  headers: {
    'x-api-key': apiKey,
  },
});

const instruments = await instrumentsResponse.json();
const instrument = instruments.data.find(
  (item: { symbol: string; chainId: number }) =>
    item.symbol === 'USDC' && item.chainId === 8453,
);
```

### Step 2: Build the transaction bundle

```typescript theme={null}
const bundleResponse = await fetch(`${API_BASE}/transactions/buy`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${jwt}`,
    'x-api-key': apiKey,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    userAddress,
    instrumentId: instrument.instrumentId,
    amountUsdc: '1000.00',
    slippageBps: 50,
  }),
});

const bundle = await bundleResponse.json();
```

### Step 3: Execute the returned transactions in order

```typescript theme={null}
import { createWalletClient, custom, parseEther } from 'viem';
import { base } from 'viem/chains';

const walletClient = createWalletClient({
  chain: base,
  transport: custom(window.ethereum),
});

for (const tx of bundle.transactions) {
  const hash = await walletClient.sendTransaction({
    account: userAddress,
    chain: base,
    to: tx.to,
    data: tx.data,
    value: BigInt(tx.value),
  });

  console.log(`sent ${tx.type}`, hash);
}
```

<Tip>
  The bundle may contain either:

  * a single router transaction, or
  * an approval followed by the router transaction.

  An approval is only included when current allowance is insufficient. If it is present, it must be mined before the deposit transaction is sent.
</Tip>

## Recipe 2: Build and Monitor a Cross-Chain Buy

For cross-chain buys, the source-chain router transaction is still built through `POST /transactions/buy`, but completion is tracked through the CCTP API.

### Step 1: Build the bundle

```typescript theme={null}
const bundleResponse = await fetch(`${API_BASE}/transactions/buy`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${jwt}`,
    'x-api-key': apiKey,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    userAddress,
    instrumentId: '0x0000a4b194d4938ed6aab5bdbac7ca4b622f3639b1bca1b8b9c3271403d3b1b5',
    amountUsdc: '2.20',
  }),
});

const bundle = await bundleResponse.json();

if (!bundle.isCrossChain) {
  throw new Error('expected a cross-chain route');
}
```

### Step 2: Execute the source-chain transactions

```typescript theme={null}
let sourceTxHash: `0x${string}` | null = null;

for (const tx of bundle.transactions) {
  const hash = await walletClient.sendTransaction({
    account: userAddress,
    to: tx.to,
    data: tx.data,
    value: BigInt(tx.value),
  });

  sourceTxHash = hash;
}
```

The final transaction in the bundle is the router `buy()` transaction. Use that hash as the source transaction hash to monitor.

### Step 3: Poll relay status by source tx hash

```typescript theme={null}
type RelayStatus = {
  jobId: string;
  status: 'pending' | 'waiting_attestation' | 'redeeming' | 'success' | 'failed';
  sourceTxHash: string;
  sourceChainId: number;
  destinationChainId: number;
  destinationTxHash?: string;
  error?: string;
};

async function waitForCrossChainCompletion(sourceTxHash: string): Promise<RelayStatus> {
  while (true) {
    const response = await fetch(`${API_BASE}/cctp/relay/tx/${sourceTxHash}`, {
      headers: {
        'x-api-key': apiKey,
      },
    });

    if (response.status === 404) {
      await new Promise((resolve) => setTimeout(resolve, 5000));
      continue;
    }

    if (!response.ok) {
      throw new Error(`relay lookup failed: ${response.status}`);
    }

    const relay = (await response.json()) as RelayStatus;

    if (relay.status === 'success') {
      return relay;
    }

    if (relay.status === 'failed') {
      throw new Error(relay.error || 'cross-chain relay failed');
    }

    await new Promise((resolve) => setTimeout(resolve, 10000));
  }
}
```

### Step 4: Show destination completion

```typescript theme={null}
const relay = await waitForCrossChainCompletion(sourceTxHash!);
console.log('destination tx:', relay.destinationTxHash);
```

<Note>
  A brief `404 Job not found` immediately after source-chain confirmation is expected. The relay job is created asynchronously when the bridge event webhook is ingested.
</Note>

## Recipe 3: Estimate CCTP Fees Before Building

If you want to display cross-chain transfer mode estimates before submitting a buy, use the CCTP fee endpoint.

```typescript theme={null}
const feeResponse = await fetch(`${API_BASE}/cctp/fee/6/3`, {
  headers: {
    'x-api-key': apiKey,
  },
});

const fees = await feeResponse.json();
console.log(fees.fastFeeBps, fees.standardFeeBps);
```

Use `GET /cctp/config` to map chain IDs to Circle domains.

## Common Pitfalls

* Missing bearer auth on `POST /transactions/buy` or `POST /transactions/sell`
* Sending transactions out of order
* Treating an early `404` from `/cctp/relay/tx/:sourceTxHash` as a permanent failure
* Reusing an expired bundle after `expiresAt`
* Formatting human-readable amounts incorrectly before calling the API

## Next Steps

<CardGroup cols={2}>
  <Card title="Transactions API" icon="code" href="/api-reference/endpoints/transactions">
    Full request and response shapes for transaction bundles
  </Card>

  <Card title="CCTP API" icon="arrow-right-arrow-left" href="/api-reference/endpoints/cctp">
    Relay monitoring and fee estimation endpoints
  </Card>
</CardGroup>
