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

> ## Agent Instructions
> Odds-API.io REST base URL: https://api.odds-api.io/v3. Authenticate every request with the apiKey query parameter (for example /v3/events?apiKey=YOUR_API_KEY&sport=football). Keep the key server-side.
> For continuously fresh odds use the WebSocket feed at wss://api.odds-api.io/v3/ws (see /guides/websockets); use REST for snapshots and one-off lookups.
> Market names differ by sport. Call GET /v3/markets?sport=<sport> (no key needed) for the exact names instead of guessing them.
> Official SDKs: npm odds-api-io (Node.js/TypeScript), PyPI odds-api-io (Python), Composer odds-api-io/odds-api-php (PHP), go get github.com/odds-api-io/odds-api-go (Go), CRAN oddsapiio (R). MCP server: npx -y odds-api-mcp-server. Prefer them over hand-written HTTP clients.
> The full machine-readable docs are at https://docs.odds-api.io/llms-full.txt and the OpenAPI spec at https://docs.odds-api.io/api-reference/openapi.json.

# Google Sheets Add-on: Live Sports Odds in Your Spreadsheet

> Pull live odds from 450+ bookmakers into Google Sheets with the Odds-API.io add-on: side panel, ODDS and ODDS_TABLE formulas, recipes and auto-refresh.

**Odds-API.io: Sports Odds for Sheets** brings live odds from 450+ bookmakers into Google Sheets without code. Search a team or league in the side panel, compare the best price per market across bookmakers, and insert it as a clean, typed table. Or use the `=ODDS()` and `=ODDS_TABLE()` formulas directly in a cell.

