SportFeeds API Documentation

Real-time, verified sports posts from X — filtered by league, team, player, game, or geo. Bring your own X API key, pay only for the data you query.

Quick Start
Get your first API response in under a minute
curl -H "Authorization: YOUR_API_KEY" "https://api.sportfeeds.com/v1/posts?league=NFL"
Sign up for an API keyFree plan includes 200 API calls / month
Real-time Feeds

Posts indexed within seconds of going live.

Verified Data

Tagged with players, teams, leagues, and games.

Low Latency

Sub-second p95 from cached endpoints.

Authorization

All SportFeeds API endpoints require authentication via the Authorization header.

Authentication Method
API Key via Authorization header
curl -H "Authorization: YOUR_API_KEY" "https://api.sportfeeds.com/v1/posts?league=NFL"

Manage your keys from the Dashboard.

For AI Agents

/agents.md is a complete, agent-ready integration guide: authentication, every parameter, league and sport codes, ID translation, the engagement rating, error handling, quota hygiene, polling patterns, a ready-made tool schema, and TypeScript/Python reference clients. Drop it into your repo and a coding agent can integrate SportFeeds without further instruction.

Claude Code
Pull the guide into the repo, then reference it from CLAUDE.md.
1. Fetch the guide
mkdir -p docs && curl -s https://sportfeeds.com/agents.md \
  -o docs/sportfeeds-agents.md
2. Append to CLAUDE.md
## SportFeeds API
Full integration guide: @docs/sportfeeds-agents.md

- Base URL: https://api.sportfeeds.com/v1 — the ONLY content endpoint is GET /posts.
- Auth: header "Authorization: Bearer $SPORTFEEDS_API_KEY". Server-side only.
- List params are PLURAL and comma-separated: leagues=, sports=, teams=, players=, sources=.
- Never call /posts/leagues, /posts/teams, /posts/players, /posts/games,
  /posts/nearby or /posts/trending — they return 410.
- "football" means soccer; the NFL game is "americanfootball".
- Poll incrementally with since=<created_at of newest post seen>. Never re-page history.
- If a response has a non-empty warnings[] array, the query is wrong — fix it, don't ship it.

Then add SPORTFEEDS_API_KEY=… to your .env (and .gitignore it).

Cursor / Windsurf
The guide is already written as agent rules — save it as one.
Install as a project rule
mkdir -p .cursor/rules && curl -s https://sportfeeds.com/agents.md \
  -o .cursor/rules/sportfeeds.md

For Windsurf, write it to .windsurfrules instead.

Custom GPT / Assistants API
Actions schema plus code-only instructions.

1. Add openapi.json as the action schema.

2. Set authentication to API Key → Bearer.

3. Paste the parameter and league/sport code sections of agents.md into the instructions so the model sends codes, not names.

Any tool-calling framework
One tool covers every retrieval mode.

Register the sportfeeds_get_posts JSON schema from agents.md and paste the parameter reference, code lists and rating scale into the system prompt.

Mode is inferred from the parameters, so the model should make one combined call — never fan out across leagues, teams and media types.

Video playback & design practices

Raw X video URLs are hotlink-protected: they often work in preview but fail in incognito, third-party embeds, or mobile webviews. Route every video through the proxy:

https://api.sportfeeds.com/v1/video-proxy?url=%3Cmedia.url%3E

Always render the X icon in the top-right of a post card linking to the original post, keep author attribution, and link the timestamp to post_url. See the full guide in agents.md §10.

Rules agents get wrong most often
  • List parameters are plural: leagues, sports, teams, players, sources.
  • football means soccer; the NFL game is americanfootball.
  • Pass league/sport codes only — never league names or provider IDs.
  • Unknown parameters are ignored but return a warnings[] array and an X-SportFeeds-Warning header. Treat that as a build error.
  • Poll with since; responses cache for 60s, so faster polling only burns quota.
  • 400 / 401 / 402 / 410 are terminal — retry only 429, 503 and 5xx, with backoff.
GET

/posts

Unified

One endpoint, six modes. Filter by league, team, player, game, geo, or omit everything to get trending. Mode is auto-selected by which params you pass.

Overview

