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

# Voting Endpoints

> Cast, cancel, and withdraw governance votes, and settle a closed proposal. Requires the governance:vote scope.

|                |                                                                     |
| -------------- | ------------------------------------------------------------------- |
| **Scope**      | `governance:vote`                                                   |
| **Rate limit** | 60 / minute                                                         |
| **Requires**   | `tradingEnabled: true` on [`GET /partner/v1/me`](/api-reference/me) |

Every endpoint on this page takes `priorityFeeLamports` with a minimum of `1000` and `tipLamports` with a minimum of `1000000`, and returns the [standard governance write response](#response).

## POST /partner/v1/governance/votes

Casts a vote. The voted tokens are locked until the user withdraws them after the proposal closes.

| Field                 | Type   | Required | Constraint                     |
| --------------------- | ------ | -------- | ------------------------------ |
| `proposal`            | string | Yes      | Base58 proposal address        |
| `side`                | string | Yes      | `"yes"` or `"no"`              |
| `amount`              | string | Yes      | Integer string, greater than 0 |
| `priorityFeeLamports` | string | Yes      | Minimum `1000`                 |
| `tipLamports`         | string | Yes      | Minimum `1000000`              |

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST 'https://api.tren.ch/partner/v1/governance/votes' \
    -H "Authorization: Bearer $ACCESS_TOKEN" \
    -H 'Content-Type: application/json' \
    -d '{
      "proposal": "…",
      "side": "yes",
      "amount": "1000000",
      "priorityFeeLamports": "20000",
      "tipLamports": "1000000"
    }'
  ```

  ```javascript Node.js theme={null}
  const res = await fetch("https://api.tren.ch/partner/v1/governance/votes", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${accessToken}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      proposal,
      side: "yes",
      amount: "1000000",
      priorityFeeLamports: "20000",
      tipLamports: "1000000",
    }),
  });
  ```

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

  res = requests.post(
    "https://api.tren.ch/partner/v1/governance/votes",
    headers={"Authorization": f"Bearer {access_token}"},
    json={
      "proposal": proposal,
      "side": "yes",
      "amount": "1000000",
      "priorityFeeLamports": "20000",
      "tipLamports": "1000000",
    },
  )
  ```
</CodeGroup>

<Warning>
  Locked tokens cannot be traded until they are withdrawn, and users who are unaware of this tend to read it as missing funds. We recommend making the lock explicit in your UI.
</Warning>

A second vote on the same proposal fails with `already_voted`. To change a vote, cancel the existing one first.

## POST /partner/v1/governance/votes/cancel

Retracts an active vote while voting is still open.

| Field                 | Type   | Required |
| --------------------- | ------ | -------- |
| `proposal`            | string | Yes      |
| `priorityFeeLamports` | string | Yes      |
| `tipLamports`         | string | Yes      |

## POST /partner/v1/governance/votes/withdraw

Reclaims tokens locked by a vote, once the proposal has closed.

| Field                 | Type   | Required | Notes                                   |
| --------------------- | ------ | -------- | --------------------------------------- |
| `proposal`            | string | Yes      |                                         |
| `voter`               | string | No       | Defaults to the connected user's wallet |
| `priorityFeeLamports` | string | Yes      |                                         |
| `tipLamports`         | string | Yes      |                                         |

<Note>
  The `voter` field exists so that anyone can crank a withdrawal on another wallet's behalf. Tokens always return to the voter rather than to the caller, and for normal use the field can be left unset.
</Note>

## POST /partner/v1/governance/proposals/settle

Settles a proposal whose voting window has closed, computing the outcome and applying the action if it passed. The operation is permissionless, so anyone can call it, and someone must before the result takes effect.

| Field                 | Type   | Required |
| --------------------- | ------ | -------- |
| `proposal`            | string | Yes      |
| `priorityFeeLamports` | string | Yes      |
| `tipLamports`         | string | Yes      |

Settling before `votingEndsAtUnix` fails with `proposal_still_open`, and settling twice fails with `proposal_already_settled`.

## Response

```json theme={null}
{
  "signature": "…",
  "status": "processed",
  "mint": "…",
  "governance": "…",
  "proposal": "…"
}
```

<Warning>
  A status of `processed` is weaker than confirmed, meaning the transaction was included in a block but is not yet rooted. Confirm the signature against Solana through your own RPC before showing the user a settled result.
</Warning>

## Errors

| Status | Error                        | Cause                                            |
| ------ | ---------------------------- | ------------------------------------------------ |
| `400`  | `invalid_input`              | Body failed schema validation                    |
| `403`  | `insufficient_scope`         | Token lacks `governance:vote`                    |
| `403`  | `delegation_missing`         | User has not enabled 1-click trading             |
| `404`  | `governance_not_found`       | Token has no governance                          |
| `422`  | `already_voted`              | User already has an active vote on this proposal |
| `422`  | `invalid_vote_amount`        | Below `minLockAmount`, or exceeds balance        |
| `422`  | `missing_vote_token_account` | User holds none of this token                    |
| `422`  | `proposal_closed`            | Voting has ended                                 |
| `422`  | `proposal_still_open`        | Cannot settle yet                                |
| `422`  | `proposal_already_settled`   | Already settled                                  |
| `422`  | `proposal_not_settled`       | Withdrawal requires settlement first             |
| `422`  | `vote_not_active`            | The vote was cancelled                           |
| `422`  | `vote_already_withdrawn`     | Tokens already reclaimed                         |
| `422`  | `vote_receipt_not_found`     | No vote from this wallet on this proposal        |