> [card] [Install from Google Workspace Marketplace](https://workspace.google.com/marketplace/app/oddsapiio_sports_odds_for_sheets/1024703542441)
>
> Install it in Google Sheets. Connect an Odds-API.io API key from a paid plan.

> [card] [Add-on overview](https://odds-api.io/google-sheets)
>
> Screenshots and a short tour of what the add-on does.

## What it does

* **Explore**: search a team or league, see the best price per market across bookmakers, the fair price and line movement, then insert any of it as a sheet.
* **Recipes**: one click builds a sheet of best prices, arbitrage, value bets or dropping odds, with optional refresh every minute.
* **Playground**: call any GET endpoint of the API, preview the response and insert it as a table.
* **Formulas**: `=ODDS(eventId, [market], [bookmaker], [refresh])` and `=ODDS_TABLE(sport, [league], [market], [refresh])`.
* **AI-ready tables**: every table has typed columns, comes with suggested questions for Gemini in Sheets, and can be copied as a prompt for ChatGPT, Claude or any AI assistant.

## Install

You need an Odds-API.io API key from a paid plan. Get one at [odds-api.io/pricing](https://odds-api.io/pricing); the key is on your [dashboard](https://odds-api.io/dashboard) right after checkout.

**1. Install the add-on**

Open the [Odds-API.io listing on the Google Workspace Marketplace](https://workspace.google.com/marketplace/app/oddsapiio_sports_odds_for_sheets/1024703542441), click **Install** and approve the permissions. Use the same Google account you open your spreadsheets with.

**2. Open the side panel**

In any spreadsheet, go to **Extensions > Odds-API.io: Sports Odds for Sheets > Open**.

**3. Connect your key**

Paste your API key and click **Connect**. The panel checks the key and shows how many bookmakers are on it.

The key is saved for your Google account, so it works in every spreadsheet you open, and is only sent to `api.odds-api.io`.

## The side panel

The panel has three tabs at the bottom: **Explore**, **Recipes** and **Playground**. The gear icon at the top opens **Settings**.

### Explore

Type at least two letters of a team or league (for example `Arsenal` or `NBA`) to search upcoming events, or pick a sport and league under **Browse** and click **Show events**.

Opening an event shows:

* **Best price per market** (ML, Spread, Totals and every other market the bookmakers price), with the bookmaker that has it. Click **Show more lines** to see alternative lines.
* **Fair price**, the margin-free price, when your plan includes the [odds summary](https://docs.odds-api.io/guides/odds-summary.md) (Growth and above). On other plans the panel shows the best price across your own bookmakers instead.
* **Bookmaker filter**: compare only the bookmakers you pick, or all bookmakers on your key.
* **Line movement**: click **Show line movement** for a price history chart of one bookmaker and market (available for the bookmakers that record movement history).

From the event you can insert three tables:

| Button | Sheet it writes |
| - | - |
| **Insert best prices** | One row per market line and selection: best odds, the bookmakers with that price, the fair price and how many bookmakers price it |
| **Insert every bookmaker's odds** | One row per bookmaker, market line and selection, with a link to the bookmaker's event page when available |
| **Insert movement** | One row per price change for the chosen bookmaker and market |

### Recipes

Recipes build a ready-made sheet in one click. Set the filters, then click **Build sheet**.

| Recipe | Filters | What you get |
| - | - | - |
| **Best prices** | Sport, league | The top price for every selection on the main ML, Spread and Totals lines for up to 25 upcoming events. Includes the fair price on Growth and above; on other plans it compares the first 30 bookmakers on your key. |
| **Arbitrage** | Minimum profit (0 to 3%) | Price gaps across the bookmakers on your key, highest `profit_pct` first. See the [Arbitrage guide](https://docs.odds-api.io/guides/arbitrage-bets.md). |
| **Value bets** | Bookmaker, minimum edge (0 to 10%) | Prices above the fair price at one bookmaker, highest `expected_value_pct` first. See the [Value Bets guide](https://docs.odds-api.io/guides/value-bets.md). |
| **Dropping odds** | Sport, league | The biggest price moves since opening, with 12h, 24h and 48h changes. See the [Dropping Odds guide](https://docs.odds-api.io/guides/dropping-odds.md). |

After a recipe has run, tick **Refresh every minute while this panel is open** to rewrite the same sheet every 60 seconds. See [Auto-refresh and limits](#auto-refresh-and-limits).

### Playground

The Playground calls any GET endpoint of the API and turns the response into a table.

1. Click the endpoint at the top and pick one, for example `/odds`, `/events` or `/settlements`.
2. Required parameters are filled in for you: the last event you opened and the bookmakers on your key. Click **optional parameters** below them to add more.
3. Click **Send request**. The panel shows the response time and row count, as a table or as raw JSON.
4. Click **Insert to sheet** or **Copy for AI**.

The copy button next to the request URL copies it with your key masked, so you can share it safely. The parameters match the [API reference](https://docs.odds-api.io/api-reference/introduction.md).

### When a sheet already exists

If a sheet with the same name is already in the spreadsheet, the panel asks what to do:

* **Replace**: clears the sheet and writes fresh data.
* **Add rows**: keeps what is there and adds the new rows below, useful for building a history.
* **New sheet**: keeps the old sheet and writes to a new one, for example `Arbitrage (2)`.

### What an inserted table looks like

* A bold, frozen header row with a filter on every column.
* Typed columns: odds as decimal numbers, percentages, dates and times in UTC, event ids as plain numbers.
* A named range `oddsapi_<sheet name>`, so formulas and charts can refer to the table by name.
* Notes two columns to the right of the table: what the columns mean, the request it came from (key masked), when it was fetched and suggested questions for an AI assistant.

Sheets always get decimal odds, so formulas and AI analysis stay numeric. **Settings > Odds format** only changes how odds look inside the panel (decimal, American or fractional).

## Formulas

The add-on adds two custom functions. They work in any spreadsheet where the add-on is installed and your key is connected.

### ODDS

```text theme={null}
=ODDS(eventId, [market], [bookmaker], [refresh])
```

Odds for one event, one row per bookmaker, market line and selection.

| Argument | Required | Description |
| - | - | - |
| `eventId` | Yes | The event id. It is shown at the top of every event in the side panel, and in the `event_id` column of inserted tables. |
| `market` | No | A market name, for example `"ML"`, `"Spread"` or `"Totals"` (not case-sensitive). Leave empty for every market. |
| `bookmaker` | No | One bookmaker, for example `"Bet365"`. Leave empty to use the bookmakers on your key (up to 30, the most popular first). |
| `refresh` | No | A cell you change to fetch fresh odds, for example a checkbox. See [Refreshing formulas](#refreshing-formulas). |

Returns these columns, with a header row:

| Column | Description |
| - | - |
| `bookmaker` | Bookmaker name |
| `market` | Market name |
| `line` | Handicap or total line, or the line label; empty for markets without one |
| `selection` | `home`, `draw`, `away`, `over`, `under` and so on |
| `odds` | Decimal odds |
| `updated_at` | When the bookmaker last updated this market |

Examples:

```text theme={null}
=ODDS(123456)
=ODDS(123456, "ML")
=ODDS(123456, "Totals", "Bet365")
=ODDS(A2, "Spread", , $Z$1)
```

### ODDS\_TABLE

```text theme={null}
=ODDS_TABLE(sport, [league], [market], [refresh])
```

The next 20 upcoming events of a sport or league, with the best price per selection on the main line of one market.

| Argument | Required | Description |
| - | - | - |
| `sport` | Yes | Sport slug, for example `"football"` or `"basketball"`. `GET /sports` in the Playground lists every slug. |
| `league` | No | League slug, for example `"england-premier-league"` or `"usa-nba"`. |
| `market` | No | Market name. Defaults to `"ML"`. |
| `refresh` | No | A cell you change to fetch fresh prices, for example a checkbox. |

Returns these columns, with a header row:

| Column | Description |
| - | - |
| `event_id` | Event id, usable in `=ODDS()` |
| `date` | Start time (UTC) |
| `home` | Home team or player |
| `away` | Away team or player |
| `selection` | `home`, `draw`, `away`, `over`, `under` and so on |
| `best_odds` | Best decimal price across bookmakers |
| `best_bookmaker` | The bookmakers offering that price, comma-separated |

Examples:

```text theme={null}
=ODDS_TABLE("football", "england-premier-league")
=ODDS_TABLE("basketball", "usa-nba", "Totals")
=ODDS_TABLE("ice-hockey", , "ML", $Z$1)
```

> [!NOTE]
>
> `ODDS_TABLE` reads the [odds summary](https://docs.odds-api.io/guides/odds-summary.md), so it needs the Growth plan or higher. On other plans it returns a message instead of prices; use `=ODDS(eventId)` or the **Best prices** recipe, which falls back to the bookmakers on your key.

### Refreshing formulas

Google Sheets caches custom function results and only recalculates a formula when one of its arguments changes. The add-on also reuses an identical response for 30 seconds. To fetch fresh prices on demand:

1. Insert a checkbox in a spare cell, for example `Z1` (**Insert > Checkbox**), or type any value there.
2. Pass that cell as the `refresh` argument: `=ODDS(123456, "ML", , $Z$1)`.
3. Tick or untick the checkbox (or change the value) whenever you want new prices. Every formula that points at `Z1` fetches again.

> [!WARNING]
>
> Do not use `=NOW()`, `=RAND()` or a cell that contains them as the `refresh` argument. Google Sheets blocks custom functions that reference volatile functions and shows an error instead of prices.

For hands-free updates, build the sheet from a recipe in the side panel and turn on **Auto-refresh**: it rewrites the sheet every 60 seconds while the panel is open.

Every refresh makes new API requests that count towards your plan's request limit, so refresh only the formulas you need.

### Older formula names

Sheets built with version 1 of the add-on keep working:

| Old formula | Same as |
| - | - |
| `=ODDS_GET_ML(eventId, [bookmaker])` | `=ODDS(eventId, "ML", bookmaker)` |
| `=ODDS_GET_SPREAD(eventId, [bookmaker])` | `=ODDS(eventId, "Spread", bookmaker)` |
| `=ODDS_GET_TOTALS(eventId, [bookmaker])` | `=ODDS(eventId, "Totals", bookmaker)` |

`ODDS_GET_ARBITRAGE` and `ODDS_GET_VALUE` now return a pointer to the **Arbitrage** and **Value bets** recipes in the side panel, which replace them.

## Auto-refresh and limits

* **Recipe refresh**: after you build a recipe sheet, **Refresh every minute while this panel is open** rewrites that sheet every 60 seconds. It stops when you close the panel, switch away from the recipe or a request fails; the panel shows why it paused.
* **Formula refresh**: see [Refreshing formulas](#refreshing-formulas).
* **Request limit**: the panel and the formulas use your API key, so every refresh counts towards your plan's hourly request limit (see [Best Practices](https://docs.odds-api.io/guides/best-practices.md)). When the limit is hit, the panel retries twice with a short pause, then shows **Too many requests**.
* **Large tables**: the panel writes tables in batches of 5,000 rows and shows progress, so large Playground responses do not hit Google's time limit.
* **Bookmakers per request**: the API returns up to 30 bookmakers per odds request. The panel splits larger selections into several requests; `=ODDS()` without a `bookmaker` uses the first 30.

## Using it with Gemini, ChatGPT and Claude

Inserted tables are built to be read by AI assistants: one header row, snake\_case column names, numeric odds and UTC times. Each table's notes include suggested questions, for example *"Which bookmaker has the best price most often?"*.

* **Gemini in Sheets**: open Gemini in the spreadsheet and ask about the table directly.
* **Copy for AI**: every **Insert** button has a **Copy for AI** button next to it. It copies a prompt with the column names and types and the table as CSV (up to 500 rows) to your clipboard. Paste it into ChatGPT, Claude or any other assistant and add your question.
* **Let the assistant query the API**: to give Claude, ChatGPT, Cursor or another assistant live access to the API itself, use the [Odds-API.io MCP server](https://odds-api.io/mcp). Setup steps per tool are in [AI & Vibe Coding](https://docs.odds-api.io/ai-vibe-coding.md#mcp-server).

## Permissions and privacy

The add-on asks for three Google permissions, the minimum it needs:

| Scope | What it allows | Why |
| - | - | - |
| `spreadsheets.currentonly` | Access only the spreadsheet the add-on is open in | Write tables into that spreadsheet. It cannot open your other files. |
| `script.container.ui` | Show a sidebar inside Google Sheets | Display the side panel. |
| `script.external_request` | Connect to an external service | Fetch odds. Requests are restricted to `api.odds-api.io`. |

Your API key and panel settings are stored in your Google account's add-on storage (Apps Script user properties). They are not shared with other people who open the spreadsheet, and the key is only sent to `api.odds-api.io`. The contents of your spreadsheets are never sent to Odds-API.io. Details: [privacy policy](https://odds-api.io/privacy#google-sheets-addon).

## Troubleshooting

> [accordion] Authorization error, or the panel stays blank
>
> This almost always means you are signed in to more than one Google account in the same browser. Google add-ons run under the default account (the first one you signed in with), which may not be the account that installed the add-on. Sign out of the other accounts, or open the spreadsheet in an incognito or guest window signed in to one account only, then open the add-on again.

> [accordion] A cell shows #NAME? or Unknown function
>
> The add-on is not installed for the Google account viewing the sheet. Custom functions only work for people who have installed the add-on, so collaborators without it see `#NAME?`. Each collaborator who wants live formulas needs to install the add-on and connect their own API key. To share a static copy instead, copy the cells and use **Paste special > Values only**.

> [accordion] A cell says "Add your API key"
>
> The add-on is installed but no key is connected for your Google account. Open **Extensions > Odds-API.io: Sports Odds for Sheets > Open** and paste your key.

> [accordion] "That key wasn't accepted" or "Your API key was not accepted"
>
> Copy the key again from your [dashboard](https://odds-api.io/dashboard), without spaces. If you regenerated the key, the old one stops working: open **Settings**, click **Remove key** and connect the new one.

> [accordion] "Not included in your plan"
>
> Some data needs a higher plan or an add-on. The fair price and `ODDS_TABLE` use the odds summary, which needs the Growth plan or higher; Explore and the Best prices recipe fall back to the bookmakers on your key. Value bets, arbitrage, outrights and settlement are add-ons. The message shows exactly what is missing, with a link to [plans](https://odds-api.io/pricing); add-ons are managed in your [dashboard](https://odds-api.io/dashboard).

> [accordion] "Too many requests"
>
> Your key reached its hourly request limit. Turn off auto-refresh on recipes you no longer watch, refresh formulas less often, or add an extra request package on [pricing](https://odds-api.io/pricing).

> [accordion] Formulas show #ERROR!, Loading... or stop updating
>
> Google limits how much custom functions can do: each call can run for up to 30 seconds, and there is a daily quota for outside requests per Google account (see [Apps Script quotas](https://developers.google.com/apps-script/guides/services/quotas)). Hundreds of `=ODDS()` formulas refreshing every minute can reach it. Use fewer formulas with a `market` or `bookmaker` filter, refresh less often, or insert a recipe table from the side panel instead, which does not use the formula quota.

> [accordion] No odds for these filters
>
> The event has no prices for that market or bookmaker yet, or the bookmaker is not on your key. Leave `bookmaker` empty to use every bookmaker on your key, and check the market name with `=ODDS(eventId)` first.

> [accordion] Remove your key or uninstall
>
> To remove your key, open **Settings** in the panel and click **Remove key**. This deletes the key and your panel settings from your Google account. To remove the add-on completely, go to **Extensions > Add-ons > Manage add-ons**, open the Odds-API.io add-on and choose **Uninstall**.

If none of these help, email [hello@odds-api.io](mailto:hello@odds-api.io) with the message you see and the formula or recipe you used.

## FAQ

> [accordion] Do I need an API key?
>
> Yes. All data comes from your Odds-API.io API key, which needs a paid plan. See [pricing](https://odds-api.io/pricing).

> [accordion] Which bookmakers and sports can I use?
>
> The same as your API key: the bookmakers you selected on your plan, across all 34 sports. The panel shows how many bookmakers are on your key in **Settings**. The full catalogue of 450+ bookmakers is on the [bookmakers page](https://odds-api.io/sportsbooks).

> [accordion] How fresh are the odds?
>
> The panel fetches live from the API every time you open an event or build a sheet. Formulas reuse an identical response for up to 30 seconds and otherwise follow Google's recalculation, see [Refreshing formulas](#refreshing-formulas). For tick-by-tick updates in your own code, use the [WebSocket feed](https://docs.odds-api.io/guides/websockets.md).

> [accordion] Does it use my request quota?
>
> Yes. Every panel action, recipe refresh and formula recalculation makes normal API requests on your key.

> [accordion] Can I share a spreadsheet that uses the add-on?
>
> Yes. Inserted tables are plain values that everyone can see. Live formulas only calculate for people who have the add-on installed with their own key; others see `#NAME?`.

> [accordion] Does it work in Excel?
>
> Not yet. The add-on is for Google Sheets. In the meantime, the [SDKs](https://docs.odds-api.io/guides/sdks.md) and the [REST API](https://docs.odds-api.io/api-reference/introduction.md) work from any language.

> [accordion] Is the source code available?
>
> Yes, under the MIT license on [GitHub](https://github.com/odds-api-io/odds-api-spreadsheets).

## Related

> [card] [AI & Vibe Coding](https://docs.odds-api.io/ai-vibe-coding.md)
>
> The MCP server, llms.txt and setup for ChatGPT, Claude and Cursor.

> [card] [SDKs & Libraries](https://docs.odds-api.io/guides/sdks.md)
>
> Node.js, Python, PHP, Go and R clients, plus the command-line tool.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.