# NBA Injury Report PDF Extractor with Source Page Evidence (`zinin/sports-injury-report-pdf-extractor`) Actor

Extract player status, team, game date and injury-report reason from supplied NBA-format digital PDFs, preserving page and row evidence.

- **URL**: https://apify.com/zinin/sports-injury-report-pdf-extractor.md
- **Developed by:** [Tim Zinin](https://apify.com/zinin) (community)
- **Categories:** Games
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.85 / 1,000 player report row delivereds

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

## NBA Injury Report PDF Extractor

Turn a supplied NBA-format injury-report PDF into player rows with the reported
status, reason, team, game date and source page. Use the output in sports research,
availability dashboards or an existing data pipeline. This is an independent tool,
not affiliated with the NBA. It does not diagnose injuries or authenticate reports.

### Quick start

For a labelled example without downloading anything:

```json
{ "demo": true }
```

For a real historical public NBA document:

```json
{
  "pdfUrl": "https://ak-static.cms.nba.com/referee/injury/Injury-Report_2026-02-05_10_30AM.pdf",
  "maxPlayers": 100
}
```

The example report is historical, not today's injury list. Supply the report URL
you want processed. Set a finite **Max total charge** before running.

If your PDF has no public URL, supply its standard padded base64 bytes through
`pdfBase64` instead. Do not include a data-URL prefix, whitespace or `pdfUrl` too.
`maxPlayers` is optional and defaults to 1,000. Demo mode accepts only `demo:true`.

### Results

Each `injury_report_entry` contains the source's player name (surname first),
team, matchup, game date, participation status, reason and report timestamp.
`sourcePages` and `sourceRows` identify where the entry was extracted; the PDF's
SHA-256 identifies its exact bytes. Names and reasons are not translated or
reclassified. Multi-line reasons and continuations across pages are preserved.

`team_report_status` means the source explicitly said **NOT YET SUBMITTED**.
It is not evidence that a team has no injuries. These rows are unbilled.

`parse_diagnostic` explains an input, download, parsing or budget problem.
If any extraction ambiguity remains, all player rows from that PDF are withheld.
The run fails with a diagnostic; partial source text is not delivered as valid data.

The Dataset contains separate player and diagnostic rows, not a single nested
report. Filter on `recordType` and `isDemo` before adding rows to a production feed.

### Charging and limits

The unit is one delivered real player row, using the price shown in Pricing.
Demo rows, team submission statuses and diagnostics do not request result charges.
A platform start charge may still apply.

The Actor checks the remaining budget before downloading and before every paid
row. It stops at the player or spending limit and identifies remaining rows.
If a write or charge acknowledgement is lost, it stops rather than retrying.
In a failed run, a row or charge may already exist: inspect the Dataset and run
charges before starting again. Automatic resurrection is not supported; a new run
is independent and may charge for the same document again.

Supported input is one digital PDF, up to **10 MiB, 20 pages and 1,000 physical
table rows**, in the NBA seven-column injury report layout. Minimum run memory is
1,024 MB, covering the Node process and the separately limited Python worker. Source download has a
20-second overall deadline; parsing runs under a separate resource limit.
Public HTTPS on port 443 is supported, with up to three redirects. Private network
addresses, cookie/login flows and compressed HTTP response bodies are rejected.
The recorded URL omits any query parameters; use the content hash for provenance.

Scanned PDFs, OCR, arbitrary table layouts and archive crawling are not included.
The game time has an ET label but no AM/PM, so no UTC start time is guessed. The
report timestamp's timezone is not specified in the supported source layout.
Text-layer extraction does not certify visual authenticity or current player health.

Report a problem in the Actor's Issues tab with the run ID and a public sample
when possible. Avoid sharing private documents or signed access URLs in public.

# Actor input Schema

## `demo` (type: `boolean`):

True returns invented example data without downloading a PDF or charging player results. Supply no other fields.

## `pdfUrl` (type: `string`):

Direct public PDF URL. HTTPS port 443 only; no login, private networks or cookies. Up to three redirects. Supply this or pdfBase64, never both.

## `pdfBase64` (type: `string`):

Alternative to a public URL: standard padded base64 of the PDF bytes, without a data: prefix or line breaks. Maximum decoded size 10 MiB.

## `maxPlayers` (type: `integer`):

Optional, defaults to 1000. Applied after the full document passes validation. Also set a finite Max total charge.

## Actor input object example

```json
{
  "demo": true
}
```

# Actor output Schema

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

Inspect recordType and isDemo. If delivery fails, inspect this Dataset and run charges before rerunning.

# 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 = {
    "demo": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("zinin/sports-injury-report-pdf-extractor").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 = { "demo": True }

# Run the Actor and wait for it to finish
run = client.actor("zinin/sports-injury-report-pdf-extractor").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 '{
  "demo": true
}' |
apify call zinin/sports-injury-report-pdf-extractor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,zinin/sports-injury-report-pdf-extractor"
        }
    }
}
```

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/04Cv8V5ET9mcPZ0Pi/builds/PJj0GJZvSrP98X0tU/openapi.json
