Developers
Build on Sports Industry Data: a REST API, a typed JS/TS SDK and a Claude MCP server for sports sales intelligence — search, verify, enrich, Lead Queue, pipeline, signals and AI outreach drafts.
Quickstart
- 1Request accessCreate an account and request access. We review every request by hand; on approval your
sid_live_…key arrives by email. It is shown once. - 2Call the APIBase URL
https://sportsindustrydata.com/api/v1. SendAuthorization: Bearerwith your key. - 3Or skip the HTTPUse the SDK in Node, or plug the MCP server into Claude.
export SID_API_KEY=sid_live_YOUR_KEY
curl -s https://sportsindustrydata.com/api/v1/me -H "Authorization: Bearer $SID_API_KEY"Auth, rate limits & quotas
Authorization: Bearer sid_live_… (or x-api-key). Keys belong to your account and carry scopes. Revoke one any time; it stops at once.
- 60 requests / minute per key →
X-RateLimit-Limit,X-RateLimit-Remaining; over it: 429 +Retry-After. - Monthly usage counts against your plan (API calls, verifications, drafts) → 402
quota_exceeded. Check withGET /me. - Errors are always
{ error: { code, message } }.
Endpoints
Generated from the live spec. * = required. Full schemas and examples: /api/v1/openapi.json.
| Method | Path | What it does | Params / body |
|---|---|---|---|
| GET | /me | Your key, account and this month's usage | — |
| GET | /openapi.json | This document | — |
| Method | Path | What it does | Params / body |
|---|---|---|---|
| GET | /orgs | Search organisations Agencies, brands, marketing firms, financial firms and foundations. Warm paths first: orgs where your account already knows people rank first. | ?q ?track ?kind ?limit ?offset |
| GET | /orgs/{id} | Get one organisation | — |
| GET | /people | Search people Contacts, athletes, agents, advisors and foundation executives. People in your rolodex come first. | ?q ?org_id ?kind ?limit ?offset |
| GET | /people/{id} | Get one person | — |
| Method | Path | What it does | Params / body |
|---|---|---|---|
| POST | /verify | Verify an email before you send Syntax, MX, disposable/role checks, suppression list, and — when the address belongs to a known person — whether they are still at that employer. Counts against the `verifies` limit. Scope: verify. | email* person_id |
| POST | /enrich | Enrich by domain or by email Send `{domain}` for the org, its email pattern and known people, or `{email}` for the person behind it. Returns email, title, LinkedIn and company only. Scope: enrich. | domain* | email* |
| Method | Path | What it does | Params / body |
|---|---|---|---|
| GET | /leads | List the Lead Queue | ?status ?limit ?offset |
| POST | /leads | Add a lead to the queue Creates a `queued` row. Nothing enters the pipeline automatically — a person approves it. Scope: leads. | title* person_id org_id reason |
| GET | /leads/{id} | Get a lead | — |
| PATCH | /leads/{id} | Update a lead (approve, reject, assign) | status assigned_to reason |
| DELETE | /leads/{id} | Delete a lead | — |
| Method | Path | What it does | Params / body |
|---|---|---|---|
| GET | /pipeline | Pipeline summary + deals | — |
| POST | /pipeline/deals | Create a deal | name* org_id person_id lead_id pipeline stage value_cents |
| PATCH | /pipeline/deals/{id} | Move or update a deal | stage value_cents name expected_close |
| Method | Path | What it does | Params / body |
|---|---|---|---|
| GET | /signals | Recent signals Job changes, agency changes, signings, foundation news and identified visitors. | ?kind ?since ?limit |
| GET | /webhooks | List webhook subscriptions | — |
| POST | /webhooks | Subscribe a URL to events | url* events* |
| DELETE | /webhooks/{id} | Delete a webhook | — |
| Method | Path | What it does | Params / body |
|---|---|---|---|
| GET | /visitor-events | Recent identified visits | ?limit |
| POST | /visitor-events | Identify a visitor from your server Send the visitor's IP (from your own server) to identify the company/person. Matches create a queued lead. Scope: visitor. | ip* url referrer site_key |
| Method | Path | What it does | Params / body |
|---|---|---|---|
| POST | /draft | AI-draft personalised outreach Uses career history, company news, call transcripts, email threads and rolodex status. Add `?stream=1` for a text/plain stream. Never drafts to do-not-contact people or minors. Scope: draft. | ?stream person_id* channel* goal tone notes |
Three calls to try
curl -s "https://sportsindustrydata.com/api/v1/orgs?q=sports&tier=1&track=Agency&limit=5" \
-H "Authorization: Bearer $SID_API_KEY"{
"data": [
{ "id": 12, "name": "Bluehollow Talent Group", "track": "Agency", "tier": "1",
"domain": "northline.example", "domain_confidence": "HIGH",
"people_count": 4, "known_count": 1, "warm_path": true }
],
"meta": { "total": 1, "limit": 5, "offset": 0 }
}curl -s -X POST https://sportsindustrydata.com/api/v1/verify \
-H "Authorization: Bearer $SID_API_KEY" \
-H "content-type: application/json" \
-d '{"email":"jordan.avery@example.com"}'curl -s -X POST https://sportsindustrydata.com/api/v1/leads \
-H "Authorization: Bearer $SID_API_KEY" \
-H "content-type: application/json" \
-d '{"title":"Bluehollow Foundation — intro","org_id":7,"reason":"Warm path"}'JS / TS SDK
Typed, zero dependencies, Node 18+. Retries 429/5xx with back-off, throws SIDError with a code, and streams drafts with draftStream().
npm i ./sportsindustrydata-sdk-1.0.1.tgz # today (tarball)
npm i @sportsindustrydata/sdk # once publishedimport { SID } from "@sportsindustrydata/sdk";
const sid = new SID({ apiKey: process.env.SID_API_KEY! });
// 1. Who do we already know at Bluehollow Talent Group?
const { data: orgs } = await sid.orgs.search({ q: "Bluehollow" });
const org = await sid.orgs.get(orgs[0].id);
const known = org.people.filter((p) => p.known);
// 2. Verify before you send
const v = await sid.verify(known[0].email!, known[0].id);
// 3. Stream an AI draft
for await (const chunk of sid.draftStream({ person_id: known[0].id, channel: "email", goal: "Introduce our athlete-partnership program and ask for 15 minutes" }))
process.stdout.write(chunk);Use it from Claude
The MCP server runs on your machine and calls the API with your key. Tools:
{
"mcpServers": {
"sports-industry-data": {
"command": "sid-mcp",
"env": { "SID_API_KEY": "sid_live_YOUR_KEY" }
}
}
}npm i -g ./sportsindustrydata-mcp-1.0.1.tgz
claude mcp add sports-industry-data -e SID_API_KEY=sid_live_YOUR_KEY -- sid-mcpThen ask Claude: “Who do we already know at Bluehollow Talent Group? Verify their email and draft a short intro about our athlete-partnership program.”
Webhooks
Subscribe a URL with POST /webhooks. Each delivery is POST {event, data, sent_at}, signed with the secret you get once at creation.
import { verifyWebhookSignature } from "@sportsindustrydata/sdk/webhooks";
// X-SID-Signature: sha256=<hex HMAC-SHA256(secret, raw body)>
app.post("/sid-hook", express.raw({ type: "application/json" }), (req, res) => {
if (!verifyWebhookSignature(process.env.SID_WEBHOOK_SECRET, req.body, req.get("x-sid-signature")))
return res.status(401).end();
const { event, data, sent_at } = JSON.parse(req.body.toString());
// event: signal.fired | lead.created | lead.approved | deal.moved | outreach.replied | visitor.identified
res.sendStatus(200);
});Embed widget + visitor pixel
Get your site key in the app under Visitor intel. The embed adds a styled request form (or a floating button) and the pixel; the pixel alone identifies visiting companies and people into your Lead Queue for a person to approve.
<!-- Request form + visitor pixel. Put <div id="sid-embed"></div> where the form should go,
or leave it out for a floating "Talk to Sports Industry Data" button. -->
<script src="https://sportsindustrydata.com/api/sid/embed.js"
data-site="YOUR_SITE_KEY" data-form="1" async></script><!-- Visitor intel only: identifies visiting companies and people into your Lead Queue -->
<script src="https://sportsindustrydata.com/api/sid/px.js?k=YOUR_SITE_KEY" async></script>