> ## Documentation Index
> Fetch the complete documentation index at: https://trench-446767c3.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Go from registering an app to a confirmed on-chain buy in five steps.

This guide walks you through connecting a user, placing a buy on the Trench bonding curve, and confirming that it landed on-chain.

## Prerequisites

Before starting, make sure you have:

* An app registered at [tren.ch/partner](https://tren.ch/partner), which gives you a `client_id` and an API key. See [Registration](/concepts/registration).
* A redirect URI on the app, matching exactly what you will send.
* The `profile:read` and `trade:execute` scopes selected for the app.
* A Trench user to connect, with 1-click trading enabled and some SOL in their wallet.
* A Solana RPC endpoint, which you will use to confirm that trades landed.

<Warning>
  Trench does not provide a sandbox environment. A client in `development` status trades real SOL against mainnet, so we recommend testing with small amounts on a wallet you control.
</Warning>

## Endpoints Used

* [`POST /oauth/token`](/api-reference/oauth-token)
* [`GET /partner/v1/me`](/api-reference/me)
* [`POST /partner/v1/trades/buy`](/api-reference/trades)

## 1. Set Up Environment Variables

```bash theme={null}
# .env
TRENCH_CLIENT_ID=tclient_your_client_id
TRENCH_API_KEY=trench_cs_your_api_key
TRENCH_REDIRECT_URI=https://yourapp.com/oauth/callback
TRENCH_API=https://api.tren.ch
SOLANA_RPC_URL=https://your-rpc-provider
```

<Warning>
  Your API key should only ever be used server-side. If it reaches a browser bundle, treat it as compromised: create a replacement key in the portal, deploy it, then revoke the leaked one.
</Warning>

## 2. Connect a User

Run the [connect flow](/guides/connect-flow) to obtain an authorization code, then exchange that code for a token pair.

```bash cURL theme={null}
curl -X POST "$TRENCH_API/oauth/token" \
  -u "$TRENCH_CLIENT_ID:$TRENCH_API_KEY" \
  -d grant_type=authorization_code \
  -d code=trench_ac_YOUR_CODE \
  -d redirect_uri="$TRENCH_REDIRECT_URI" \
  -d code_verifier=YOUR_VERIFIER
```

Store the returned `access_token` and `refresh_token` against your own user record.

## 3. Verify the Token

```bash cURL theme={null}
curl "$TRENCH_API/partner/v1/me" \
  -H "Authorization: Bearer $ACCESS_TOKEN"
```

```json theme={null}
{
  "user": {
    "walletSolana": "…",
    "twitterHandle": "…",
    "tradingEnabled": true
  },
  "client": "tclient_…",
  "scopes": ["profile:read", "trade:execute"]
}
```

There are two things worth checking before you attempt a trade: that `tradingEnabled` is `true`, and that `scopes` includes `trade:execute`.

Keep `walletSolana` on hand as well, since you will need it to read the user's balances and transaction history from your RPC.

## 4. Place a Buy

All amounts are sent as integer strings in base units, using lamports for SOL and 1e6 units for tokens. See [Amount Conventions](/concepts/amounts) for details.

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "$TRENCH_API/partner/v1/trades/buy" \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{
      "mint": "YOUR_TOKEN_MINT",
      "maxSolIn": "100000000",
      "slippageBps": 100,
      "priorityFeeLamports": "20000",
      "tipLamports": "1000000"
    }'
  ```

  ```javascript Node.js theme={null}
  const res = await fetch(`${TRENCH_API}/partner/v1/trades/buy`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      mint: TOKEN_MINT,
      maxSolIn: "100000000", // 0.1 SOL
      slippageBps: 100,      // 1% tolerance
      priorityFeeLamports: "20000",
      tipLamports: "1000000",
    }),
  });

  const { signature } = await res.json();
  ```

  ```python Python theme={null}
  import requests

  res = requests.post(
    f"{TRENCH_API}/partner/v1/trades/buy",
    headers={"Authorization": f"Bearer {access_token}"},
    json={
      "mint": TOKEN_MINT,
      "maxSolIn": "100000000",
      "slippageBps": 100,
      "priorityFeeLamports": "20000",
      "tipLamports": "1000000",
    },
  )

  signature = res.json()["signature"]
  ```
</CodeGroup>

```json Response theme={null}
{ "signature": "…", "mint": "…", "status": "submitted" }
```

<Warning>
  `slippageBps` is your protection against the price moving between quoting and execution. Trench takes a quote when the trade executes, derives the minimum tokens it must return, and fails with `slippage_exceeded` rather than filling worse. If you would rather compute that bound yourself, omit `slippageBps` and send `minTokensOut` instead.
</Warning>

<Tip>
  If you want to take a cut of the trade, add `partnerFeeBps` to the request body. See [Partner Fees](/concepts/partner-fees).
</Tip>

## 5. Confirm It Landed

A status of `submitted` means the network accepted the transaction, not that it succeeded. Confirmation is public on-chain state, so you read it from Solana directly using the signature Trench returned.

```javascript Node.js theme={null}
import { Connection } from "@solana/web3.js";

const connection = new Connection(process.env.SOLANA_RPC_URL, "confirmed");

async function waitForTrade(signature) {
  for (let i = 0; i < 30; i++) {
    const { value } = await connection.getSignatureStatuses([signature]);
    const status = value[0];

    if (status?.err) throw new Error(`Trade failed: ${JSON.stringify(status.err)}`);

    if (status?.confirmationStatus === "confirmed" || status?.confirmationStatus === "finalized") {
      return status;
    }

    await new Promise((r) => setTimeout(r, 1000));
  }

  throw new Error("Timed out waiting for confirmation");
}
```

Once the transaction has confirmed, the token balance changes recorded on it tell you what the user actually received.

```javascript Node.js theme={null}
const tx = await connection.getParsedTransaction(signature, {
  maxSupportedTransactionVersion: 0,
});

const { preTokenBalances, postTokenBalances } = tx.meta;
```

<Warning>
  The Partner API does not support idempotency keys, so sending the same trade twice will execute it twice. If a request times out before you receive a signature, check the user's recent transactions on-chain to see whether it landed before trying again.
</Warning>

## Next Steps

<Columns cols={2}>
  <Card title="Trade Tokens" icon="arrow-right-left" href="/guides/trading">
    Exact-out buys, sells, and volume caps.
  </Card>

  <Card title="Partner Fees" icon="percent" href="/concepts/partner-fees">
    Charge your own fee on every trade.
  </Card>

  <Card title="Governance" icon="landmark" href="/guides/governance">
    Read proposals and vote on behalf of a user.
  </Card>

  <Card title="Security Requirements" icon="lock" href="/concepts/security">
    Recommended reading before going to production.
  </Card>
</Columns>
