> For the complete documentation index, see [llms.txt](https://titan-exchange.gitbook.io/titan/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://titan-exchange.gitbook.io/titan/developer-doc/developers-portal/quickstart.md).

# Quickstart

Fetch a quote and assemble an executable swap transaction.

Fetch a swap quote over HTTP, select the recommended route, and assemble it into a versioned transaction ready to sign and send.

## Prerequisites

| Requirement                                                                | Purpose                                            |
| -------------------------------------------------------------------------- | -------------------------------------------------- |
| API key from [developer.titan.exchange](https://developer.titan.exchange/) | Authenticates every Portal request                 |
| Solana RPC endpoint                                                        | Reading blockhashes and submitting the transaction |
| `@solana/web3.js`                                                          | Building the versioned transaction                 |

{% code title=".env" %}

```bash
TITAN_API_KEY=your-api-key
SOLANA_RPC_URL=https://your-rpc-endpoint
```

{% endcode %}

## Fetch a quote

{% tabs %}
{% tab title="curl" %}

```bash
curl "https://portal.api.titan.exchange/api/v1/quote/swap?\
inputMint=So11111111111111111111111111111111111111112&\
outputMint=EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v&\
amount=1000000000&\
userPublicKey=8AdYBZcRixYVacvhGG2PBNruyoWfmagR6aiBUq6qE1nf&\
numQuotes=5&\
includeAltContents=true" \
  -H "x-api-key: $TITAN_API_KEY" \
  -H "Accept: application/json"
```

{% endtab %}

{% tab title="TypeScript" %}

```typescript
const params = new URLSearchParams({
  inputMint:  'So11111111111111111111111111111111111111112',
  outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
  amount: '1000000000',
  userPublicKey: '8AdYBZcRixYVacvhGG2PBNruyoWfmagR6aiBUq6qE1nf',
  numQuotes: '5',
  includeAltContents: 'true',
});

const res = await fetch(
  `https://portal.api.titan.exchange/api/v1/quote/swap?${params}`,
  { headers: { 'x-api-key': process.env.TITAN_API_KEY!, Accept: 'application/json' } },
);
```

{% endtab %}
{% endtabs %}

| Parameter            | Description                                                                    |
| -------------------- | ------------------------------------------------------------------------------ |
| `inputMint`          | Mint address of the token being sold.                                          |
| `outputMint`         | Mint address of the token being bought.                                        |
| `amount`             | Amount of `inputMint` in its smallest unit. `1000000000` is 1 SOL in lamports. |
| `userPublicKey`      | Wallet that will sign and execute the swap.                                    |
| `numQuotes`          | Maximum number of provider quotes to return. Defaults to `1`, maximum `10`.    |
| `includeAltContents` | Includes address lookup table contents inline in a top-level `alts` array.     |

The response contains one entry per provider under `quotes`, keyed by provider ID, and the recommended route in `metadata.ExpectedWinner`:

```json
{
  "id": "swap:2afe554d-af4f-4c5d-a1c1-3f1fd6eb605a:0",
  "inputMint": "So11111111111111111111111111111111111111112",
  "outputMint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
  "amount": 1000000000,
  "quotes": {
    "Titan": {
      "inAmount": 1000000000,
      "outAmount": 100781959,
      "slippageBps": 100,
      "steps": [ ... ],
      "instructions": [ ... ],
      "addressLookupTables": [ "9Re4PV8SstkAFveSuVckncTJakQVS8aT3z8uZvWRY4QA" ],
      "contextSlot": 447800832,
      "computeUnits": 85743,
      "computeUnitsSafe": 171486
    },
    "Titan-DART": {
      "inAmount": 1000000000,
      "outAmount": 100772613,
      "slippageBps": 100,
      "steps": [],
      "instructions": [ ... ],
      "addressLookupTables": [ "9Re4PV8SstkAFveSuVckncTJakQVS8aT3z8uZvWRY4QA" ],
      "contextSlot": 447800832,
      "computeUnits": 1400000,
      "computeUnitsSafe": 1400000,
      "referenceId": "titan_dart"
    }
  },
  "metadata": {
    "ExpectedWinner": "Titan-DART",
    "inputMintDecimals": 9,
    "outputMintDecimals": 6,
    "inputPriceUSD": 100.51,
    "outputPriceUSD": 0.9998
  },
  "alts": [ { "p": "9Re4PV8SstkAFveSuVckncTJakQVS8aT3z8uZvWRY4QA", "a": [ ... ] } ]
}
```

## Build the transaction

```typescript
import {
  Connection, Keypair, PublicKey, TransactionInstruction, ComputeBudgetProgram,
  TransactionMessage, VersionedTransaction, AddressLookupTableAccount,
} from '@solana/web3.js';

const API = 'https://portal.api.titan.exchange';
const headers = { 'x-api-key': process.env.TITAN_API_KEY!, Accept: 'application/json' };

const wallet = Keypair.fromSecretKey(/* your key */);
const connection = new Connection(process.env.SOLANA_RPC_URL!);

const params = new URLSearchParams({
  inputMint:  'So11111111111111111111111111111111111111112',   // SOL
  outputMint: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',  // USDC
  amount: '1000000000',                                        // 1 SOL, in lamports
  userPublicKey: wallet.publicKey.toBase58(),
  slippageBps: '50',
  numQuotes: '5',
  includeAltContents: 'true',
});

const res = await fetch(`${API}/api/v1/quote/swap?${params}`, { headers });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const quotes = await res.json();

// Use metadata.ExpectedWinner for the best slippage-adjusted route
const winner = quotes.metadata?.ExpectedWinner;
const route = quotes.quotes[winner];
if (!route) throw new Error('No route returned');

// Instructions use short field names: p = programId, a = accounts, d = data.
// Each account is { p: pubkey, s: isSigner, w: isWritable }.
const instructions = route.instructions.map((ix: any) => new TransactionInstruction({
  programId: new PublicKey(ix.p),
  keys: ix.a.map((m: any) => ({ pubkey: new PublicKey(m.p), isSigner: m.s, isWritable: m.w })),
  data: Buffer.from(ix.d, 'base64'),
}));

// Some providers include a compute-budget instruction and some do not.
// Set the limit from computeUnitsSafe when the route omits it.
if (!instructions.some((ix) => ix.programId.equals(ComputeBudgetProgram.programId))) {
  instructions.unshift(ComputeBudgetProgram.setComputeUnitLimit({ units: route.computeUnitsSafe }));
}

// `alts` covers every returned route. Keep the tables this route uses.
const needed = new Set(route.addressLookupTables);
const lookupTables = (quotes.alts ?? [])
  .filter((t: any) => needed.has(t.p))
  .map((t: any) => new AddressLookupTableAccount({
    key: new PublicKey(t.p),
    state: {
      deactivationSlot: BigInt('18446744073709551615'),  // u64::MAX — table is active
      lastExtendedSlot: 0,
      lastExtendedSlotStartIndex: 0,
      addresses: t.a.map((a: string) => new PublicKey(a)),
    },
  }));

const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash();
const message = new TransactionMessage({
  payerKey: wallet.publicKey,
  recentBlockhash: blockhash,
  instructions,
}).compileToV0Message(lookupTables);

const tx = new VersionedTransaction(message);
tx.sign([wallet]);

const signature = await connection.sendTransaction(tx, { maxRetries: 3 });
await connection.confirmTransaction({ signature, blockhash, lastValidBlockHeight });
```

## Implementation notes

| Behavior       | Detail                                                                                                                                                                                                                                                     |
| -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Compute budget | Some providers include a compute-budget instruction in the route and some do not. Check for the `ComputeBudget111111111111111111111111111111` program before adding one; when absent, set the limit from `computeUnitsSafe`. The value varies by provider. |
| Quote lifetime | Routes are computed against the on-chain state at `contextSlot` and expire within seconds. Do not cache quotes.                                                                                                                                            |
| Signing wallet | Instructions reference the token accounts of the `userPublicKey` used at quote time. A different signer fails.                                                                                                                                             |
| Lookup tables  | Without `includeAltContents`, load each address in `route.addressLookupTables` with `connection.getAddressLookupTable`.                                                                                                                                    |

## Parameter format

Titan Direct requests and the WebSocket examples in the Swap API guides describe parameters as fields within nested `SwapParams` and `TransactionParams` objects. On the Portal each is a flat query parameter, and lists are comma-separated.

| Titan Direct                                  | Portal                            |
| --------------------------------------------- | --------------------------------- |
| `swap.dexes: ["Raydium", "Phoenix"]`          | `?dexes=Raydium,Phoenix`          |
| `swap.onlyDirectRoutes: true`                 | `?onlyDirectRoutes=true`          |
| `transaction.createOutputTokenAccount: false` | `?createOutputTokenAccount=false` |

Parameter names and behavior are identical. The code samples in [Configure Routing](/titan/developer-doc/swap-api/guides/configure-routing.md) and [Transaction Template](/titan/developer-doc/swap-api/guides/transaction-template.md) use distributor authentication, so keep the `x-api-key` and `Accept: application/json` headers from this page when applying them. The full parameter list is in the [Quote Swap reference](/titan/developer-doc/developers-portal/reference/quote-swap.md).
