# Odds API R client: read scoped sportsbook data

Install the GetOdds R source client, read stored DraftKings odds or four source-specific threshold datasets, and retain timestamps, pagination and sanitized error metadata.

Canonical page: https://getoddsapi.com/docs/r

## Free API key

Get a free GetOdds API key: **1,000 requests per UTC day and 60 per minute, no card**. One key covers REST and the hosted MCP server.

Sign up: https://getoddsapi.com/sign-up?ref=ai-claudebot

## Quickstart

1. Create an account at https://getoddsapi.com/sign-up?ref=ai-claudebot, open https://getoddsapi.com/dashboard and issue a key with the sources you need (draftkings, fanduel, betrivers, prizepicks or underdog). Keep it in a server environment variable named GETODDS_API_KEY.
2. Read current DraftKings NBA spreads with curl:

```bash
curl --fail-with-body "https://getoddsapi.com/api/v1/odds?sport=NBA&market=spread&fresh_only=true&limit=50" \
  -H "Authorization: Bearer $GETODDS_API_KEY"
```

3. The same request in Python (standard library only):

```python
import json, os, urllib.request

req = urllib.request.Request(
    "https://getoddsapi.com/api/v1/odds?sport=NBA&market=spread&fresh_only=true&limit=50",
    headers={"Authorization": "Bearer " + os.environ["GETODDS_API_KEY"]},
)
with urllib.request.urlopen(req) as res:
    rows = json.load(res)["data"]
for row in rows:
    print(row["away"], "at", row["home"], row["side"], row["line"], row["american"], row["observed_at"])
```

4. Check `observed_at`, `age_seconds` and `stale` on every row before using a price. Full reference: https://getoddsapi.com/docs

## Use with Claude (MCP)

```bash
claude mcp add --transport http getodds https://getoddsapi.com/api/mcp \
  --header "Authorization: Bearer $GETODDS_API_KEY"
```

The MCP tools follow the key's source grants and share its allowance. Setup guide: https://getoddsapi.com/use-with-claude

## Pricing

| Plan | Allowance | Price |
| --- | --- | --- |
| Free key | 1,000 requests a day, 60 a minute | $0, no card |
| Developer Bundle | 10,000 requests or credits a month on each of four sources | $149 a month |

Free development allowance: 1,000 requests per UTC day and 60 per minute per account, with no payment step. Paid: the Developer Bundle at $149 per month, with 10,000 monthly requests or credits on each of four sources.
Details: https://getoddsapi.com/bundle

## Guide


Canonical: https://getoddsapi.com/docs/r
Reviewed: 2026-11-07 UTC

Install the GetOdds R source client, read stored DraftKings odds or four source-specific threshold datasets, and retain timestamps, pagination and sanitized error metadata.

## Install the source package

Download the R source archive below and extract getodds-r. Install curl and jsonlite from CRAN, then install the extracted local package. The GetOdds package is a direct source download; it is not published to CRAN. The client was tested with R 4.6.2 and declares R 4.1 or later.

Create a GetOdds key with DraftKings access for sportsbook reads or the corresponding source grant for threshold samples. Set GETODDS_API_KEY in your server or local process environment before launching R. Do not put the value in a notebook, shared .Rhistory file or source repository.

```r
install.packages(c("curl", "jsonlite"), repos="https://cloud.r-project.org")
install.packages("./getodds-r", repos=NULL, type="source")
library(getodds)
```

## Read five stored prices

The odds resource reads retained DraftKings prices captured via ESPN. fresh_only=TRUE excludes captures older than 15 minutes. An empty response stays empty; it does not mean zero prices or a closed market. Preserve observed_at, source_updated_at where supplied, age_seconds and stale.

The result is a nested R list, preserving the JSON structure. Keeping the list avoids silently coercing nullable fields or large history sequence IDs into numeric columns. Convert selected fields into a data frame deliberately after checking their types.

```r
quotes <- getodds_read("odds", sport="NBA", fresh_only=TRUE, limit=5)
print(quotes$meta)
print(quotes$pagination)
for (quote in quotes$data) {
  print(quote[c("event_id", "market", "side", "decimal", "observed_at")])
}
```

## Use the right resource and filters

The client supports markets, events, odds, history, sports, bookmakers and market-types. The markets resource accepts source=prizepicks, underdog, draftkings or fanduel and returns an incomplete threshold sample with odds set to null. PrizePicks remains the default. It is not a priced sportsbook market.

History requires an event_id or offer_id and reads retained changes from the last seven days. It cannot recreate missing captures or establish a closing line. Sportsbook limit ranges from 1 to 200; offset ranges from 0 to 10,000. A next_offset is an invitation to another metered request, not an automatic client action. Pages are not a frozen snapshot.

```r
coverage <- getodds_read("sports", limit=20)
props <- getodds_read("markets", limit=5)
if (length(quotes$data) > 0) {
  changes <- getodds_read("history", offer_id=quotes$data[[1]]$id, limit=20)
}
```

## Handle errors without leaking credentials

Each call uses a 20-second timeout, refuses redirects and limits the response to 2 MiB before parsing. Invalid filters are rejected before the network request. The client never automatically retries or fetches another page.

Errors inherit getodds_error and expose code, status and retry_after. A 401 means the key is invalid or revoked; a 403 means it lacks the required source grant. For a 429, wait for the documented allowance before deciding whether to make another request. Failed source reads do not become fabricated observations.

```r
result <- tryCatch(
  getodds_read("odds", sport="NBA", limit=5),
  getodds_error=function(e) {
    message(e$code, " (HTTP ", e$status, ")")
    if (!is.null(e$retry_after)) message("Retry after: ", e$retry_after)
    NULL
  }
)
```

## Questions

### Is the package on CRAN?

No. Version 0.4.0 is a tested source download. Install its curl and jsonlite dependencies, then the local package.

### Does the client calculate live arbitrage or probabilities?

No. It reads the documented gateway resources. It does not invent missing books, infer win probabilities or reinterpret PrizePicks thresholds as sportsbook prices.

### Does one call download the full board?

No. Each call is bounded. Each threshold source is a sample; sportsbook resources expose explicit offset pagination without snapshot consistency.

## Sources

- [Download R client 0.4.0](https://getoddsapi.com/sdk/getodds-r-0.4.0.zip)
- [GetOdds sportsbook contract](https://getoddsapi.com/docs/sportsbook)
- [R curl transport reference](https://jeroen.r-universe.dev/curl/doc/manual.html)

Independent product; not affiliated with the operators named. No picks or predicted profits.

---

GetOdds is an independent developer product and is not affiliated with any sportsbook or pick’em operator. Prices describe data, not betting advice.
