Skip to content
OFF SZN Network (opens in new tab)
Boys Hoops Current
LoginSign up free
OFF SZN Hoops
HomeNewsRankingsDatabaseEventsCommitmentsForums
Ctrl K
OFF SZN Hoops

High school basketball recruiting, rankings, and commitments nationwide, every class — with full local coverage in the Live states below.

Explore

  • Rankings
  • Recruiting Classes
  • Recruiter Rankings
  • Commitments
  • Commitment Trends
  • Crystal Ball
  • Recruiting Wire
  • Rankings Movers
  • News
  • Forums
  • Submit a Tip
  • Submit a Player
  • Events
  • Film Room
  • Trainers
  • Almanac
  • Saved Articles

Company

  • About
  • For Coaches
  • For Athletes
  • What's New
  • Coverage
  • Methodology
  • Scouting Reports
  • Pricing
  • FAQ
  • Contact
  • Install App
  • API & Embeds
Email updates

Commitment alerts and recruiting updates by email.

Free forever. Unsubscribe anytime.

Got a scoop?
tips@offsznnetwork.com

Coverage by State

ArizonaLiveCaliforniaLive+ 49 more · expanding nationwide →
PrivacyData RightsExportAccount DeletionCookiesYour Privacy ChoicesRemove a profileYouth safetyTermsCommunity GuidelinesDMCAAccessibilityCorrectionsPressSitemapRSS

© 2026 OFF SZN Network. All rights reserved.

Coast to coast

HomeRankingsNewsCommitsJoin
  1. Home
  2. Developers
Developers

OFF SZN API & Embeds

Free, read-only JSON API and iframable widgets for OFF SZN player profiles, composite rankings, commitments, news, and more. No API key required for the free tier. Attribution required. Versioned at /api/v1.

Rate limit
60 req/min/IP
JSON free tier · no key
Endpoints
15 GET routes
Stable under /api/v1
CORS
Enabled (*)
Browser fetch from any origin

Limits & honesty

  • Free tier: 60 requests / minute / IP for JSON routes. PDF is capped at 30 / min / IP. Exceeding returns 429 with code: rate_limited, a Retry-After header, and retryAfter (seconds) in the body.
  • No key required today. A future partner key header (X-OFFSZN-API-Key) is reserved; free tier ignores it.
  • Public card fields only — no scout bios, internal notes, or PII. Responses use explicit field allowlists.
  • Pagination: limit defaults to 25 (max 100 on most routes); offset is capped at 10,000.
  • Caching: successful JSON responses are edge-cached for 15 seconds (then served stale for up to 30 seconds while they refresh); the player PDF for 5 minutes. Error responses are never edge-cached.
  • Coverage: rankings and player depth vary by state and class year. Empty lists are valid JSON with total: 0, not 404s.

Endpoint catalog

MethodPathDescriptionQuery
GET/api/v1/playersList players (card fields)state, classYear, position, school, q, limit, offset
GET/api/v1/players/:idSingle player + composite ranks—
GET/api/v1/players/:id/timelineRecruiting timeline eventslimit
GET/api/v1/players/:id/articlesNews tagged to a player—
GET/api/v1/players/:id/pdfOne-pager PDF (binary; 30/min)—
GET/api/v1/rankingsComposite rankings feedsport, gender, state, classYear, position, limit, offset
GET/api/v1/commitmentsLatest commitmentsstate, classYear, limit, offset
GET/api/v1/newsPublished headlines + summariesstate, category, sport, q, limit, offset
GET/api/v1/eventsTournaments / events windowstate, from, to, circuit, limit, offset
GET/api/v1/collegesColleges by commit volume (limit default 50, max 200)q, limit, offset
GET/api/v1/colleges/:slugOne college: commits, offers, alumnigender
GET/api/v1/schools/:slugOne high school: roster and alumni commitssport, gender
GET/api/v1/team-rankingsProgram recruiting class rankssport, classYear, state, gender, sortBy, limit, offset
GET/api/v1/transfer-portalPortal entriessport, status, limit, offset
GET/api/v1/alumniGraduated / alumni prospectsstate, classYear, limit, offset