Endpoint
GET https://api.sportfeeds.com/v1/posts
Query Modes
Trending
GET /v1/posts
By League
GET /v1/posts?league=NFL,NBA
By Team(s)
GET /v1/posts?id_type=espn_guid&teams=...,...
By Player(s)
GET /v1/posts?id_type=espn_guid&players=...,...
By Game
GET /v1/posts?id_type=espn_guid&match=teamA,teamB&start_time=2024-01-15T20:00:00Z
Nearby (Geo)
GET /v1/posts?lat=40.71&lng=-74.00&radius_km=50
Parameters
ParameterRequiredTypeExampleDescription
leagues
OptionalArray<String> (CSV)NFL,NBAComma-separated league codes, or `ALL`. Supported codes: NFL, NCAAFB, NBA, WNBA, NCAAMB, MLB, NHL, PGA, GOLF, EPL, MLS, FIFA, SOCCER, LALIGA, BUNDESLIGA, SERIEA, LIGUE1, UCL, SAPREMIERSHIP, ISL, CRICKET, IPL, SA20, RUGBY, URC, SUPERRUGBY, SIXNATIONS, RWC, MMA, UFC, PFL, DPWORLDTOUR, SUNSHINETOUR. Case-insensitive.
sports
OptionalArray<String> (CSV)football,basketballFilter to one or more parent sports: americanfootball, football, basketball, baseball, hockey, golf, cricket, rugby, mma, tennis, boxing, motorsport, athletics, cycling, wrestling. Case-insensitive. `football` means association football (soccer) — the NFL/NCAA game is `americanfootball`. `soccer` is still accepted as an alias for `football`. Returns posts across all leagues under those sports. Combine with `leagues` to narrow further. Invalid values return a 400 error.
teams
OptionalArray<String> (CSV)s:40~l:46~t:13Team IDs (≤10). Pair with `id_type`.
players
OptionalArray<String> (CSV)1f6592b3-...Player IDs (≤100). Pair with `id_type`.
id_type
OptionalStringespn_guidID system used by `teams`/`players` (espn_guid, espn_uid, sportradar, code, ...)
match
OptionalStringteamA,teamBTwo team IDs comma-separated; combined with `start_time` to query a specific game.
start_time
OptionalISO timestamp2024-01-15T20:00:00ZGame start time (paired with `match`).
include_pregame
OptionalBooleantrueInclude pregame posts when querying a game.
lat
OptionalFloat40.7128Latitude (with `lng` and optionally `radius_km`).
lng
OptionalFloat-74.0060Longitude.
radius_km
OptionalInteger50Search radius in km (default 145, max 4830).
category
OptionalStringnewsFilter by post category: news, highlight, other.
news_type
OptionalString (CSV)injury,tradeFilter news posts by type: injury, trade, signing, cut, suspension, contract_extension, roster_move, return_from_injury, retirement, coaching_change, draft, other.
news_status
OptionalStringverifiedFilter news posts by status: verified or rumor.
news_origin
OptionalStringbreakingFilter news posts by origin: breaking (first to report) or relaying (re-reporting others).
include_news
OptionalBooleantrueInclude the news classification fields (category, news_type, news_status, news_origin, news_attribution) on each post. Automatically enabled when any news filter is used.
media_type
OptionalStringvideoFilter by media type: photo, video, gif, animated_gif, none
aspect_ratio
OptionalStringlandscapeFilter by aspect ratio: landscape, portrait, square
min_score
OptionalInteger5Minimum engagement score (0–9). 7+ = top performing, 8–9 = viral.
min_duration
OptionalInteger (ms)10000Minimum video duration in milliseconds.
highlight
OptionalBooleantrueReturn only highlight clips.
has_player
OptionalBooleantrueReturn only posts with at least one tagged player.
custom_sources
OptionalBooleantrueInclude posts from your custom sources.
sources
OptionalArray<String> (CSV)FIFAWorldCup,SkySportsReturn posts only from these sources (max 500). Accepts X.com handles (case-insensitive) or numeric X.com account IDs. Public sources are open to all; private custom sources require them to be enabled on your account.
user_location
OptionalStringUSEnd-user region as an ISO 3166-1 alpha-2 country code (e.g. US, ZA). Returns only content from sources cleared for viewing in that region; sources not marked viewable there are excluded. An invalid code returns a 400 error.
sort
OptionalStringrecentSort order: recent, top, trending.
since
OptionalISO timestamp2024-01-15T00:00:00ZReturn posts created after this timestamp.
since_id
OptionalString1879726815913861526Return posts created after this post id.
limit
OptionalInteger10Items per page (max 50).
page
OptionalInteger1Page number.
Data Points

AttributeParent ElementTypeDescription
iditems[]StringNative X post id.
post_urlitems[]StringDirect URL to the post on X.
textitems[]StringPost body text.
created_atitems[]ISO timestampOriginal post timestamp (UTC).
media_typeitems[]Stringvideo | photo | gif | animated_gif | none
mediaitems[]Array<MediaObject>Attached media; see Media Object below.

Errors
StatusCodeMeaning & recommended action
400INVALID_PARAMETERBad / missing param. Validate input before retrying.
400SINCE_ID_NOT_FOUNDReference post unavailable. Drop `since_id` and retry.
401UNAUTHORIZEDMissing or invalid API key.
403FORBIDDENEndpoint or league not on your plan.
404NOT_FOUNDNo teams/players matched IDs.
429RATE_LIMITEDMonthly limit / burst exceeded. Back off.
500INTERNAL_ERRORRetry with exponential backoff.

