---
title: "Search API"
url: "https://www.2026election.com/tools/api"
updated: "2026-10-09"
source: "Candidates' campaign sites and Ballotpedia, quoted verbatim"
publisher: "Pluribus"
---

# Search API

One GET endpoint searches everything the nominees said on the issues and returns the matching quote, its source, and links to the race guide.

## Endpoint

`GET https://www.2026election.com/api/search` — also HEAD and OPTIONS. No key. CORS is open (`Access-Control-Allow-Origin: *`).

| Parameter | Required | Values |
| --- | --- | --- |
| `q` | yes | Words to search for, e.g. `tariffs` or `medicaid expansion`. |
| `state` | no | Full state name or 2-letter code, matched exactly. |
| `chamber` | no | `house`, `senate`, `governor` |
| `issue` | no | Issue topic slug: immigration-border-security, economy-cost-of-living, healthcare, abortion-reproductive-rights, education, energy-environment, taxes-government-spending, guns, crime-public-safety, democracy-elections, government-reform-ethics, housing, foreign-policy-defense, veterans, agriculture-rural, infrastructure-transportation, social-security-retirement. Other text matches issue names by substring. |
| `party` | no | `D`, `R`, `other` |
| `limit` | no | 1–25, default 10. |

## Examples

```bash
curl "https://www.2026election.com/api/search?q=tariffs&state=Georgia&limit=3"
```

```js
const res = await fetch("https://www.2026election.com/api/search?q=medicaid&chamber=senate");
const { total, results } = await res.json();
```

## Response

A JSON object `{ query, total, results }`. Each result names the candidate, party and incumbency; the race (`key`, `title`, `url`, `markdownUrl`); the issue and stance; and `match`, the quote or key point that matched, with its `source` and `url`.

```json
{
  "query": "tariffs",
  "total": 42,
  "results": [
    {
      "candidate": "…",
      "party": "Democratic",
      "incumbent": false,
      "race": { "key": "2026-senate-ga", "title": "…", "url": "…", "markdownUrl": "…" },
      "issue": "…",
      "stance": "…",
      "summary": "…",
      "match": { "kind": "quote", "text": "…", "source": "…", "url": "…" },
      "score": 12.3
    }
  ]
}
```

## Errors, limits and caching

Bad input returns 400 with `{ "error": "…" }` saying what to fix. If the index can't load, 500 with `{ "error": "…" }` and `Cache-Control: no-store`. At most 25 results per request.

Responses are cached at the edge until the next deploy, and the data only changes when we deploy. Fetch freely; there's no need to poll.

## Try it

The form below calls the API and shows the JSON. Browser agents that support WebMCP can also fill it in as the `search_positions` tool.