Detailed examples

GET/api/v1/players/:id

Fetch a single player profile + their composite ranking. Public card fields only. Sample is abridged and uses placeholder values; the live response adds measurables, offers, visits, source rankings, stats, video and team history.

Try it
https://offsznhoops.com/api/v1/players/cmo9lw9p00001jw047ke18g3e (opens in new tab)
Sample response
{
  "apiVersion": "v1",
  "data": {
    "id": "cmo9lw9p00001jw047ke18g3e",
    "firstName": "First",
    "lastName": "Last",
    "position": "SG",
    "classYear": 2027,
    "starRating": 4,
    "highSchool": "High School Name",
    "state": "AZ",
    "committedTo": null,
    "composite": {
      "compositeRating": 90.5,
      "nationalRank": 12,
      "positionRank": 3,
      "stateRank": 1,
      "updatedAt": "2026-05-01T12:00:00.000Z"
    },
    "url": "https://offsznhoops.com/players/cmo9lw9p00001jw047ke18g3e",
    "attribution": "Data via OFF SZN Hoops · offsznhoops.com"
  }
}
GET/api/v1/rankings

List rankings, filterable by state, classYear, and position. Paginated via offset. rank is the national composite rank; boardRank is the row's place in this filtered, paged list. Sample values are placeholders.

ParamDescription
state2-letter code, e.g. AZ
classYearClass year, e.g. 2027
positionPG, SG, SF, PF, C
sportbasketball (default), football, baseball, soccer, volleyball
genderboys (default) or girls — ranks are per sport + gender board
limit1–100 (default 25)
offsetPagination offset (max 10_000)
Try it
https://offsznhoops.com/api/v1/rankings?state=AZ&classYear=2030&limit=25 (opens in new tab)
Sample response
{
  "apiVersion": "v1",
  "filters": {
    "sport": "basketball",
    "gender": "boys",
    "state": "AZ",
    "classYear": 2027,
    "position": null
  },
  "pagination": {
    "offset": 0,
    "limit": 25,
    "total": 87
  },
  "data": [
    {
      "rank": 12,
      "boardRank": 1,
      "classYear": 2027,
      "positionRank": 3,
      "stateRank": 1,
      "composite": 90.5,
      "player": {
        "id": "cmo9lw9p00001jw047ke18g3e",
        "firstName": "First",
        "lastName": "Last",
        "starRating": 4,
        "position": "SG",
        "classYear": 2027,
        "state": "AZ",
        "highSchool": "High School Name",
        "city": "City",
        "status": "uncommitted",
        "committedTo": null,
        "imageUrl": null,
        "highSchoolLogoUrl": null,
        "committedToLogoUrl": null,
        "url": "https://offsznhoops.com/players/cmo9lw9p00001jw047ke18g3e"
      }
    }
  ],
  "attribution": "Data via OFF SZN Hoops · offsznhoops.com"
}
GET/api/v1/commitments

Latest commitments (event-sourced). Estimated import dates surface as null date + isDateEstimated: true. Sample is abridged; values are placeholders.

ParamDescription
state2-letter code
classYearClass year filter
limit1–100 (default 25)
offsetPagination offset
Try it
https://offsznhoops.com/api/v1/commitments?state=AZ&limit=10 (opens in new tab)
Sample response
{
  "apiVersion": "v1",
  "attribution": "OFF SZN Hoops · offsznhoops.com",
  "url": "https://offsznhoops.com/commitments",
  "total": 42,
  "limit": 10,
  "offset": 0,
  "data": [
    {
      "id": "EVENT_ID",
      "title": "Committed to College Name",
      "date": "2026-04-12T00:00:00.000Z",
      "isDateEstimated": false,
      "college": "College Name",
      "collegeSlug": "college-name",
      "collegeUrl": "https://offsznhoops.com/colleges/college-name",
      "collegeLogoUrl": null,
      "player": {
        "id": "cmo9lw9p00001jw047ke18g3e",
        "firstName": "First",
        "lastName": "Last",
        "position": "SG",
        "classYear": 2027,
        "state": "AZ",
        "committedTo": "College Name",
        "url": "https://offsznhoops.com/players/cmo9lw9p00001jw047ke18g3e"
      }
    }
  ]
}