Try it out

Sign in to test API calls with your key.

Sign In / Get Started Free

Example Response

{
"pagination": {
"page": 1,
"limit": 10,
"has_next": true,
"has_prev": false
},
"items": [
{
"id": "1879726815913861526",
"post_url": "https://x.com/NFLonFOX/status/1879726815913861526",
"text": "Patrick Mahomes throws his 3rd TD of the game! 🏈",
"created_at": "2024-01-15T20:45:00Z",
"media_type": "video",
"media": [
{
"type": "video",
"url": "https://video.twimg.com/...mp4",
"preview_image_url": "https://pbs.twimg.com/...jpg",
"width": 1280,
"height": 720,
"duration_ms": 24500
}
],
"author": {
"username": "NFLonFOX",
"name": "NFL on FOX",
"profile_image_url": "https://pbs.twimg.com/profile_images/...jpg",
"verified": true
},
"players": [
{
"espn_guid_id": "1f6592b3-ff53-d321-8dc5-6038d48c1786",
"sportfeeds_id": 90000001,
"name": "Patrick Mahomes"
}
],
"teams": [
{
"espn_guid_id": "s:20~l:28~t:12",
"sportfeeds_id": 90000050,
"name": "Kansas City Chiefs"
}
]
}
]
}
GET

/account/information

Free

Retrieve your company information, billing cycle, and current API usage. Free — call as often as needed.

Example Response
{
  "company": { "name": "Acme Sports Inc", "plan": "paid", "subscription_status": "active" },
  "billing_cycle": {
    "current_period_start": "2026-02-07T20:16:36+00:00",
    "current_period_end":   "2026-03-07T20:16:36+00:00"
  },
  "usage": { "current_calls": 12450 }
}

Sign in to test this endpoint.

Sign In
GET

/account/x-ids

Returns post IDs that should be deleted from your storage to remain compliant with the X platform's developer agreement. Recommended polling cadence depends on your plan (daily / weekly / monthly).

Example Response
{
  "ids_to_delete": ["1846572934857291245", "1846572934857291246"],
  "as_of": "2026-04-30T05:00:00Z"
}

Sign in to test this endpoint.

Sign In
GET

/account/sources

Returns every source your account can query, tagged as default (globally available) or custom (added to your company). Each source includes a geo_availability block listing ISO 3166-1 alpha-2 country codes where the source is explicitly viewable or blocked. Includes a counts block for quick verification.

A source's source_type can change from custom to default over time. When a customer-added handle proves broadly useful, SportFeeds promotes it into the standard catalog: posts keep flowing, the response shape is unchanged, and the handle stops counting toward your custom source limit. After promotion its sport, league and geo settings are managed by SportFeeds. Treat source_type as a current-state field, not a stable identifier.

Enterprise only

This endpoint requires an active Enterprise subscription. Contact sales to enable access.

Example Response
{
  "ok": true,
  "counts": { "total": 185, "default": 177, "custom": 8 },
  "sources": [
    {
      "platform": "X",
      "username": "acme_custom",
      "name": "Acme Custom Feed",
      "type": null,
      "league": "multiple",
      "source_type": "custom",
      "geo_availability": {
        "viewable": ["US", "CA"],
        "blocked": []
      }
    },
    {
      "platform": "X",
      "username": "nba",
      "name": "NBA",
      "type": "league",
      "league": "NBA",
      "source_type": "default",
      "geo_availability": {
        "viewable": [],
        "blocked": ["ZA"]
      }
    }
  ]
}

Sign in to test this endpoint.

Sign In
GET

/ids

One endpoint for all ID lookups. Pass entity to choose teams, players, leagues, or posts.

List all teams in a league. Returned alphabetically by location. Auto-paginated up to 1,000 per call.

GET /ids?entity=teams&league=NFL&reference_id=sportradar_id
Parameters
NameTypeRequiredDescription
entitystring
Yes
One of: teams, players, leagues, posts.
leaguestring
Yes
League code (NFL, NBA, MLB, NHL, PGA).
reference_idstringNoExternal id column to include in each item. Response key matches the value you pass. Allowed: sportradar_id, espn_id, sportsdataio_id, nba_id, yahoo_dfs_id, apisports_id, grid_id, code, external_id.
lookupstringNoReturn only the single team matching this value (resolved against reference_id if provided, otherwise sportfeeds_id).
Example Response
{
  "ok": true,
  "count": 32,
  "items": [
    {
      "sportfeeds_id": 12000045,
      "location": "Atlanta",
      "name": "Falcons",
      "conference": null,
      "division": null,
      "league": "NFL",
      "sportradar_id": "e6aa13a4-0055-48a9-bc41-be28dc106929"
    }
  ]
}

Sign in to test this endpoint.

Sign In