# USTA Player Search Scraper (`automation-lab/usta-player-search`) Actor

Look up supplied full tennis player names or USTA IDs and export public USTA directory identities, locations, section, district, profile links and observation timestamps for roster reconciliation.

- **URL**: https://apify.com/automation-lab/usta-player-search.md
- **Developed by:** [Automation Lab](https://apify.com/automation-lab) (community)
- **Categories:** Sports
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.86 / 1,000 item extracteds

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## USTA Player Search Scraper

Look up supplied tennis player names or USTA IDs with **USTA player search** and export public directory identities for recurring roster reconciliation. Get display name, UAID, city, state, section, district, profile URL, and observation time in structured rows.

### What does this Actor do?

This Actor queries the public USTA player directory. It accepts a bounded list of full names or numeric USTA IDs, follows search pagination, and returns unique players to the default dataset. It does not fetch ratings, rankings, match results, birth dates, email addresses, or account-only information.

### Who is it for?

Club administrators can reconcile supplied roster names against public directory IDs. Tournament staff can refresh known player identifiers. Tennis data teams can join directory observations to records they already lawfully hold, using UAID rather than treating names as unique identifiers.

### Why use it?

- Preserve IDs as strings, including leading zeros in supplied IDs.
- Reduce duplicate rows across overlapping supplied queries.
- Carry the first matching query and observation timestamp into downstream tables.
- Export only the narrow public directory fields needed for identity review.

A same-name result is a candidate, not proof of a person's identity. Review city, state, section, and district before joining records.

### Getting started

1. Open the Actor input form.
2. Enter one or more full player names or numeric USTA IDs.
3. Set a global maximum for unique player rows.
4. Start the run and inspect the dataset.
5. Download JSON, CSV, or Excel through Apify, or connect the dataset to your workflow.

Example input:

```json
{"queries":["11208794"],"maxItems":100}
```

### Input parameters

| Parameter | Meaning |
| --- | --- |
| `queries` | Required array of 1–100 full names or numeric USTA IDs. |
| `maxItems` | Maximum unique players across the entire run; default 20, allowed 1–5000. |

Whitespace is trimmed and repeated whitespace is collapsed. Names are split at the first space: the first part becomes the first-name search and the rest becomes the surname search. Matching is controlled by USTA and is not guaranteed whole-field equality. Apostrophes, hyphens, accented names, and multi-part surnames are accepted. Surname-only searches and URLs are rejected.

Numeric queries use the exact UAID route. Unsupported input fails before charging the start event. Identical normalized queries are removed. Queries run sequentially in input order; later queries may not run when the global output or billing limit is reached.

### Extracted data

| Field | Meaning |
| --- | --- |
| `query` | First normalized query that found this unique player. |
| `name` | Public USTA display name. |
| `uaid` | Public USTA identifier as text. |
| `city` | Public city, or null. |
| `state` | Public state, or null. |
| `section` | Public section name, or null. |
| `district` | Public district name, or null. |
| `profileUrl` | Canonical public USTA profile link. |
| `scrapedAt` | UTC observation time in ISO 8601 format. |

Results contain one row per UAID, not one row per query. The Actor does not decide which same-name player is the intended person.

### Output example

A directory ID lookup returns the following shape. This representative directory record was observed during development; timestamps change each run.

```json
{
  "query": "11208794",
  "name": "John Smith",
  "uaid": "11208794",
  "city": "Dothan",
  "state": "AL",
  "section": "Southern",
  "district": "Alabama",
  "profileUrl": "https://www.usta.com/en/home/play/player-search/profile.html#uaid=11208794",
  "scrapedAt": "2026-10-22T12:00:00.000Z"
}
```

### How much does it cost to look up USTA players?

Pay per event: a **$0.001 start fee** per valid run plus **$0.00144 per unique player** at the BRONZE plan tier. Other Apify plan tiers may differ; check the Actor's live pricing panel.

At BRONZE, 1 player costs $0.00244, 10 players cost $0.01540, and 100 players cost $0.14500. A valid search with no results incurs only the start fee. Duplicates and failed records do not incur an item charge. Your maximum total charge can stop delivery early. No proxy subscription or USTA login is required.

### Pagination, limits, and completeness

The Actor requests pages of 51 public directory records and follows the source's reported page count. `maxItems` counts unique exported UAIDs globally, not pages or queries. No unlimited mode is offered. There is a safety ceiling of 100 pages per query; unsupported pagination or repeated pages fails explicitly rather than claiming completeness.

USTA controls directory visibility, matching, ordering, and availability. Counts and rows can change between pages. This is a live observation, not an exhaustive historical registry. Schedule repeated supplied-name/ID lookups in Apify if you need periodic refreshes; comparison and alerting must be implemented downstream.

### Errors and troubleshooting

Transient network failures, HTTP 429, and server errors receive at most three attempts with bounded backoff. Permanent HTTP errors, unexpected response formats, mismatched IDs, and malformed records fail the run. A failed run can retain partial rows; do not interpret those as complete results.

- **No results:** verify the exact name or ID in the public directory. A genuine empty response is successful and produces no item rows.
- **Too many similar names:** use the known USTA ID, or manually review the returned locations. The Actor does not accept surname-only discovery.
- **Upstream unavailable:** retry later after checking the source. This Actor has no automatic paid proxy fallback.

### Integrations

Use a dataset export to update a roster spreadsheet. In Make, Zapier, or n8n, start a run, wait for terminal success, then retrieve the dataset. Join observations by UAID and compare timestamps in your own database. Keep ambiguous name matches in a review queue rather than automatically overwriting existing identities.

### API examples

Store your Apify token in an environment variable, never in shared input or source files.

#### cURL

```bash
curl -X POST 'https://api.apify.com/v2/acts/automation-lab~usta-player-search/run-sync-get-dataset-items' \
  -H "Authorization: Bearer $APIFY_TOKEN" -H 'Content-Type: application/json' \
  -d '{"queries":["11208794"],"maxItems":100}'
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation-lab/usta-player-search').call({
  queries: ['11208794'], maxItems: 100,
});
if (run.status !== 'SUCCEEDED') throw new Error(`Run ${run.id}: ${run.status}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems({ limit: 100 });
console.log(items);
```

#### Python

```python
import os
from apify_client import ApifyClient
client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('automation-lab/usta-player-search').call(
    run_input={'queries': ['11208794'], 'maxItems': 100})
if run['status'] != 'SUCCEEDED':
    raise RuntimeError(run['status'])
print(client.dataset(run['defaultDatasetId']).list_items(limit=100).items)
```

### MCP use

For Claude Code:

```bash
claude mcp add --transport http apify \
  'https://mcp.apify.com?tools=automation-lab/usta-player-search'
```

Claude Desktop, Cursor, and VS Code configuration:

```json
{"mcpServers":{"apify":{"url":"https://mcp.apify.com?tools=automation-lab/usta-player-search"}}}
```

Authenticate through your client's supported Apify authorization flow. Example prompt: “Look up USTA ID 11208794 and show its directory name, city, and section.”

Discover actual tool names and argument schemas with scoped `tools/list`. Actor selection also adds run and storage helper tools; discovery does not authorize execution or aborts. Start once, retain the run and dataset IDs, and follow that same run. `call-actor` waits at most 45 seconds (default 30); if still running, use `get-actor-run` with bounded backoff (2, 4, 8, then at most 10 seconds) and a 120-second overall deadline. Set client timeouts above the server wait plus transport margin. After a client timeout, recover the known run rather than restarting it. At deadline report pending and stop. Report failures and partial rows honestly.

After success, fetch untransformed dataset pages with explicit limit, offset, and fields. For model context, a sensible consumer budget is 20 source rows per page, at most 100 rows and 64 KiB of serialized UTF-8 content across all pages, whichever comes first. Enforce bytes host-side before model injection; omit or summarize oversized rows with disclosure. If your client cannot intercept oversized responses, do not claim a hard byte guarantee. Track source offsets, report truncation and the next offset, and keep full exports outside model context. These consumer limits do not change Actor collection limits. Client caching and progressive discovery vary; no universal token saving is promised.

### Legality and responsible use

Use public directory data only for lawful purposes and respect USTA's terms, applicable privacy laws, retention limits, and the rights of the people represented. Public visibility does not grant unlimited reuse. Do not use this tool for harassment, sensitive profiling, or attempting to access private accounts. This Actor is independent and is not endorsed by USTA. No AI is used during extraction or to generate player records. Results remain in your Apify run storage until you delete them or your platform retention policy removes them. Delete datasets and key-value stores through Apify Console/API; there is no cross-run roster cache. For help, open an issue on this Actor's Apify page.

Failed operations send sanitized diagnostic input, exceptions, and Actor/build/run IDs to our private GlitchTip service for repair. Secret fields and URL query strings are removed. Reports are retained for 30 days. Supplied names/IDs may remain in sanitized diagnostic input; do not submit confidential roster material without an appropriate basis.

### Frequently asked questions

**Does it include ratings or match results?** No. It exports directory identity and public location only.

**Does it require a USTA account?** No. It uses the public directory without login or account cookies.

**Can it search horse racing records?** No. This is United States Tennis Association data, not trotting or horse records.

**Can it uniquely identify someone by name?** No. Different people can share a name. Use UAID and manual verification.

**Does scheduling detect changes automatically?** No. Apify scheduling reruns your supplied queries; use a downstream comparison workflow for changes and alerts.

### Related Actors

For separate professional-tennis ranking research, see [WTA Tennis Rankings Scraper](https://apify.com/automation-lab/wta-rankings). Its ranking output is a different product and is not included in this Actor.

# Changelog

This Actor's version history is a separate document: https://apify.com/automation-lab/usta-player-search/changelog.md

# Actor input Schema

## `queries` (type: `array`):

Supply 1–100 full player names or numeric USTA IDs. Whitespace is normalized. Names are split at the first space into first name and remaining surname, using USTA public search matching (not guaranteed whole-field equality). IDs request the exact UAID. Queries run in order; identical normalized queries are removed. No surname-only or broad directory discovery.

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

Global run limit on unique UAIDs across all queries, after deduplication. Default 20; range 1–5000. Zero and unlimited are unsupported. Later queries may not run once this limit or your charge limit is reached. Each row records the first query that found that player.

## Actor input object example

```json
{
  "queries": [
    "11208794"
  ],
  "maxItems": 20
}
```

# Actor output Schema

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

Unique public USTA player identities exported during this run.

# 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 = {
    "queries": [
        "11208794"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation-lab/usta-player-search").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 = { "queries": ["11208794"] }

# Run the Actor and wait for it to finish
run = client.actor("automation-lab/usta-player-search").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 '{
  "queries": [
    "11208794"
  ]
}' |
apify call automation-lab/usta-player-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation-lab/usta-player-search"
        }
    }
}
```

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/Ops9SYhpCumSQjcGY/builds/xJ7nCGcAVfFbeHOwQ/openapi.json