curl examples

Player by id
curl -sS "https://offsznhoops.com/api/v1/players/cmo9lw9p00001jw047ke18g3e"
Rankings slice
curl -sS "https://offsznhoops.com/api/v1/rankings?state=AZ&classYear=2030&limit=10"

Error responses

Errors share a stable JSON envelope on every /api/v1/* route (including PDF). The human string is always in error; structured clients should branch on code. Every error includes apiVersion, docs (/developers), CORS *, and Cache-Control: private, no-store so failures are never edge-cached.

StatuscodeWhen
404not_foundUnknown player id (or other missing resource)
404invalid_idMalformed id — use the id from list/rankings feeds
400invalid_paramstate is not a two-letter US code (or all), or classYear is not a four-digit year · names the key in param
403LICENSE_MODULE_DISABLEDWhite-label install without the api_v1 module · may include module + tier
429rate_limitedOver free-tier budget (JSON 60/min · PDF 30/min) · Retry-After header + retryAfter body (seconds)
503unavailableTransient backend fault · retry with backoff
404 sample
{
  "apiVersion": "v1",
  "error": "Player not found. Confirm the id via GET /api/v1/players or GET /api/v1/rankings.",
  "code": "not_found",
  "docs": "/developers"
}
429 sample
{
  "apiVersion": "v1",
  "error": "Rate limited. Free tier is 60 req/min.",
  "code": "rate_limited",
  "docs": "/developers",
  "retryAfter": 13
}

No secrets in responses. Errors never include stack traces, env values, or internal query details. Empty list results are 200 with total: 0, not errors.

Embed widgets

Drop an iframe into any article. Widgets are noindex, carry attribution in the footer, and open profile links with target=_top so readers leave the iframe cleanly. Free-tier JSON under /api/v1/* is 60 req/min/IP (see Limits above); embed HTML pages render on request from a 5-minute server cache and are not the same rate-limit bucket.

Copy-paste snippets

Paste into CMS HTML or a static page. Attribution footer is built into each widget — do not strip the chrome. Pick a state and lane on the widgets page.

Rankings /embed/rankings?state=AZ&classYear=2030
<iframe src="https://offsznhoops.com/embed/rankings?state=AZ&amp;classYear=2030" title="OFF SZN rankings" width="100%" height="520" style="border:0;max-width:640px" loading="lazy"></iframe>
<p style="margin:4px 0 0;font:12px/1.4 system-ui,sans-serif"><a href="https://offsznhoops.com/rankings?state=AZ&amp;classYear=2030&amp;utm_source=embed&amp;utm_medium=attribution&amp;utm_campaign=widget-rankings">Arizona Class of 2030 basketball rankings</a> from OFF SZN Hoops</p>
Commitments /embed/commitments?state=AZ
<iframe src="https://offsznhoops.com/embed/commitments?state=AZ" title="OFF SZN commitments" width="100%" height="520" style="border:0;max-width:640px" loading="lazy"></iframe>
<p style="margin:4px 0 0;font:12px/1.4 system-ui,sans-serif"><a href="https://offsznhoops.com/commitments?utm_source=embed&amp;utm_medium=attribution&amp;utm_campaign=widget-commitments">College basketball commitments</a> from OFF SZN Hoops</p>
Player card (live sample id) /embed/player/cmo9lw9p00001jw047ke18g3e
<iframe src="https://offsznhoops.com/embed/player/cmo9lw9p00001jw047ke18g3e" title="OFF SZN player card" width="100%" height="320" style="border:0;max-width:560px" loading="lazy"></iframe>
<p style="margin:4px 0 0;font:12px/1.4 system-ui,sans-serif"><a href="https://offsznhoops.com/players/adan-diggs-2027?utm_source=embed&amp;utm_medium=attribution&amp;utm_campaign=widget-player">Full player profile</a> from OFF SZN Hoops</p>

Empty & error contract

  • Empty scope (true zero): compact frame with an Open full site CTA — never demo rankings, commits, or player cards.
  • Load failure: says temporarily unavailable (not “no data yet”) and still offers Retry + open full site.
  • Player embeds: require a real player id from GET /api/v1/rankings or GET /api/v1/players — sample below uses live id cmo9lw9p00001jw047ke18g3e (refreshed hourly).
  • API rate limit: free JSON tier is 60 requests / minute / IP (429 + code: rate_limited). PDF is 30/min. Embeds are HTML, not that JSON bucket.
GET/embed/rankings

Top-N rankings table. Omit state (or use ALL) for national. limit 5–25 (default 10). Empty filters show an open-site CTA — no invented rows.

Try it
https://offsznhoops.com/embed/rankings?state=AZ&classYear=2030 (opens in new tab)
Embed code
<iframe src="https://offsznhoops.com/embed/rankings?state=AZ&amp;classYear=2030" title="OFF SZN rankings" width="100%" height="520" style="border:0;max-width:640px" loading="lazy"></iframe>
<p style="margin:4px 0 0;font:12px/1.4 system-ui,sans-serif"><a href="https://offsznhoops.com/rankings?state=AZ&amp;classYear=2030&amp;utm_source=embed&amp;utm_medium=attribution&amp;utm_campaign=widget-rankings">Arizona Class of 2030 basketball rankings</a> from OFF SZN Hoops</p>
GET/embed/commitments

Latest commitments ticker. state optional; limit 5–25. Estimated import dates never display as real commit days.

Try it
https://offsznhoops.com/embed/commitments?state=AZ (opens in new tab)
Embed code
<iframe src="https://offsznhoops.com/embed/commitments?state=AZ" title="OFF SZN commitments" width="100%" height="520" style="border:0;max-width:640px" loading="lazy"></iframe>
<p style="margin:4px 0 0;font:12px/1.4 system-ui,sans-serif"><a href="https://offsznhoops.com/commitments?utm_source=embed&amp;utm_medium=attribution&amp;utm_campaign=widget-commitments">College basketball commitments</a> from OFF SZN Hoops</p>
GET/embed/player/:id

Single-player card for articles and newsletters. height ~320 works well. Example id is a live top-ranked player (refreshed hourly).

Try it
https://offsznhoops.com/embed/player/cmo9lw9p00001jw047ke18g3e (opens in new tab)
Embed code
<iframe src="https://offsznhoops.com/embed/player/cmo9lw9p00001jw047ke18g3e" title="OFF SZN player card" width="100%" height="320" style="border:0;max-width:560px" loading="lazy"></iframe>
<p style="margin:4px 0 0;font:12px/1.4 system-ui,sans-serif"><a href="https://offsznhoops.com/players/adan-diggs-2027?utm_source=embed&amp;utm_medium=attribution&amp;utm_campaign=widget-player">Full player profile</a> from OFF SZN Hoops</p>

Attribution

Free tier requires a visible attribution link to offsznhoops.com on the page or article using our data. API responses include an attribution string you can render verbatim. Embed widgets carry attribution natively.

Partner / commercial use

The free tier is public and no-key. It is rate-limited and attribution-required. If you are redistributing data at product scale, need higher throughput, or want a named contact, reach out — free tier stays available either way.

  • Free-tier rate limits (honest): JSON routes under /api/v1/* are 60 requests / minute / IP (enforced in shared withV1). Player PDF is 30 / minute / IP. Over budget returns 429 with code: rate_limited, Retry-After, and retryAfter (seconds).
  • Embeds require attribution: iframes under /embed/* already show a footer credit. If you build a custom UI from the API, keep a visible link to offsznhoops.com (or render the response attribution string). Do not strip embed chrome or re-skin widgets to hide the source.
  • Commercial / higher limits: for elevated caps, bulk historical dumps, webhook delivery, or SLA-style access, email partners@offsznnetwork.com or hello@offsznnetwork.com. Include expected volume, use case, and contact name.
Contact partners →

No invented partner tiers on this page — we only document limits the free tier actually enforces today.

Share
Live6,300+recruits tracked3stories this week21,000+schools covered· updated Oct 27, 2026