> ## 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.

# Rate Limits

> The two rate limit layers on the Trench Partner API: your app's tier budget and the per-endpoint limits, how each bucket is keyed, and request size ceilings.

The Partner API applies two layers of rate limiting, and a request has to pass both. Exceeding either returns a `429` with a `retry-after` value.

## The Two Layers

| Layer        | Scope                                   | Keyed on         |
| ------------ | --------------------------------------- | ---------------- |
| Tier budget  | Every `/partner/v1/*` endpoint together | Your app         |
| Per-endpoint | One route group                         | The access token |

The tier budget is the ceiling for your whole integration. The per-endpoint limits sit underneath it and stop any single user from consuming that budget on their own.

## Tier Budget

Your app gets a fixed number of requests per minute across all Partner API endpoints combined.

| Tier    | Requests per minute |
| ------- | ------------------- |
| Basic   | 120                 |
| Partner | 1,200               |

<Warning>
  This budget is shared by all of your connected users, so they do compete with one another for it. On the Basic tier, 120 requests per minute across your entire user base is usually the limit you hit first, well before any per-endpoint limit.
</Warning>

Exceeding it returns a `429` naming your tier.

```json theme={null}
{
  "error": "rate_limit_exceeded",
  "message": "Basic tier allows 120 requests per minute",
  "retryAfterSeconds": 34
}
```

See [Registration](/concepts/registration#tiers) for what each tier includes, and contact the Trench team if you need the Partner rate.

## Per-Endpoint Limits

These are keyed on the access token, so one user cannot exhaust them for everybody.

| Endpoint                                                | Limit     |
| ------------------------------------------------------- | --------- |
| `GET /partner/v1/me`                                    | 300 / min |
| `GET /partner/v1/governance/{mint}`                     | 300 / min |
| `GET /partner/v1/governance/proposals/{proposal}/votes` | 300 / min |
| `POST /partner/v1/trades/*`                             | 60 / min  |
| `POST /partner/v1/governance/*`                         | 60 / min  |

Writes are capped lower than reads because each one builds, signs, and submits a Solana transaction.

<Note>
  On the Basic tier these ceilings are mostly theoretical, since the 120 per minute tier budget is tighter than any of them. They matter once you are on the Partner tier, where they stop a single user from spending your whole allowance.
</Note>

## OAuth Endpoints

OAuth limits are keyed on the caller's IP address rather than on a token, since there is no token yet.

| Endpoint             | Limit    |
| -------------------- | -------- |
| `POST /oauth/token`  | 30 / min |
| `POST /oauth/revoke` | 30 / min |

<Warning>
  Because these are keyed on IP, all of your token exchanges and refreshes share a single bucket per egress address. A backend behind one NAT IP that refreshes aggressively can exhaust that bucket for every user at once, so we recommend refreshing lazily rather than on a timer.
</Warning>

### Failed Authentication

Separately from the rate limit, twenty failed authentication attempts against one `client_id` within five minutes lock that app out for the remainder of the window.

```json theme={null}
{ "error": "too_many_failed_attempts" }
```

This is returned as a `429` with a `retry-after` header. In practice it means a stale or mistyped API key in a retry loop will lock out your working traffic too, so treat a `401 invalid_client` as a configuration problem to fix rather than something to retry.

## Response Headers

Every response carries the state of the per-endpoint bucket.

* **`x-ratelimit-limit`**: requests allowed in the window
* **`x-ratelimit-remaining`**: requests remaining
* **`x-ratelimit-reset`**: seconds until the window resets
* **`retry-after`**: sent on `429` responses only

<Note>
  These headers describe the per-endpoint bucket, not your tier budget. A tier `429` carries `retry-after` and a `retryAfterSeconds` field in the body, so watch for the `rate_limit_exceeded` code rather than trying to predict it from the headers.
</Note>

## Monitoring Usage

<CodeGroup>
  ```bash cURL theme={null}
  curl -i 'https://api.tren.ch/partner/v1/me' \
    -H 'Authorization: Bearer trench_at_…'

  # x-ratelimit-limit: 300
  # x-ratelimit-remaining: 299
  # x-ratelimit-reset: 47
  ```

  ```javascript Node.js theme={null}
  const res = await fetch('https://api.tren.ch/partner/v1/me', {
    headers: { Authorization: `Bearer ${accessToken}` }
  });

  console.log('Limit:', res.headers.get('x-ratelimit-limit'));
  console.log('Remaining:', res.headers.get('x-ratelimit-remaining'));
  console.log('Resets in:', res.headers.get('x-ratelimit-reset'), 'seconds');
  ```

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

  res = requests.get(
    'https://api.tren.ch/partner/v1/me',
    headers={'Authorization': f'Bearer {access_token}'}
  )

  print('Limit:', res.headers.get('x-ratelimit-limit'))
  print('Remaining:', res.headers.get('x-ratelimit-remaining'))
  print('Resets in:', res.headers.get('x-ratelimit-reset'))
  ```
</CodeGroup>

## Request Size

| Constraint              | Limit  |
| ----------------------- | ------ |
| JSON request body       | 64 KiB |
| Uploaded file           | 5 MiB  |
| Files per request       | 4      |
| Form fields per request | 16     |

The only Partner API endpoint that accepts a file is [`POST /partner/v1/governance/proposals/update-content`](/api-reference/governance-propose), which takes at most one image.

## Handling 429 Responses

Back off and retry after the interval given in `retry-after`. A `429` is rejected before it reaches the transaction builder, so nothing was submitted on-chain and the retry is safe.

<Warning>
  A `429` and a `403 daily_cap_exceeded` both indicate that you should slow down, but they operate on very different timescales. Rate limits clear within the minute, whereas volume caps reset at 00:00 UTC, so we recommend handling them on separate retry paths.
</Warning>

<Tip>
  If your integration needs a higher limit, please contact the Trench team rather than sharding across IP addresses or registering extra apps.
</Tip>
