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

# Registering Your App

> Register your app yourself in the Trench partner portal. Covers tiers, API keys and rotation, redirect URIs, volume caps, and fee wallets.

Registration is self-serve. Sign in at [tren.ch/partner](https://tren.ch/partner) with your Trench account, name your app, set a redirect URI, and choose the scopes you need. The app works immediately, with no review step.

## What You Get

|               |                                                                   |
| ------------- | ----------------------------------------------------------------- |
| `client_id`   | Public identifier, prefixed `tclient_`                            |
| API key       | Server-side only, prefixed `trench_cs_`, shown once at creation   |
| Redirect URIs | Exact-match strings                                               |
| Scopes        | Which of the [available scopes](/concepts/scopes) you may request |

Trench stores only a hash of each API key, so it cannot be recovered after it is shown. If you lose one, create another and revoke the old one.

## Tiers

New apps land on the free Basic tier.

|                                 | Basic | Partner         |
| ------------------------------- | ----- | --------------- |
| Requests per minute             | 120   | 1,200           |
| Apps per account                | 1     | 25              |
| API keys per app                | 5     | 20              |
| Trading and governance writes   | Yes   | Yes             |
| Per-trade and daily volume caps | None  | None by default |
| Charge your own trade fees      | No    | Yes             |

Basic includes everything you need to build a real integration, including trading and governance writes, with no ceiling on trade size or daily volume. The two things it withholds are a higher request rate and the ability to charge your own [trade fees](/concepts/partner-fees).

Message the Trench team for a higher request rate, more apps, or fee wallets. Those are granted by hand.

## API Keys

An app can hold several live keys at once, which is what makes rotation possible without downtime. Keys are named, so you can keep separate ones for production, staging, and CI, and revoke one without disturbing the others.

Keys authenticate the [token exchange](/api-reference/oauth-token) and [revocation](/api-reference/oauth-revoke) only. Partner API calls are authenticated by the user's access token, which already identifies your app, so you should never send a key alongside one.

### Rotating a Key

<Warning>
  Revoking a key disconnects every user who connected through it. Each token records the key that minted it, so revoking the key invalidates those access and refresh tokens immediately rather than leaving a leaked key useful for the remainder of a 60-day refresh lifetime. Affected users have to reconnect from scratch.
</Warning>

To rotate without interrupting anyone, move your users onto the new key before you revoke the old one.

<Steps>
  <Step title="Create the new key">
    Do this in the portal and copy the secret straight away, since it is shown once.
  </Step>

  <Step title="Deploy it">
    Roll the new value out to every backend that calls `/oauth/token`.
  </Step>

  <Step title="Refresh each user once">
    A refresh rebinds that user's tokens to whichever key you present, so refreshing on the new key moves them off the old one.
  </Step>

  <Step title="Revoke the old key">
    Once no live tokens are bound to it, revoking it affects nobody.
  </Step>
</Steps>

If you are rotating because a key leaked, skip the third step and revoke immediately. Disconnecting those users is the point.

### Failed Authentication

Twenty failed authentication attempts against one `client_id` within five minutes lock that app out for the remainder of the window. Further attempts return `429 too_many_failed_attempts` with a `retry-after` header, and normal service resumes once the window passes.

## Client Status

Every app sits in one of three states.

| Status        | Meaning                                                                                |
| ------------- | -------------------------------------------------------------------------------------- |
| `development` | Default for new apps. Permits `http://localhost` and `http://127.0.0.1` redirect URIs. |
| `live`        | Production. Plain `http://` redirect URIs are rejected.                                |
| `suspended`   | Trench has disabled the app.                                                           |

<Warning>
  Development status is not a sandbox. The only behaviour it changes is the redirect URI rule described below. A development app trades real SOL against mainnet, on the same data, with the same token lifetimes and rate limits as a live one. We recommend testing with small amounts on a wallet you control.
</Warning>

A suspended app is treated as though it does not exist. The authorize flow returns `unknown_client`, token calls return `invalid_client`, and every previously issued access token begins failing with `401 invalid_token` on its next request.

## Redirect URIs

The `redirect_uri` you send must exactly match a registered string. There is no prefix matching, no wildcard support, and no trailing-slash normalization, so we recommend registering every environment you need up front, including your local callback.

HTTPS is required except for `localhost` and `127.0.0.1`, and that exception only applies while your app is in `development`. Promoting an app to `live` will therefore break any localhost URI still in use.

A mismatch returns `invalid_redirect_uri`.

<Warning>
  The localhost exception requires a path, even an empty one. Both `http://localhost:3000/callback` and `http://localhost:3000/` are accepted, but `http://localhost:3000` without a trailing slash is not and will fail with `invalid_redirect_uri`.
</Warning>

## Volume Caps

Neither tier imposes a trade cap by default, but Trench can set them per app. When set, they apply to `maxSolIn` on buys only, and sells are never capped.

| Cap               | Applies to                                                          | Error                    |
| ----------------- | ------------------------------------------------------------------- | ------------------------ |
| Per-trade maximum | `maxSolIn` on buys                                                  | `403 trade_cap_exceeded` |
| Daily volume      | Sum of `maxSolIn` across successful buys, per user, since 00:00 UTC | `403 daily_cap_exceeded` |

Both errors include the relevant limit in the response body, so you can surface something useful to the user.

```json theme={null}
{
  "error": "daily_cap_exceeded",
  "message": "…",
  "dailyVolumeCapLamports": "…",
  "spentTodayLamports": "…"
}
```

The daily cap is scoped to an app and user pair rather than to your app overall, which means one user reaching their ceiling does not affect anyone else.

Sells and governance writes are not counted against either cap.

## Fee Wallets

Charging your own fee on trades requires the Partner tier and at least one registered fee wallet. Each address has to already exist on-chain, be a plain system account, and be rent-exempt.

Registering several lets Trench spread your fee volume across them, since one is picked at random per trade.

The rate itself is not registered. It travels with each request as `partnerFeeBps`, so you can price users individually without asking Trench to change anything.

See [Partner Fees](/concepts/partner-fees) for how much is taken and how it interacts with slippage.

## 1-Click Trading

The `trade:execute` and governance write scopes require the user to have delegated their wallet to Trench, which the product refers to as 1-click trading. The consent screen enforces this, so if delegation is off the Approve button stays disabled until the user enables it inline.

This means you will never be issued a trading token that cannot trade at the time it is created. A user can revoke delegation afterwards, though, so we recommend checking `tradingEnabled` on [`GET /partner/v1/me`](/api-reference/me) before showing trade controls. Writes fail with `403 delegation_missing` once delegation has been revoked.
