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

# Cast Office Votes

> Vote for trademark offices you want on Signa

## Overview

Tell us which trademark offices your organization wants covered next — votes directly drive our coverage roadmap. Vote for as many offices as you like: each office counts **once per organization**, no matter how many times (or through how many API keys) you vote, so re-votes are harmless no-ops.

The office-vote endpoints are the one write surface in the reference-data section — `POST` and `DELETE` both take the usual write ceremony: an `Idempotency-Key` header is required, and the request counts against the write rate bucket (responses carry the standard `RateLimit-*` headers).

Voting is free — `POST` and `DELETE` bill 0 units. Reading your votes back with [List Office Votes](/api-reference/reference/list-office-votes) bills 1 read unit.

Retrying with the **same** `Idempotency-Key` replays the cached response of that attempt; a **new** logical attempt — re-casting a vote you previously retracted, say — needs a **fresh** key. Either way the once-per-org, once-per-office counting is enforced server-side, so a fresh key can never double-count you.

## Votable codes

Office codes are WIPO ST.3 two-letter codes. You can vote for:

* **Any ISO 3166-1 country code** — `BR`, `MX`, `IN`, … (`UK` is accepted and canonicalized to `GB`, `EL` to `GR`).
* **Intergovernmental offices with no ISO country code**: `BX` (Benelux/BOIP), `AP` (ARIPO), `OA` (OAPI) — plus `XK` (Kosovo — ST.3-assigned, no ISO code), which is a national office rather than an IGO but is votable on the same footing.
* Legacy lowercase office codes are accepted as aliases and canonicalized — `ukipo` → `GB`, `dpma` → `DE`.

Two kinds of code are rejected:

* **Offices already covered by Signa** — including `EM` (EUIPO) and `WO` (WIPO), which are covered today. Voting for one returns `400` with an `office_already_live` error entry. ([List Offices](/api-reference/reference/list-offices) shows the offices currently **serving** data — an office that is covered but temporarily offline is absent from it, yet still not votable, so the rejection is the authoritative answer.) A dependent territory has no register of its own, so it resolves through the office that registers its marks — `PR`/`GU` → USPTO, `RE`/`GF` → INPI-FR, `SJ` → NIPO, `CX`/`CC`/`NF` → IP Australia — and a vote for it is a vote for that parent office: rejected as already covered when the parent is covered, otherwise stored under the parent's code.
* **Codes with no trademark register of their own** — uninhabited or non-filing territories such as `AQ` (Antarctica), `BV`, `HM`, `TF`, `GS`, `IO`, `UM`, and `PN`. These return `400` with a `no_trademark_register` error entry: there is nothing to connect, so there is nothing to vote for.

Validation is all-or-nothing: if any code in the batch is unknown, already covered, or has no register, nothing is recorded.

## Body Parameters

<ParamField body="office_codes" type="string[]" required>
  Office codes to vote for (1–50). Any case; aliases are canonicalized. Codes your organization already voted for are no-ops.
</ParamField>

## Response

A list of the stored votes for every requested code — newly cast or pre-existing alike. `created_at` is when your organization **first** voted for that office.

<ResponseField name="object" type="string">Always `list`.</ResponseField>

<ResponseField name="data" type="object[]">
  <Expandable title="Office vote object">
    <ResponseField name="object" type="string">Always `office_vote`.</ResponseField>
    <ResponseField name="office_code" type="string">Canonical uppercase ST.3 office code.</ResponseField>
    <ResponseField name="office_status" type="string">`live` (now on Signa — your ask landed), `roadmap` (modeled, connector not shipping yet), or `not_covered` (not modeled yet).</ResponseField>
    <ResponseField name="created_at" type="string">When your organization first voted for this office.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="has_more" type="boolean">Always `false` — the votable vocabulary is bounded, so results are a single page.</ResponseField>

<ResponseExample>
  ```json theme={null}
  {
    "object": "list",
    "data": [
      {
        "object": "office_vote",
        "office_code": "BR",
        "office_status": "not_covered",
        "created_at": "2026-08-29T12:00:00.000Z"
      },
      {
        "object": "office_vote",
        "office_code": "MX",
        "office_status": "not_covered",
        "created_at": "2026-08-29T12:00:00.000Z"
      }
    ],
    "has_more": false,
    "pagination": { "cursor": null },
    "request_id": "req_01kabc..."
  }
  ```
</ResponseExample>

## Code Examples

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST "https://api.signa.so/v1/offices/votes" \
    -H "Authorization: Bearer sig_YOUR_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: office-votes-br-mx-001" \
    -d '{ "office_codes": ["BR", "MX"] }'
  ```

  ```typescript TypeScript theme={null}
  import { Signa } from "@signa-so/sdk";

  const signa = new Signa({ api_key: process.env.SIGNA_API_KEY });

  const votes = await signa.references.castOfficeVotes({ office_codes: ["BR", "MX"] });
  for (const vote of votes.data) {
    console.log(vote.office_code, vote.office_status, vote.created_at);
  }
  ```
</CodeGroup>

## Errors

| Status | Type                     | Description                                                                                                                                                                                                                                                                                     |
| ------ | ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 400    | `validation_error`       | One or more codes rejected: `unknown_office_code` (not a known office or country code), `office_already_live` (already covered by Signa, including territories of a covered office), `no_trademark_register` (no register of its own, e.g. `AQ`). Also an empty or over-50 `office_codes` array |
| 400    | `validation_error`       | Missing `Idempotency-Key` header                                                                                                                                                                                                                                                                |
| 401    | `unauthorized`           | Missing or invalid API key                                                                                                                                                                                                                                                                      |
| 409    | `conflict`               | `Idempotency-Key` reused with a different body                                                                                                                                                                                                                                                  |
| 409    | `idempotency_processing` | A request with the same `Idempotency-Key` is still in flight                                                                                                                                                                                                                                    |
| 429    | `rate_limited`           | Too many requests                                                                                                                                                                                                                                                                               |

Every rejected code comes back as its own entry in `errors[]`, each with `field: "office_codes"` and one of the codes above.

## Related Endpoints

* [List Office Votes](/api-reference/reference/list-office-votes), read your organization's votes back
* [Retract Office Vote](/api-reference/reference/retract-office-vote), remove a vote
* [List Offices](/api-reference/reference/list-offices), the offices already covered by Signa
