# API FAQ

### Sportmonks Football API v3

### Most popular questions

#### Why is my data missing?

**Short answer:** Data might be missing due to subscription plan limitations, missing includes, incorrect filters, or the data genuinely not existing for that fixture/league.

**Common causes & solutions:**

**1. Missing includes**

Your subscription includes the data, but you didn't request it with `include`.

```javascript
// ❌ Wrong - No includes, missing participant data
const fixture = await fetch('/fixtures/123?api_token=TOKEN');
// Returns: { id: 123, name: "Match", participants: undefined }

// ✅ Correct - With includes
const fixture = await fetch('/fixtures/123?api_token=TOKEN&include=participants;events;statistics');
// Returns: Full data with participants, events, and statistics
```

**Solution:** Always use `include` parameter to get related data.\
[Learn more about includes](https://docs.sportmonks.com/v3/tutorials-and-guides/tutorials/includes)

**2. Plan limitations**

Your plan may not include certain data types (odds, predictions, player statistics, etc.)

**Check your plan:** Visit [MySportmonks](https://my.sportmonks.com/) → Subscriptions → My subscription

**Base plans all include**

* ✅ Basic match data
* ✅ Live scores
* ✅ Player statistics
* ✅ Team data
* ✅ Fixtures & results
* ✅ Lineups
* ✅ Events
* ✅ Statistics

{% hint style="info" %}
**Note**: Your plan may not include certain data types (odds, predictions etc.). Odds, Predictions, Pressure Index & Expected Goals are available as add-ons. You can add these add-ons on top of your plan.
{% endhint %}

| Plan           | Leagues     | API Calls/Hour | Price      |
| -------------- | ----------- | -------------- | ---------- |
| **Starter**    | 5 leagues   | 2,000          | €29/month  |
| **Growth**     | 30 leagues  | 2,500          | €99/month  |
| **Pro**        | 120 leagues | 3,000          | €249/month |
| **Enterprise** | All leagues | 5,000          | Custom     |

**Solution:** Upgrade your plan or verify which data your plan includes.\
[Compare plans](https://www.sportmonks.com/pricing)

**3. Data not available yet**

For upcoming fixtures, some data (lineups) isn't available until closer to kickoff.

**Typical data availability timeline:**

**Pre-match**

| Data type          | Availability                                                                                                        |
| ------------------ | ------------------------------------------------------------------------------------------------------------------- |
| Lineups            | Updated 4–6 times per day for higher-coverage leagues; checked every 5 minutes during the final hour before kickoff |
| Weather conditions | Updated 4 times per day; every 30 minutes for upcoming fixtures                                                     |
| Pre-match odds     | Updated every 1–15 minutes depending on the bookmaker                                                               |

**During match (90+ minutes)**

| Data type       | Availability                            |
| --------------- | --------------------------------------- |
| Scores          | Updated within 10 seconds of a goal     |
| Events          | Updated within 10–30 seconds            |
| Statistics      | Updated every 30–60 seconds             |
| In-play odds    | Updated every 2–10 seconds              |
| Live commentary | Updated at the same frequency as events |

**Post-match (after final whistle)**

| Data type        | Availability                                                                          |
| ---------------- | ------------------------------------------------------------------------------------- |
| Final statistics | Available within 10 minutes, then regularly updated for several days if changes occur |
| Player ratings   | Live during the match (updated every minute); updated alongside statistics post-match |
| Match highlights | Not currently available                                                               |
| Standings        | Available shortly after match completion                                              |

**Solution:** Check `fixture.starting_at` to see when the match begins. Request data at appropriate times.

**4. League/Competition not covered**

Some lower-tier leagues or cup competitions may have limited data coverage.

**Check coverage:**

```javascript
// Get all leagues in your subscription
const leagues = await fetch('/core/leagues?api_token=TOKEN');

// Check if specific league is covered
const isLeagueIncluded = leagues.data.some(l => l.id === YOUR_LEAGUE_ID);
```

**Solution:** Verify league coverage in [MySportmonks](https://my.sportmonks.com/) → Data Coverage

**5. Fixture state**

Data availability depends on fixture state (NS = Not Started, LIVE = In Progress, FT = Finished, etc.)

```javascript
const fixture = await fetch('/fixtures/123?api_token=TOKEN&include=state');

console.log(fixture.state.name); // "NS", "LIVE", "FT", "POSTP", "CANCL"

// Check what data is available
if (fixture.state.name === 'NS') {
  // Only pre-match data available
} else if (fixture.state.name === 'LIVE') {
  // Live scores, events available
} else if (fixture.state.name === 'FT') {
  // All data available
}
```

**Solution:** Check fixture state before expecting certain data types.\
[Learn about fixture states](https://docs.sportmonks.com/v3/tutorials-and-guides/tutorials/states)

#### How do I reduce API calls?

**Short answer:** Use includes to combine requests, cache reference data, use batch endpoints, and implement smart polling strategies.

**5 Proven strategies:**

**1. Use Includes (50-80% Reduction)**

Combine multiple requests into one:

```javascript
// ❌ Bad - 3 separate requests
const fixture = await fetch('/fixtures/123?api_token=TOKEN');
const teams = await fetch('/teams/53?api_token=TOKEN');
const stats = await fetch('/statistics/fixtures/123?api_token=TOKEN');
// Total: 3 API calls

// ✅ Good - 1 request with includes
const fixture = await fetch('/fixtures/123?api_token=TOKEN&include=participants;statistics;events');
// Total: 1 API call (67% savings!)
```

**Impact:** Reduces 3 calls to 1 = **67% savings**

[Complete includes guide](https://docs.sportmonks.com/v3/tutorials-and-guides/tutorials/includes)

**2. Cache reference data (30-50% Reduction)**

Data that rarely changes should be cached:

**What to cache & for how long:**

| Data Type                  | Cache Duration | Why                |
| -------------------------- | -------------- | ------------------ |
| Types (statistics, events) | **1 week**     | Never changes      |
| States                     | **1 week**     | Static data        |
| Leagues                    | **1 day**      | Rarely updates     |
| Teams                      | **1 hour**     | Occasional updates |
| Venues                     | **1 week**     | Stable data        |
| Markets/Bookmakers         | **1 day**      | Infrequent changes |

**Example implementation:**

```javascript
class CachedAPI {
  constructor(token) {
    this.token = token;
    this.cache = new Map();
  }
  
  async getCached(endpoint, cacheDuration) {
    const now = Date.now();
    
    if (this.cache.has(endpoint)) {
      const { data, timestamp } = this.cache.get(endpoint);
      if (now - timestamp < cacheDuration) {
        console.log('✅ Using cache - 0 API calls');
        return data;
      }
    }
    
    console.log('📡 Fetching from API');
    const response = await fetch(`${endpoint}?api_token=${this.token}`);
    const data = await response.json();
    
    this.cache.set(endpoint, { data, timestamp: now });
    return data;
  }
}

// Usage
const api = new CachedAPI('YOUR_TOKEN');

// First call - fetches from API (1 call)
const types = await api.getCached('/core/types', 7 * 24 * 60 * 60 * 1000);

// Next 1000 lookups - from cache (0 calls!)
const type1 = types.data.find(t => t.id === 86);
const type2 = types.data.find(t => t.id === 52);
// ... 998 more lookups = 0 API calls
```

**Impact:** 1000 requests reduced to 1 = **99.9% savings**

**3. Use batch endpoints (40-60% Reduction)**

Fetch multiple resources in one request:

```javascript
// ❌ Bad - 10 separate requests
for (const id of [123, 456, 789, 101, 102, 103, 104, 105, 106, 107]) {
  await fetch(`/fixtures/${id}?api_token=TOKEN`);
}
// Total: 10 API calls

// ✅ Good - 1 batched request
const ids = [123, 456, 789, 101, 102, 103, 104, 105, 106, 107];
await fetch(`/fixtures/multi/${ids.join(',')}?api_token=TOKEN`);
// Total: 1 API call (90% savings!)
```

**Available batch endpoints:**

* `/fixtures/multi/{ids}`
* `/teams/multi/{ids}`
* `/players/multi/{ids}`

**4. Smart polling for livescores (40-60% reduction)**

Only poll when necessary:

```javascript
// ❌ Bad - Poll every 5 seconds, always
setInterval(() => {
  fetch('/livescores?api_token=TOKEN');
}, 5000);
// = 720 calls/hour

// ✅ Good - Adaptive polling
function adaptivePolling() {
  const hasLiveMatches = checkIfAnyLive();
  
  if (hasLiveMatches) {
    return setInterval(pollLivescores, 10000); // 10s when live
  } else {
    return setInterval(pollLivescores, 300000); // 5min when no live matches
  }
}
// = 360 calls/hour during matches, 12 calls/hour otherwise (95% savings!)
```

**Better yet - Use `/livescores/latest`:**

```javascript
// Only fetches matches that updated in last 10 seconds
const updates = await fetch('/livescores/latest?api_token=TOKEN');
// Only updates changed matches in UI
```

**5. Use `filters=populate` for bulk operations**

When populating databases, use populate filter:

```javascript
// ❌ Slow - Default pagination (25 per page)
// For 1000 fixtures = 40 requests
for (let page = 1; page <= 40; page++) {
  await fetch(`/fixtures?page=${page}&api_token=TOKEN`);
}

// ✅ Fast - With populate filter (1000 per page)
await fetch(`/fixtures?filters=populate&per_page=1000&api_token=TOKEN`);
// For 1000 fixtures = 1 request (97.5% savings!)
```

**Note:** `populate` disables includes, use only for bulk data collection.

**Combined impact:**

Before optimisation:

* Daily API calls: 20,000

After all strategies:

* Daily API calls: 2,500

**Total savings: 87.5%** 🎉

[Complete optimisation guide](https://docs.sportmonks.com/v3/api/rate-limit)

#### What's the difference between endpoints and entities?

**Short answer:** Endpoints are URLs you call. Entities are the data types that count toward rate limits. Multiple endpoints can use the same entity.

**Detailed explanation:**

**Endpoints** = The API URLs you make requests to

**Entities** = The underlying resource type (what counts for rate limits)

**Key concept:** Rate limits are **per entity**, not per endpoint.

**Example:**

```javascript
// These are different ENDPOINTS:
await fetch('/fixtures/123');           // Endpoint 1
await fetch('/fixtures/date/2026-03-17'); // Endpoint 2
await fetch('/livescores/inplay');      // Endpoint 3

// But they ALL use the same ENTITY: "Fixture"
// So they all count toward the SAME rate limit bucket
```

**Rate limit structure:**

Each entity has its own rate limit depending on your plan:

| Entity      | Your Endpoints                                                        |
| ----------- | --------------------------------------------------------------------- |
| **Fixture** | `/fixtures`, `/fixtures/{id}`, `/fixtures/date/{date}`, `/livescores` |
| **Team**    | `/teams`, `/teams/{id}`, `/teams/search/{name}`                       |
| **Player**  | `/players`, `/players/{id}`, `/players/search/{name}`                 |
| **League**  | `/leagues`, `/leagues/{id}`                                           |

**Practical example:**

```javascript
// Scenario: You make these requests in 1 hour

// Fixture entity requests (all count together)
await fetch('/fixtures/123');          // Fixture count: 1
await fetch('/fixtures/456');          // Fixture count: 2
await fetch('/livescores');            // Fixture count: 3
await fetch('/fixtures/date/today');   // Fixture count: 4
// Current Fixture usage: 4/2000

// Team entity requests (separate counter)
await fetch('/teams/53');              // Team count: 1
await fetch('/teams/62');              // Team count: 2
// Current Team usage: 2/2000

// Current total usage:
// - Fixture entity: 4/2000
// - Team entity: 2/2000
```

**Why this matters:**

You could theoretically make:

* 3,000 Fixture requests
* 3,000 Team requests
* 3,000 Player requests
* 3,000 League requests

\= **12,000+ total API requests per hour** across different entities!

**How to check which entity:**

Every API response includes:

```json
{
  "data": { ... },
  "rate_limit": {
    "resets_in_seconds": 1847,
    "remaining": 2996,
    "requested_entity": "Fixture"
  }
}
```

[Complete rate limiting guide](https://docs.sportmonks.com/v3/api/rate-limit)

#### How often is data updated?

**Short answer:** Live match data updates every 10-30 seconds. Reference data (teams, leagues) updates less frequently. Update frequency varies by data type.

**Update frequency by data type:**

| Data Type        | Update Frequency | When It Updates                          |
| ---------------- | ---------------- | ---------------------------------------- |
| **Live Scores**  | 10-30 seconds    | During live matches                      |
| **Match Events** | 10-30 seconds    | Goals, cards, substitutions in real-time |
| **Statistics**   | 30-60 seconds    | During and after matches                 |
| **Lineups**      | Once             | Published 1 hour before kickoff          |
| **Standings**    | After each match | When match finishes                      |
| **Fixtures**     | Daily            | New fixtures added, dates updated        |
| **Teams**        | Weekly           | Squad changes, manager updates           |
| **Players**      | Weekly           | Transfers, injuries                      |
| **Leagues**      | Monthly          | Seasonal updates                         |
| **Venues**       | Rarely           | Only when stadium info changes           |
| **Types/States** | Never            | Static reference data                    |

**Live match data timeline:**

```
Pre-Match
├─ Lineups → Updated 4–6 times per day for higher-coverage leagues; checked every 5 minutes during the final hour before kickoff
├─ Weather conditions → Updated 4 times per day; every 30 minutes for upcoming fixtures
└─ Pre-match odds → Updated every 1–15 minutes depending on the bookmaker

During Match (90+ minutes)
├─ Scores → Updated within 10 seconds of a goal
├─ Events → Updated within 10–30 seconds
├─ Statistics → Updated every 30–60 seconds
├─ In-play odds → Updated every 2–10 seconds
└─ Live commentary → Updated at the same frequency as events

Post-Match (after final whistle)
├─ Final statistics → Available within 10 minutes, then regularly updated for several days if changes occur
├─ Player ratings → Already live during the match, updated every minute; updated alongside statistics post-match where applicable
├─ Match highlights → Not currently available
└─ Standings → Available shortly after match completion

```

**Recommended polling intervals:**

```javascript
// Live matches - Poll every 10 seconds
if (fixture.state.name === 'LIVE') {
  setInterval(fetchLiveData, 10000);
}

// Pre-match - Poll every 30 minutes (for lineup updates)
if (fixture.state.name === 'NS' && hoursUntilKickoff < 2) {
  setInterval(fetchPreMatchData, 1800000);
}

// Standings - Poll once after each match completes
if (fixture.state.name === 'FT') {
  fetchStandings(); // One-time fetch
}

// Reference data - Cache for 1 week
const types = await getCached('/core/types', 604800000);
```

**Special cases:**

**Expected goals (xG)**

* Available during live matches, updated every 60 seconds
* Final xG available shortly after the match

**Player statistics**

* All stats (standard, advanced, and xG) are updated live during the match and continue to be updated post-match

**Odds:**

* Pre-match: Updated every 1–15 minutes depending on the bookmaker
* In-play: Updated every 2–10 seconds during live matches

Don't poll more frequently than the data updates. Use appropriate intervals based on data type.

[Learn about fixture states](https://docs.sportmonks.com/v3/tutorials-and-guides/tutorials/states)

#### Why am I getting rate limited?

**Short answer:** You've exceeded your plans requests per hour for a specific entity. Common causes: polling too frequently, not using includes, not caching reference data.

**Understanding rate limits:**

Every plan has its own requests figure per hour per entity.

**Error message:**

```json
{
  "error": "Too Many Requests",
  "message": "Rate limit of 2000 requests per hour exceeded (This is the base rate for the starter plan)",
  "retry_after": 1847,
  "rate_limit": {
    "remaining": 0,
    "total": 2000,
    "resets_in_seconds": 1847,
    "requested_entity": "Fixture"
  }
}
```

**Common causes:**

**1. Polling too frequently**

```javascript
// ❌ This hits rate limit in 4 hours
setInterval(() => {
  fetch('/livescores?api_token=TOKEN');
}, 5000); // Every 5 seconds = 720 calls/hour
// 4 hours × 720 = 2,880 calls (almost at limit!)

// ✅ Poll smarter
setInterval(() => {
  fetch('/livescores/latest?api_token=TOKEN'); // Only updated matches
}, 10000); // Every 10 seconds = 360 calls/hour
```

**2. Not using includes**

```javascript
// ❌ Making separate requests
for (let i = 0; i < 100; i++) {
  await fetch(`/fixtures/${ids[i]}?api_token=TOKEN`); // 100 calls
  await fetch(`/teams/${teamIds[i]}?api_token=TOKEN`); // 100 calls
}
// Total: 200 calls for 100 fixtures

// ✅ Using includes
const response = await fetch(
  `/fixtures/multi/${ids.join(',')}?api_token=TOKEN&include=participants`
);
// Total: 1 call (99.5% reduction!)
```

**3. Not caching reference data**

```javascript
// ❌ Fetching types for every fixture
for (let fixture of fixtures) {
  const types = await fetch('/core/types?api_token=TOKEN'); // 100 calls
  const statType = types.data.find(t => t.id === fixture.type_id);
}

// ✅ Cache types once
const types = await fetch('/core/types?api_token=TOKEN'); // 1 call
const typeMap = new Map(types.data.map(t => [t.id, t]));

for (let fixture of fixtures) {
  const statType = typeMap.get(fixture.type_id); // 0 API calls
}
// Savings: 99 calls (99% reduction!)
```

**How to fix:**

**Immediate solutions:**

1. **Wait for reset:**

   ```javascript
   // Response tells you when limit resets
   const retryAfter = response.retry_after; // seconds
   console.log(`Wait ${retryAfter}s before retrying`);
   ```
2. **Implement retry logic:**

   ```javascript
   async function fetchWithRetry(url) {
     try {
       const response = await fetch(url);
       if (response.status === 429) {
         const data = await response.json();
         await sleep(data.retry_after * 1000);
         return fetchWithRetry(url); // Retry after waiting
       }
       return response.json();
     } catch (error) {
       console.error('Error:', error);
     }
   }
   ```

**Long-term solutions:**

1. Use includes to reduce requests by 50-80%
2. Cache reference data (types, states, leagues)
3. Use `/livescores/latest` instead of `/livescores`
4. Implement smart polling (only when needed)
5. Use batch endpoints (`/fixtures/multi/{ids}`)
6. Upgrade your rate limit if consistently hitting it

[Complete rate limiting guide](https://docs.sportmonks.com/v3/api/rate-limit)

#### How do I debug API responses?

**Short answer:** Use browser DevTools Network tab, console.log responses, check response status codes, verify includes are working, and use the API Explorer.

**6-Step debugging process:**

**Step 1: Check response status**

```javascript
const response = await fetch('/fixtures/123?api_token=TOKEN');

console.log('Status:', response.status);
console.log('OK?:', response.ok);

// Common status codes:
// 200 = Success
// 401 = Invalid API token
// 404 = Resource not found
// 429 = Rate limited
// 500 = Server error
```

**Step 2: Log full response**

```javascript
const response = await fetch('/fixtures/123?api_token=TOKEN&include=participants');
const data = await response.json();

console.log('Full response:', data);
console.log('Data:', data.data);
console.log('Participants:', data.data.participants);
console.log('Rate limit:', data.rate_limit);
```

**Step 3: Verify includes are working**

```javascript
const response = await fetch('/fixtures/123?api_token=TOKEN&include=participants;events');
const data = await response.json();

// Check if includes loaded
console.log('Has participants?', Array.isArray(data.data.participants));
console.log('Has events?', Array.isArray(data.data.events));

if (!data.data.participants) {
  console.error('❌ Participants not included! Check:');
  console.error('1. Is include parameter spelled correctly?');
  console.error('2. Does your plan include this data?');
  console.error('3. Is data available for this fixture?');
}
```

**Step 4: Use browser DevTools**

Open browser Console (F12) and check:

**Network tab:**

1. Find your API request
2. Click on it
3. Check **Headers** tab → Request URL (is it correct?)
4. Check **Response** tab → See raw JSON
5. Check **Preview** tab → Formatted view

**Step 5: Test in API playground**

[**MySportmonks API Playground**](https://my.sportmonks.com/api/playground)

1. Select endpoint (e.g., `/fixtures/{id}`)
2. Enter ID: `123`
3. Add includes: `participants;events`
4. Click "Send Request"
5. View response

Benefits:

* No code needed
* Verifies endpoint works
* Shows exact response structure
* Copies working code examples

**Step 6: Check common issues**

**Issue 1: Data is `null` or `undefined`**

```javascript
// ❌ Data is null
const teams = data.data.participants; // null

// Debugging:
console.log('Fixture state:', data.data.state?.name);
// If state is "NS" (Not Started), some data isn't available yet

console.log('Subscription includes:', data.subscription);
// Check if your plan includes this data

console.log('Include param:', new URL(requestUrl).searchParams.get('include'));
// Verify you actually included it
```

**Quick debug helper:**

```javascript
function debugResponse(response, data) {
  console.group('🔍 API Debug Info');
  console.log('Status:', response.status, response.ok ? '✅' : '❌');
  console.log('URL:', response.url);
  console.log('Has data?', !!data?.data);
  console.log('Rate limit:', data?.rate_limit?.remaining, '/', data?.rate_limit?.total);
  console.log('Response:', data);
  console.groupEnd();
}

// Usage
const response = await fetch(url);
const data = await response.json();
debugResponse(response, data);
```

[Error codes reference](https://docs.sportmonks.com/v3/api/error-codes)

#### Can I use the API in production?

**Short answer:** Yes! The Sportmonks API is designed for production use. Make sure you handle errors, implement caching, respect rate limits, and secure your API token.

**Production readiness checklist:**

```
□ API token stored securely (env variables, secrets manager)
□ Error handling on all API calls
□ Rate limit handling with retry logic
□ Caching for reference data
□ Request timeouts configured
□ Monitoring/logging in place
□ Graceful degradation for failures
□ Backend proxy (not direct frontend calls)
□ HTTPS only
□ API usage metrics tracked
□ Backup/fallback strategies
□ Load testing completed
□ Error tracking service configured (Sentry, etc.)
```

[Best practices guide](https://docs.sportmonks.com/v3/welcome/best-practices)\
[Rate limiting guide](https://docs.sportmonks.com/v3/api/rate-limit)

#### What's the difference between plans?

**Short answer:** Plans differ in data access, number of leagues, rate limits, and support level.

**Plan comparison:**

<table><thead><tr><th width="147.800048828125">Feature</th><th width="145.4000244140625">Starter</th><th width="139.0001220703125">Growth</th><th width="152">Pro</th><th>Enterprise</th></tr></thead><tbody><tr><td><strong>Price</strong></td><td>€29/month</td><td>€99/month</td><td>€249/month</td><td>Custom</td></tr><tr><td><strong>Leagues</strong></td><td><p>5</p><p>leagues</p></td><td><p>30 </p><p>leagues</p></td><td><p>120 </p><p>leagues</p></td><td>All leagues</td></tr><tr><td><strong>Rate Limit</strong></td><td>2K/hour</td><td>2.5K/hour</td><td>3K/hour</td><td>5K/hour</td></tr><tr><td><strong>Support</strong></td><td>Email</td><td>Priority Email</td><td>Priority + Chat</td><td>Dedicated</td></tr></tbody></table>

**Free Trial:**

All paid plans include a **14-day free trial**. A credit card is required.

**Compare plans:** [Sportmonks pricing](https://www.sportmonks.com/football-api/plans-pricing/)

### FAQs by category

#### Authentication & Access

**Q: How do I get an API token?**

Sign up at [sportmonks.com](https://www.sportmonks.com/), then find your API token at [MySportmonks](https://my.sportmonks.com/) → API → Token.

**Q: My API token isn't working. What should I check?**

Common issues:

1. Token not included: Use `?api_token=YOUR_TOKEN`
2. Typo in token: Copy-paste from MySportmonks
3. Wrong subscription: Verify correct token
4. Subscription expired: Check [MySportmonks](https://my.sportmonks.com/)

**Q: Should I use different tokens for development and production?**

Yes, recommended! Get separate subscriptions to prevent development work from affecting production rate limits.

#### Data & Content

**Q: Which leagues are included in my plan?**

Check [MySportmonks](https://my.sportmonks.com/) → Data Coverage, or:

```javascript
const leagues = await fetch('/core/leagues?api_token=YOUR_TOKEN');
console.log('Included leagues:', leagues.data.length);
```

**Q: How do I get historical data?**

Use date filters:

```javascript
// Fixtures from specific date
const fixtures = await fetch('/fixtures?api_token=TOKEN&filters=fixtureDate:2024-01-01');

// Date range
const fixtures = await fetch('/fixtures?api_token=TOKEN&filters=fixtureStartDate:2024-01-01;fixtureEndDate:2024-01-31');
```

**Q: What's the difference between includes and selects?**

**Includes** = Add related data\
**Selects** = Limit which fields return

```javascript
// Includes - get MORE data
fetch('/fixtures/123?include=participants;events');

// Selects - get LESS data (smaller, faster)
fetch('/fixtures/123?select=id,name,starting_at');
```

[Includes guide](https://docs.sportmonks.com/v3/tutorials-and-guides/tutorials/includes)

#### Performance & Optimisation

**Q: What's the fastest way to get live scores?**

Use `/livescores/latest`:

```javascript
// Only returns matches updated in last 10 seconds
const updates = await fetch('/livescores/latest?api_token=TOKEN');
```

**Q: How can I reduce response size?**

Use `select` parameter:

```javascript
// Default: ~5KB
const fixture = await fetch('/fixtures/123?api_token=TOKEN');

// With select: ~1KB (80% smaller!)
const fixture = await fetch('/fixtures/123?api_token=TOKEN&select=id,name,starting_at,state');
```

**Q: Should I use pagination?**

Yes, for large datasets:

```javascript
// Standard pagination
const page1 = await fetch('/fixtures?api_token=TOKEN&page=1&per_page=100');

// Bulk operations - use populate
const bulk = await fetch('/fixtures?api_token=TOKEN&filters=populate&per_page=1000');
```

#### Billing & Plans

**Q: Can I try before I buy?**

Yes! All paid plans include a **14-day free trial**. A credit card is required.

**Q: Can I cancel anytime?**

Yes, cancel anytime at [MySportmonks](https://my.sportmonks.com/) → Subscriptions → Cancel.

**Q: Do you offer annual billing discounts?**

Yes! Annual billing offers \~20% savings. Contact <sales@sportmonks.com>.

#### Technical & Debugging

**Q: Why am I getting CORS errors?**

CORS errors occur when calling API directly from browser.

**Solution:** Create a backend proxy:

```javascript
// Backend (Node.js/Express)
app.get('/api/fixtures/:id', async (req, res) => {
  const data = await fetch(
    `https://api.sportmonks.com/v3/football/fixtures/${req.params.id}?api_token=${process.env.TOKEN}`
  );
  res.json(await data.json());
});

// Frontend calls your backend
fetch('/api/fixtures/123'); // No CORS!
```

**Q: How do I handle null values?**

Use optional chaining:

```javascript
// ❌ Unsafe
const teamName = fixture.participants.home.name;

// ✅ Safe
const teamName = fixture?.participants?.find(p => p.meta.location === 'home')?.name ?? 'Unknown';
```

**Q: How do I search for teams/players?**

Use search endpoints:

```javascript
// Search teams
const teams = await fetch('/teams/search/Arsenal?api_token=TOKEN');

// Search players
const players = await fetch('/players/search/Messi?api_token=TOKEN');
```

#### Integration & Development

**Q: Can I use this with React/Vue/Angular?**

Absolutely! Example React hook:

```javascript
import { useState, useEffect } from 'react';

function useFixture(id) {
  const [fixture, setFixture] = useState(null);
  const [loading, setLoading] = useState(true);
  
  useEffect(() => {
    async function fetchFixture() {
      const response = await fetch(`/api/fixtures/${id}`);
      setFixture(await response.json());
      setLoading(false);
    }
    fetchFixture();
  }, [id]);
  
  return { fixture, loading };
}
```

### Still have questions?

#### Get help

**Email Support:** <support@sportmonks.com>

#### Useful links

* [Complete API Documentation](https://docs.sportmonks.com/v3)
* [Tutorials & Guides](https://docs.sportmonks.com/v3/tutorials-and-guides/tutorials)
* [API Playground](https://my.sportmonks.com/api/playground)
* [Status Page](https://status.sportmonks.com/)
* [My Account](https://my.sportmonks.com/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.sportmonks.com/v3/api-faq.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
