# Barttorvik College Basketball Scraper (`parseforge/barttorvik-college-basketball-scraper`) Actor

Scrape Barttorvik T-Rank college basketball analytics: adjusted efficiency ratings and four factors for every Division I team since 2008, plus every game with its box-score four factors.

- **URL**: https://apify.com/parseforge/barttorvik-college-basketball-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** Lead generation, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.45 / 1,000 team ratings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

[![ParseForge](https://raw.githubusercontent.com/ParseForge/apify-assets/main/banner.jpg)](https://apify.com/parseforge?fpr=vmoqkp)

### NCAA Basketball Rankings Scraper - Barttorvik T-Rank

**Barttorvik's T-Rank as data: adjusted efficiency ratings and four factors for all 365 Division I teams, every season since 2008, plus every game with its own four factors.** No login, no API key, no proxy. Export to CSV, JSON, Excel, or XML.

T-Rank is the public tempo-free rating system college basketball analysts actually use, but the site gives you a table to look at, not a file to work with. This Actor reads the ratings table and the season game file, returns them as flat rows, and adds what the site leaves you to work out by hand: form splits, schedule strength, and the rank and barthag of both sides on every game.

| Who uses it | What they use T-Rank data for |
|---|---|
| Bettors and modellers | Tempo-free efficiency inputs and per-game four factors for a rating model |
| College coaching staffs and analysts | Opponent scouting: four factors for and against, form and schedule strength |
| Bracketologists and media | Wins above bubble, quality wins and bad losses by team |
| Fantasy and DFS tools | Pace and efficiency by team to project game totals |
| Sports data researchers | Nineteen seasons of tempo-free ratings in one schema |

### What it does

Two datasets, both from the season files the site publishes:

- 🏀 **Team ratings:** one row per team per season. T-Rank position, conference, record, adjusted offense and defense, barthag, effective field goal percentage for and against, turnover rate for and against, offensive and defensive rebound percentage, free throw rate for and against, two and three point percentages and rates for and against, adjusted tempo, wins above bubble, and the tournament note the site prints next to the name ("1 seed, CHAMPS").
- 📅 **Games:** one row per team per game, so each game appears twice, once from each side. Date, opponent, both conferences, venue, result, score, margin, the adjusted offense and defense of that performance, the four factors for and against, game score, adjusted margin, tempo and both head coaches. The 2026 season carries 11,504 game rows.

And three blocks computed from the same files, so they cost no extra request:

- 📈 **Team form:** last-10 record, home, away and neutral splits, conference and non-conference records, the last game played and its result.
- 💪 **Schedule strength:** average opponent rank and barthag, the toughest opponent faced, wins against the top 50 and losses to teams outside the top 200.
- 🔍 **Game context:** the season rank, barthag and record of both sides on each game row, which is what turns a result into a quality win or a bad loss.

Coverage runs from the 2008 season (341 teams) to the current one (365).

### What you can do with T-Rank data

**Build a rating model.**

Pull the games for several seasons with the four factors and the adjusted margin already computed per performance, and you have a training set without touching a box score.

**Scout an opponent.**

One team, one season, with form and schedule strength: how they score and defend, how they have played in the last ten, and against whom.

**Find quality wins and bad losses.**

Game context puts the opponent's rank on the row, so filtering wins against the top 50 or losses to teams outside the top 200 is a spreadsheet filter, not a join.

**Compare conferences.**

Filter by conference across seasons and compare adjusted efficiency, tempo and wins above bubble.

### Why choose this scraper

|  | What you get |
|---|---|
| **Columns that are verified, not guessed** | The site's JSON is an unlabelled array; every field here was aligned against its own labelled table, and the positions that could not be confirmed are left out rather than mislabelled |
| **Scores the right way round** | The site writes the score winner first, so "L, 96-62" means the team scored 62. Every row carries the team's own score, the opponent's, and the signed margin |
| **Two datasets, one schema** | Ratings and games in the same run, with `rowType` telling them apart |
| **Nineteen seasons** | 2008 onward, the same fields throughout |
| **Fast and cheap to run** | One request per season file: 3,000 game rows written in about three seconds |
| **No proxy, no browser** | Plain HTTP; the site's browser check is answered by posting the form it ships |

### How it compares

No Apify Actor publishes tempo-free college basketball ratings. The NCAA actors on the Store return box scores, which are the raw counting stats behind the game rather than the adjusted ratings.

| Feature | ParseForge | barttorvik.com | NCAA box score actors |
|---|---|---|---|
| Adjusted efficiency and barthag | Yes | Yes, as a table | No |
| Four factors for and against | Yes | Yes | Partly, unadjusted |
| Per-game adjusted performance | Yes | Yes | No |
| Form and schedule strength computed | Yes | Work it out yourself | No |
| Seasons back to 2008 | Yes | Yes | Varies |
| Export | CSV, JSON, Excel, XML | No | Yes |
| Price per row | $0.005 ratings, $0.002 games | Free, manual | $0.00002 to $0.004 |

### What a team rating looks like

```json
{
  "rowType": "team-rating",
  "season": 2026,
  "rank": 1,
  "team": "Michigan",
  "tournamentNote": "1 seed, CHAMPS",
  "conference": "B10",
  "games": 40,
  "record": "37-3",
  "wins": 37,
  "losses": 3,
  "adjustedOffense": 129.54,
  "adjustedDefense": 91.51,
  "barthag": 0.98191,
  "effectiveFgPct": 58.38,
  "effectiveFgPctDefense": 44.61,
  "turnoverPct": 16.3154,
  "turnoverPctDefense": 15.1271,
  "offensiveReboundPct": 34.754,
  "defensiveReboundPct": 28.269,
  "freeThrowRate": 38.0102,
  "freeThrowRateDefense": 26.013,
  "twoPointPct": 60.64,
  "twoPointPctDefense": 43.82,
  "threePointPct": 36.831,
  "threePointPctDefense": 30.416,
  "threePointRate": 41.4141,
  "threePointRateDefense": 42.3275,
  "adjustedTempo": 71.121,
  "winsAboveBubble": 14.21,
  "scrapedAt": "2026-08-27T20:30:46.346Z"
}
```

A game row from the same season, with context on:

```json
{
  "rowType": "game",
  "date": "2026-04-06",
  "team": "Michigan",
  "teamConference": "B10",
  "opponent": "Connecticut",
  "opponentConference": "BE",
  "venue": "Neutral",
  "isConferenceGame": "No",
  "result": "W, 69-63",
  "outcome": "Win",
  "teamScore": 69,
  "opponentScore": 63,
  "margin": 6,
  "coach": "Dusty May",
  "opponentRank": 9,
  "opponentBarthag": 0.95619
}
```

### Configure the run

Leave everything empty for the current season's ratings. Pick `games` for the game file, or `both` to get the ratings first and then the games.

The top 25 teams this season:

```json
{ "dataset": "team-ratings", "maxRank": 25, "maxItems": 25 }
```

One conference with form and schedule strength:

```json
{
  "dataset": "team-ratings",
  "conferences": ["B10"],
  "includeTeamForm": true,
  "includeScheduleStrength": true,
  "maxItems": 20
}
```

Every game one team played, with the opponent's rating on each row:

```json
{
  "dataset": "games",
  "teamNameContains": "Michigan",
  "includeGameContext": true,
  "maxItems": 45
}
```

Three seasons of conference games for a model:

```json
{
  "dataset": "games",
  "seasons": ["2024", "2025", "2026"],
  "conferenceGamesOnly": true,
  "maxItems": 20000
}
```

### Pricing

Pay-per-event. **$5 per 1,000 team ratings** and **$2 per 1,000 game rows**, plus $0.02 per run start and $0.003 per season file read. Game rows are priced lower because a season is 11,504 of them and NCAA box score actors already sit in that range.

| Event | Price | When |
|---|---|---|
| `team-rating` | $0.005 | Every team-season row written |
| `game-row` | $0.002 | Every game row written |
| `season-scan` | $0.003 | Each season file read, never more than the rows written |
| `team-form` | $0.003 | Form splits computed for a team with games on file |
| `schedule-strength` | $0.003 | Schedule strength computed for a team with games on file |
| `game-context` | $0.002 | Ratings found for either side of the game |

| Run | Approximate cost |
|---|---|
| Top 25 teams | $0.15 |
| All 365 teams of a season | $1.85 |
| All 365 teams with form and schedule strength | $4.03 |
| A full season of games (11,504 rows) with context | $46.04 |

New Apify accounts start with $5 in free credit.

### Free users

Free-plan runs return up to 10 rows as a preview. [Upgrade your Apify plan](https://console.apify.com/sign-up?fpr=vmoqkp) to pull whole seasons.

### Run it

1. [Create a free Apify account with $5 in credit](https://console.apify.com/sign-up?fpr=vmoqkp).
2. Open the [Barttorvik College Basketball Scraper](https://apify.com/parseforge/barttorvik-college-basketball-scraper?fpr=vmoqkp).
3. Pick ratings or games, choose the seasons and filters, then click **Start**.
4. Export the results as CSV, Excel, JSON, or XML from the **Dataset** tab, or schedule a daily run during the season.

Run it programmatically through the [Apify API](https://docs.apify.com/api/v2) (`run-sync-get-dataset-items`) or the [ApifyClient](https://docs.apify.com/api/client/js) for JavaScript and Python.

### Use with AI agents (MCP)

Give an AI agent tempo-free college basketball data through the Model Context Protocol:

```bash
claude mcp add --transport http apify "https://mcp.apify.com?tools=parseforge/barttorvik-college-basketball-scraper"
```

Then ask: *"Which Big Ten team had the best adjusted defense this season?"*, *"List Michigan's wins against top 50 opponents"* or *"Compare tempo across the ACC and the Big 12"*.

### Troubleshooting

**Why does every game appear twice?**

Because the season file records each game from both sides, once for each team, with that team's own offensive and defensive numbers. Filter by team, or keep one row per `gameKey` if you want a single row per game.

**Why is the score reversed from what I expected?**

It is not: the site writes the score winner first, so a loss reads "L, 96-62" even though the team scored 62. Every row carries `teamScore`, `opponentScore` and a signed `margin` so you never have to read the string.

**Why is the current season empty in the summer?**

Because it has not started. A season is named for the year it ends in, and the run falls back to the previous season with a warning until November.

**Why are the form and schedule strength fields missing?**

They are computed from that season's game file, so a team with no games on file gets neither, and neither block is charged.

**Why do some columns from the site not appear here?**

The site's JSON is an unlabelled array. Every field this Actor ships was matched against the site's own labelled table for a known team and a known game; four positions whose meaning that comparison did not settle were left out rather than published under a guessed name.

### FAQ

| Question | Answer |
|---|---|
| What is T-Rank? | Barttorvik's tempo-free rating system: adjusted offensive and defensive efficiency per 100 possessions, plus a win probability rating called barthag. |
| How far back does it go? | The 2008 season, which carries 341 teams; the current season carries 365. |
| Is this the same as KenPom? | No. Both are tempo-free rating systems; this Actor reads Barttorvik, which is free and public. |
| What is wins above bubble? | How many more games a team has won than a bubble team would have, given the same schedule. It is the bracket metric on the ratings row. |
| Do I get player stats? | Not in this Actor. It covers team ratings and games. |
| How current is it? | The site updates through the season; the ratings row carries the record and the game file carries every game played to date. |
| What is game score? | Barttorvik's single-number rating of a team's performance in that game, on the same scale the site shows in its results table. |
| Can I get one row per game instead of two? | Filter by team, or deduplicate on `gameKey`, which is the same for both sides of a game. |
| How many rows per run? | Free plan: 10. Paid: a whole season of games is 11,504 rows, and nineteen seasons of ratings is about 6,800. |
| Is this an official Barttorvik product? | No. It is unofficial and reads only public pages. |

### Related actors

- [ESPN College Basketball Scraper](https://apify.com/parseforge/espn-college-basketball-scraper?fpr=vmoqkp): scores, schedules and box scores from ESPN.
- [Sports Reference Scraper](https://apify.com/parseforge/hockey-reference-scraper?fpr=vmoqkp): season and career tables from the Reference family of sites.
- [TeamRankings Scraper](https://apify.com/parseforge/teamrankings-scraper?fpr=vmoqkp): team ratings, trends and betting stats across sports.
- [SportsLine Scraper](https://apify.com/parseforge/sportsline-scraper?fpr=vmoqkp): projections and picks across leagues.
- [Covers Scraper](https://apify.com/parseforge/covers-scraper?fpr=vmoqkp): odds, matchups and consensus by sportsbook.

Browse the full [ParseForge collection](https://apify.com/parseforge?fpr=vmoqkp) for more scrapers.

🆘 **Need help?** Email parseforge@protonmail.com with your run ID, your input, and what you expected.

⚠️ **Disclaimer.** This Actor is unofficial and is not affiliated with, endorsed by, or sponsored by Barttorvik, the NCAA or any conference or school. It reads only publicly available pages. Use the data in line with the site's terms and applicable law.

# Actor input Schema

## `dataset` (type: `string`):

Team ratings is one row per team per season (365 teams). Games is one row per team per game (11,504 rows in the 2026 season, each game appearing once from each side). Both writes the ratings first.

## `seasons` (type: `array`):

Seasons by the year they end in, from 2008 to the current one. Leave empty for the current season.

## `maxItems` (type: `integer`):

Free users: limited to 10 items (preview). Paid users: up to 1,000,000.

## `conferences` (type: `array`):

Keep only these conferences. On games, a row is kept when either side is in one of them.

## `teamNameContains` (type: `string`):

Keep only rows whose team name contains this text, for example "Michigan" or "State".

## `opponentNameContains` (type: `string`):

Games only. Keep only games against an opponent whose name contains this text.

## `minRank` (type: `integer`):

Team ratings only. Lowest T-Rank position to include, for example 1.

## `maxRank` (type: `integer`):

Team ratings only. Highest T-Rank position to include, for example 50 for the top 50.

## `venues` (type: `array`):

Games only. Home, away or neutral court.

## `outcomes` (type: `array`):

Games only. Keep wins, losses or both.

## `conferenceGamesOnly` (type: `boolean`):

Games only. Drop non-conference games.

## `dateFrom` (type: `string`):

Games only. Earliest game date, as YYYY-MM-DD.

## `dateTo` (type: `string`):

Games only. Latest game date, as YYYY-MM-DD.

## `sortBy` (type: `string`):

Ratings sort by T-Rank position or by a rating; games sort by date.

## `includeTeamForm` (type: `boolean`):

Team ratings only. Add the last-10 record, the home, away and neutral splits, the conference and non-conference records, and the last game played, computed from that season's games.

## `includeScheduleStrength` (type: `boolean`):

Team ratings only. Add the average opponent rank and barthag, the toughest opponent faced, wins against the top 50 and losses to teams outside the top 200.

## `includeGameContext` (type: `boolean`):

Games only. Add the season rank, barthag and record of both the team and the opponent to each game row.

## Actor input object example

```json
{
  "dataset": "team-ratings",
  "maxItems": 10,
  "conferenceGamesOnly": false,
  "sortBy": "rank",
  "includeTeamForm": false,
  "includeScheduleStrength": false,
  "includeGameContext": false
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `rows` (type: `string`):

No description

## `csv` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/barttorvik-college-basketball-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "maxItems": 10 }

# Run the Actor and wait for it to finish
run = client.actor("parseforge/barttorvik-college-basketball-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxItems": 10
}' |
apify call parseforge/barttorvik-college-basketball-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parseforge/barttorvik-college-basketball-scraper"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/72EacxhTzyeKtzOIQ/builds/1zwPu0kRMLuHyruae/openapi.json
