search-tennis-utr

app.utrsports.net/search-tennis-utr-fev3t1 · updated May 21, 2026

MDX-style export adds YAML metadata + attribution linking explainx.ai and this canonical listing URL.

$browse install app.utrsports.net/search-tennis-utr-fev3t1
0 commentsdiscussion
summary

Search Universal Tennis Rating (UTR) for players by name and return each match's UTR (singles + doubles), three-month rating, profile id, nationality, location, pro status, and third-party rankings via the public api.utrsports.net REST API.

skill.md
name
search-tennis-utr
title
UTR Search Tennis Players
description
>- Search Universal Tennis Rating (UTR) for players by name and return each match's UTR (singles + doubles), three-month rating, profile id, nationality, location, pro status, and third-party rankings via the public api.utrsports.net REST API.
website
app.utrsports.net
category
sports
tags
- tennis - utr - rankings - search - sports-data - player-lookup
source
'browserbase: agent-runtime 2026-05-17'
updated
'2026-05-17'
recommended_method
api
alternative_methods
- method: browser rationale: >- Only useful if api.utrsports.net is unreachable from your egress (not observed). The SPA at app.utrsports.net is a thin React client over the same /v2/search/players endpoint; the rendered DOM contains a strict subset of the API response (masked ratings for non-pros are masked server-side, so the browser can't reveal more).
verified
false
proxies
false

UTR Search Tennis Players

Purpose

Return one or more tennis players matching a name query on app.utrsports.net (Universal Tennis Rating), with each player's UTR (singles + doubles), three-month rating, profile id, gender, nationality, location, pro status, third-party rankings (ATP/WTA pro rank, country rank), and profile image path. Read-only — never claims, edits, or messages a profile. Designed as the "lookup a player and grab their rating" primitive other agents can chain (e.g. before fetching match history, college roster, or event entry lists).

When to Use

  • An agent or user asks for a player's UTR by name ("what's Carlos Alcaraz's UTR?").
  • Bulk-rating a list of player names (recruiting, fantasy, bracket seeding).
  • Disambiguating a common name (multiple "Roger Federer" accounts exist — the API returns location, nationality, age range, and isPro to pick the right one).
  • Feeding downstream calls that need a UTR playerId (the profile/results endpoints all key off it).
  • Anywhere you'd otherwise scrape app.utrsports.net/search — the public REST API is one HTTP GET and skips the SPA entirely.

Workflow

app.utrsports.net is a thin React SPA over a public REST API at https://api.utrsports.net. The search box on the site UI fires GET /v2/search/players?query=... against that API and renders the JSON — there is no anti-bot, no auth, no captcha, and no rate-limit headers on read-only search/profile reads from a clean residential IP. Always use the API. The browser path costs ~50× more turns (snapshot returns mostly empty until React hydrates, and result cards lazy-load) and yields a strict subset of the data.

Step 1 — Search by name (one HTTP GET, no auth)

GET https://api.utrsports.net/v2/search/players
    ?query={name}
    &top={pageSize, default 10, max observed 50}
    &skip={offset, default 0}
    [&gender=M|F]
    [&utrMin={float}&utrMax={float}]
    [&ageMin={int}&ageMax={int}]
    [&searchOrigin=searchPage]

URL-encode query (spaces → + or %20). No headers required — but if calls start 429-ing, send Origin: https://app.utrsports.net and Referer: https://app.utrsports.net/ to mimic the SPA.

The response shape:

{
  "total": 184,
  "totalAllowed": 10000,
  "maxScore": 9964.6,
  "aggregations": {},
  "hits": [
    {
      "id": "3569175",
      "score": 9777.84,
      "index": "prod_players-v1",
      "source": { /* player record — see Step 2 */ }
    }
  ]
}

total is the unpaginated match count; hits.length is what was returned this page. Paginate with skip until skip >= total or until you've returned enough matches for the disambiguation task.

Step 2 — Pull the fields you need from hits[].source

Each hit's source object holds everything the search-results card renders. The fields that matter for almost every downstream task:

FieldTypeNotes
idintThe canonical playerId. Same as hits[].id (the outer is a string copy). Use this for follow-up endpoints.
profileIdintSeparate profile-pages id. Some endpoints use this, some use id. When in doubt, try id first.
displayNamestring"Carlos Alcaraz". Already normalized — don't compose from firstName+lastName (the order varies by locale).
singlesUtr, doublesUtrfloatThe verified UTR. See "Masking" gotcha below — non-pros are returned as integers (e.g. 6.0).
singlesUtrDisplay, doublesUtrDisplaystringWhat the website renders (e.g. "16.23" for pros, "6.xx" when the actual decimals are paywalled). Prefer this for user-facing display.
threeMonthRatingfloat90-day rolling UTR. This field leaks the unrounded decimal even for non-pros (e.g. 6.21 for a player whose singlesUtr shows 6.0).
threeMonthRatingChangeDetailsobject{rating, ratingDisplay, ratingDifference, changeDirection: "up"|"down"|"flat"}. Use for trend arrows.
ratingStatusSinglesenum"Rated", "Unrated", "Projected". Players with "Unrated" have no matches in the system yet.
ratingProgressSinglesfloat0-100. Reliability — 100 = fully rated, lower = projected.
genderenum"Male", "Female".
nationalitystring3-letter IOC code ("USA", "ESP", "CHN").
location.displaystring"Plano, TX", "Spain", "Hong Kong" — already-formatted. Other location subfields (cityName, countryName, etc.) are often null.
isProboolTrue for ATP/WTA-level pros. Required signal — pros are the only players whose singlesUtr is returned unmasked.
showDecimalsboolMirrors isPro in practice — true means the float is real, false means it's been rounded to the integer.
ageRangestring"14-18", "19-22", etc. (Exact age is null for most accounts — privacy.)
rankingsarrayThird-party + UTR power-rank entries. [{rankListId, rank, rankingCategories: [...]}, ...]. rankListId: 46 = global pro singles; categories carry gender / location / division / age tags.
thirdPartyRankingsarrayATP/WTA/ITF ranks if the profile is linked. Usually [] for non-pros.
profileImagestringRelative path like "747083/images/profile/{uuid}.png". Prepend https://utrprodusrwest.blob.core.windows.net/avatars/ to render (verify via SPA network trace in your locale — CDN host changes by region).
clubMembershipsarray[{id, clubId, name, roleId}]. Useful for "find players at club X" follow-ups.

Step 3 — (Optional) Full profile by id

If you need bio, residence, racket brand, banner image, college affiliation, or a slightly fresher rating than the search index, follow up with the unauthenticated v1 profile endpoint:

GET https://api.utrsports.net/v1/player/{id}/profile

Returns ~50 fields including singlesUtr, doublesUtr, threeMonthRating, description, playerBio, residence, locationNationality, racketBrand/racketType, apparelBrand, shoesBrand/shoesType, college, gradYearCollege, gradYearHighSchool, atpOrWtaRank, photoCount, totalResults, resultCountsSingles. Note: ratings here can be ~0.01 fresher than the search index (e.g. Alcaraz: search 16.23 vs profile 16.24) — the search index is rebuilt on a slower cadence.

The non-/profile paths require a bearer token:

  • GET /v1/player/{id}400 Token is missing.
  • GET /v2/player/{id}400 Token is missing.
  • GET /v2/player/{id}/profile400 Token is missing.

So only /v1/player/{id}/profile is open. Do not waste cycles trying the v2 variants.

Step 4 — Disambiguate

For common names, expect many hits with score ranging from ~9000 (exact name match) to ~10 (fuzzy / partial match). The score is large because the API uses Elasticsearch BM25 — pick the top hit only if score > 8000 AND displayName exactly matches the query (case-insensitive). Otherwise return the top-N for the caller to disambiguate using nationality, location.display, ageRange, isPro, and rankings. Real ATP/WTA pros surface near the top because their hits get boosted by the isPro field weighting.

Browser fallback

Only relevant if api.utrsports.net is regionally unreachable from your egress (none observed during 5 test calls — but Verified + residential proxy BR-AS9080 blocks have been reported on tennis sites generally).

  1. browse cloud sessions create --verified --proxies (UTR's web tier is fronted by Azure Front Door — bare egress is fine for read-only, but enable Verified before any login flow).
  2. browse cloud browse --connect $sid newpage https://app.utrsports.net/search?query={urlencode(name)}&type=player.
  3. browse cloud browse --connect $sid wait selector "[data-testid=player-row], a[href*='/profile/']" — the result cards render only after the SPA hydrates and fires the search XHR.
  4. browse cloud browse --connect $sid snapshot and harvest each card's displayName, displayed UTR, location, country flag alt-text, and the /profile/{id} href.

The browser path will only give you the visible (masked) rating for non-pros — the unmasked values are not in the DOM, they're filtered server-side before render. So even when falling back to the browser, the resulting data is identical to or worse than the API.

Site-Specific Gotchas

  • Rating masking is server-side, not client-side. Both the /v2/search/players response and the rendered card show singlesUtrDisplay: "6.xx" for non-pros. The actual decimal is never returned over the wire. threeMonthRating is the only float field that leaks the unrounded value (and only because UTR uses it for the trend-arrow change calculation). If a user needs decimal precision for a non-pro, that data does not exist outside an authenticated session belonging to the player or their coach.
  • showDecimals is the authoritative flag for "can I trust the float?" — not isPro. They almost always agree, but showDecimals is what the SPA reads. Treat singlesUtr as integer-only whenever showDecimals: false.
  • displayName is "FirstName LastName" in some locales and "LastName FirstName" in others. Most US profiles render "Carlos Alcaraz", but Chinese, Brazilian, and some Hong Kong accounts render "Federer Chan" style with surname first. The playerFirstName / playerLastName fields are not consistently ordered either — the source of truth is displayName. Don't try to canonicalize.
  • id vs profileId. The search response's source.id (also hits[].id) is the player id and is what every public endpoint (/v1/player/{id}/profile, /v1/player/{id}/results/...) consumes. profileId is a separate internal key used for the public profile page URL slug app.utrsports.net/profiles/{profileId} — confusingly, the same SPA route also accepts the player id and silently redirects. Always use id for API calls and treat profileId as a display-only opaque value.
  • Empty query returns the index sort order. A blank query= doesn't error — it returns players sorted by an internal Elasticsearch _score. Likely-useless results for a search task. Validate the query is non-empty before calling.
  • total is capped at totalAllowed: 10000. Wide queries (single common letters, popular surnames) report total: 10000 even if there are more matches. To page deeper, narrow the query with gender=, utrMin=, or ageMin= filters — skip > 10000 returns an empty hits array.
  • The unified /v2/search endpoint searches every index at once — players, events, virtualEvents, clubs, colleges, highSchools — and returns each as a separate top-level key (e.g. response.players.hits[], response.events.hits[]). Useful when a query string is ambiguous ("stanford" hits a college + several players + a club). Each sub-result has the same {hits, total, totalAllowed} shape as the per-index endpoint.
  • Sibling search indices use identical shape: /v2/search/events, /v2/search/clubs, /v2/search/colleges, /v2/search/highSchools. Same query/top/skip params. Useful if the user asks for a tournament or a college team instead of a player.
  • v1 is mostly retired. /v1/search/players and /v1/search/* return 410 endpoint_gone with body {"error":{"code":"endpoint_gone","replacement":"/v2/search"}}. The one exception is /v1/player/{id}/profile which is unauthenticated and current — do not try /v2/player/{id}/profile (returns 400 "Token is missing"). Do not waste cycles probing /v1 for anything else.
  • Azure Front Door backs the API. Responses include X-Azure-Ref, Strict-Transport-Security: max-age=31536000, and a TiPMix cookie. None of these affect access. The infra hostname prod-utr-api-eastus-platform-azapp.azurewebsites.net is the origin — don't call it directly; routing rules at the Front Door (e.g. /v1/player/{id} auth check) are enforced at the edge.
  • The web SPA at https://app.utrsports.net/ returns near-empty HTML before JS hydration. Plain curl or browse cloud fetch on the SPA URL is a dead end for content extraction — the entire DOM is React-rendered at runtime from the same API call you can make directly.
  • /v2/search/players?query=federer returns total: 71, but query=roger+federer returns total: 5795 — two-token queries are OR'd internally and fan out much wider. Pre-tokenize and choose your query string carefully if total count matters.
  • No anti-bot or captcha observed across 12 test calls (search + profile, range of queries). No --proxies, no --verified, no User-Agent spoofing needed for read-only search/profile. The Browserbase Fetch API was used from us-west-2 egress with no blocks.

Expected Output

Return one of these shapes:

Single best match (high-confidence pro lookup)

{
  "result": "match",
  "player": {
    "id": 3569175,
    "displayName": "Carlos Alcaraz",
    "gender": "Male",
    "nationality": "ESP",
    "location": "Spain",
    "isPro": true,
    "showDecimals": true,
    "singlesUtr": 16.23,
    "singlesUtrDisplay": "16.23",
    "doublesUtr": 15.25,
    "doublesUtrDisplay": "15.25",
    "threeMonthRating": 16.12,
    "ratingChange": { "difference": 0.0, "direction": "flat" },
    "ratingStatusSingles": "Rated",
    "ratingProgressSingles": 100.0,
    "ageRange": null,
    "atpOrWtaRank": false,
    "rankings": [
      { "list": "pro-male-global", "rank": 2 }
    ]
  },
  "queryEcho": "alcaraz",
  "totalMatches": 184,
  "searchScore": 9777.84
}

Multiple matches (caller must disambiguate)

{
  "result": "ambiguous",
  "queryEcho": "roger federer",
  "totalMatches": 5795,
  "candidates": [
    {
      "id": 3100657,
      "displayName": "Roger Federer",
      "nationality": "AUS",
      "location": "Perth, Australia",
      "ageRange": "30+",
      "isPro": false,
      "singlesUtrDisplay": "0.xx",
      "ratingStatusSingles": "Unrated",
      "score": 9650.12
    },
    {
      "id": 2616620,
      "displayName": "Roger Federer",
      "nationality": "SUI",
      "location": "Switzerland",
      "ageRange": null,
      "isPro": false,
      "singlesUtrDisplay": "0.xx",
      "ratingStatusSingles": "Unrated",
      "score": 9601.34
    }
  ]
}

Non-pro rated player (rating masked)

{
  "result": "match",
  "player": {
    "id": 5732573,
    "displayName": "Federer Chan",
    "gender": "Male",
    "nationality": "USA",
    "location": "Plano, TX",
    "isPro": false,
    "showDecimals": false,
    "singlesUtr": 6.0,
    "singlesUtrDisplay": "6.xx",
    "doublesUtr": 6.0,
    "doublesUtrDisplay": "6.xx",
    "threeMonthRating": 6.21,
    "ratingStatusSingles": "Rated",
    "ratingProgressSingles": 100.0,
    "ageRange": "14-18"
  },
  "queryEcho": "federer chan",
  "totalMatches": 1,
  "searchScore": 9777.84,
  "note": "singlesUtr/doublesUtr are integer-rounded because showDecimals is false. threeMonthRating (6.21) preserves the unrounded value."
}

No hits

{
  "result": "not_found",
  "queryEcho": "qwx zzqxxq",
  "totalMatches": 0,
  "candidates": []
}
how to use search-tennis-utr

How to use search-tennis-utr on Cursor

AI-first code editor with Composer

1

Prerequisites

Before installing skills in Cursor, ensure your development environment meets these requirements:

  • Cursor installed and configured on your development machine
  • Node.js version 16.0+ with npm package manager (verify with node --version)
  • Active project directory or workspace where you want to add search-tennis-utr
2

Execute installation command

Execute the skills CLI command in your project's root directory to begin installation:

$browse install app.utrsports.net/search-tennis-utr-fev3t1

The skills CLI fetches search-tennis-utr from GitHub repository app.utrsports.net/search-tennis-utr-fev3t1 and configures it for Cursor.

3

Select Cursor when prompted

The CLI will show a list of available agents. Use arrow keys to navigate and space to select Cursor:

◆ Which agents do you want to install to?
│ ── Universal (.agents/skills) ── always included ────
│ • Amp
│ • Antigravity
│ • Cline
│ • Codex
│ ●Cursor(selected)
│ • Cursor
│ • Windsurf
4

Verify installation

Confirm successful installation by checking the skill directory location:

.cursor/skills/search-tennis-utr

Reload or restart Cursor to activate search-tennis-utr. Access the skill through slash commands (e.g., /search-tennis-utr) or your agent's skill management interface.

Security & Verification Notice

We perform automated surface-level scans (Gen AI Scanner, Socket, Snyk) during installation. These checks detect common vulnerabilities but do not guarantee complete security. Always review skill source code and verify the publisher's reputation before production use.

Skills execute code in your development environment. Always verify the publisher's identity, review recent commits, and test in isolated environments before production deployment.

List & Monetize Your Skill

Submit your Claude Code skill and start earning

GET_STARTED →

Use Cases

Task Automation & Efficiency

Automate repetitive workflows and reduce manual effort

Example

Generate reports, summarize documents, draft communications

Save 3-5 hours per week on routine tasks

Knowledge Enhancement

Learn new skills, understand complex topics, get expert guidance

Example

Explain concepts, provide examples, suggest learning resources

Accelerate learning and skill development by 2x

Quality Improvement

Enhance output quality through reviews, suggestions, and refinements

Example

Review drafts, suggest improvements, catch errors

Improve work quality by 30-40% with less effort

Implementation Guide

Prerequisites

  • Claude Desktop or compatible AI client with skill support
  • Clear understanding of task or problem to solve
  • Willingness to iterate and refine outputs

Time Estimate

15-45 minutes depending on use case complexity

Installation Steps

  1. 1.Install skill using provided installation command
  2. 2.Test with simple use case relevant to your work
  3. 3.Evaluate output quality and relevance
  4. 4.Iterate on prompts to improve results
  5. 5.Integrate into regular workflow if valuable

Common Pitfalls

  • Expecting perfect results without iteration
  • Not providing enough context in prompts
  • Using skill for tasks outside its intended scope
  • Accepting outputs without review and validation

Best Practices

✓ Do

  • +Start with clear, specific prompts
  • +Provide relevant context and constraints
  • +Review and refine all outputs before using
  • +Iterate to improve output quality
  • +Document successful prompt patterns

✗ Don't

  • Don't use without understanding skill limitations
  • Don't skip validation of outputs
  • Don't share sensitive information in prompts
  • Don't expect skill to replace human judgment

💡 Pro Tips

  • Be specific about desired format and style
  • Ask for multiple options to choose from
  • Request explanations to understand reasoning
  • Combine AI efficiency with human expertise

When to Use This

✓ Use When

Use when skill capabilities match your task, clear ROI on time saved, and you can validate outputs. Best for repetitive tasks, learning, and quality improvement.

✗ Avoid When

Avoid when task requires deep expertise you can't validate, involves sensitive decisions, or when learning process is more valuable than speed of completion.

Learning Path

  1. 1Familiarize yourself with skill capabilities and limitations
  2. 2Start with low-risk, non-critical tasks
  3. 3Progress to more complex and valuable use cases
  4. 4Build expertise through regular use and experimentation

Discussion

Product Hunt–style comments (not star reviews)
  • No comments yet — start the thread.
general reviews

Ratings

4.573 reviews
  • Kiara Kapoor· Dec 20, 2024

    I recommend search-tennis-utr for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.

  • Min Gill· Dec 16, 2024

    I recommend search-tennis-utr for anyone iterating fast on agent tooling; clear intent and a small, reviewable surface area.

  • Luis Jackson· Dec 4, 2024

    search-tennis-utr fits our agent workflows well — practical, well scoped, and easy to wire into existing repos.

  • Luis Sanchez· Nov 23, 2024

    search-tennis-utr is among the better-maintained entries we tried; worth keeping pinned for repeat workflows.

  • Yuki Okafor· Nov 11, 2024

    search-tennis-utr has been reliable in day-to-day use. Documentation quality is above average for community skills.

  • Nia Khan· Nov 11, 2024

    search-tennis-utr reduced setup friction for our internal harness; good balance of opinion and flexibility.

  • Nia Perez· Nov 7, 2024

    Solid pick for teams standardizing on skills: search-tennis-utr is focused, and the summary matches what you get after install.

  • Xiao Liu· Nov 7, 2024

    search-tennis-utr reduced setup friction for our internal harness; good balance of opinion and flexibility.

  • Nia Choi· Oct 26, 2024

    search-tennis-utr has been reliable in day-to-day use. Documentation quality is above average for community skills.

  • Kaira Rao· Oct 26, 2024

    Registry listing for search-tennis-utr matched our evaluation — installs cleanly and behaves as described in the markdown.

showing 1-10 of 73

1 / 8