# Best Practices and Common Mistakes
URL: https://sportsgameodds.com/docs/info/best-practices

Best Practices and Common Mistakes [#best-practices-and-common-mistakes]

This guide covers our recommended patterns as well as some common mistakes to avoid when working with the SportsGameOdds API.

Patterns to Follow [#patterns-to-follow]

Set up a server-side process to sync data from the API into your database [#set-up-a-server-side-process-to-sync-data-from-the-api-into-your-database]

* This is the most secure and scalable way to ingest API data
* A simple cron job can handle this well.
* Since you're syncing the data, you're in full control of how up-to-date your data is.
* If your app starts doing well and you get 10x more traffic, your API calls remain consistent and predictable.

Calculate your expected usage [#calculate-your-expected-usage]

* Use these factors to determine how many requests/objects you'll need:
  * How many leagues you're tracking data for
  * How frequently you want to refresh your data
  * How many games you want track/update at a time for each league
    * All games? Then determine how many that will roughly be at each time of year based on active sports seasons.
    * All games in the next 24 hours? 48 hours? week? month? If so, what do those numbers look like for each tracked league?
    * Only games with active odds markets? If so, then what do the average numbers look like for each tracked league?

Specify oddIDs in /events requests when you only need specific odds markets [#specify-oddids-in-events-requests-when-you-only-need-specific-odds-markets]

* Including this parameter can significantly reduce the respoonse payload size and improve response times.

Implement retry logic on 500-level errors [#implement-retry-logic-on-500-level-errors]

* If you ever receive a 500-level error, you should wait a short period, then retry a single time.
* In most cases, you'll get a successful response on the second attempt.
* If you don't then stop retrying and log the error.

Use query params to filter data [#use-query-params-to-filter-data]

* Filtering at the API level means less irrelevant/unused data is returned to you.
* This improves response times and reduces your costs.

Use eventID by itself for direct lookups [#use-eventid-by-itself-for-direct-lookups]

* When you already know which event(s) you want, query by `eventID` or `eventIDs` — this is the fastest query path.
* Note that when `eventID`/`eventIDs` are provided, all other filters (`sportID`, `leagueID`, `live`, `started`, `startsAfter`, etc.) are ignored. Only the eventIDs are used for filtering.
* Response-shaping parameters like `oddID`, `bookmakerID`, and `playerID` still apply normally, so you'll only get odds/bookmakers/players inside each event corresponding to your filters but you may see events without any odds/bookmakers/players due to that filtering.

Use the limit and cursor parameters together [#use-the-limit-and-cursor-parameters-together]

* Before you start using the `cursor` parameter, increase the `limit` parameter so you get more results per request.

Keep your API key secure [#keep-your-api-key-secure]

* Never expose it in your frontend code.
* Never commit it to version control.

Monitor your usage [#monitor-your-usage]

* Check the `/account/usage` endpoint to see how you're doing against your rate limits

Handle missing fields defensively [#handle-missing-fields-defensively]

* Some fields may not always be available across all of our data. You should handle such cases gracefully.
* Typically, critical fields will always have a value (ex: Events will always have an `eventID`, `sportID`, `leagueID`), but less critical fields won't.
* For example, use `Event.teams.home.names.long || Event.teams.home.names.medium || Event.teams.home.names.short` rather than assuming `Event.teams.home.names.long` is always available.

Vary Your Polling/Caching Intervals [#vary-your-pollingcaching-intervals]

* Odds change very infrequently when a game is far in the future
* Many markets aren't even offered until a game is less than 24-48 hours away
* You can save on API calls polling less frequently for games in the far future and more frequently for games in the near future.

Learn the oddID Structure [#learn-the-oddid-structure]

* Knowing this structure and what the individual values mean will make working with the API much faster and easier
* `{statID}-{statEntityID}-{periodID}-{betTypeID}-{sideID}-{bookmakerID}`

Anti-Patterns to Avoid [#anti-patterns-to-avoid]

Making API Requests from a Frontend/Browser [#making-api-requests-from-a-frontendbrowser]

* Frontend code (ex: React, Vue, etc.) should never make API requests directly.
* This exposes your API key to the public.
* In general, to avoid this you have two options:
  * Set up a server-side proxy that makes the API requests and returns the data to the frontend.
  * Set up a server-side process to sync data from the API into your database. Query your database from your frontend.

Polling on an Interval on the Free/Amateur plan [#polling-on-an-interval-on-the-freeamateur-plan]

* If you set up a system that makes a number of API requests continuously on an interval, you'll quickly hit your limits on the Amateur tier
* We recomend only running your API requests manually and upgrading to a higher-limit plan when you're ready to set something like this up.

Polling Too Frequently [#polling-too-frequently]

* Based on your plan, your data may not update more than every 30 seconds to 1 minute
* Polling more frequently than this wastes your rate limit quota

Always Polling All Upcoming Games [#always-polling-all-upcoming-games]

* Instead, cache data for longer when a game is happening far in the future
* Such games likely won't have frequent odds movements
* This can help you save on API calls and reduce your costs

Not Considering Response Codes [#not-considering-response-codes]

* For example, if you get a 429 (Rate Limit Exceeded) error, you should wait before retrying
* Not waiting is just going to cause you to burn through your rate limit quota faster
* You'll also want to consider whether you've hit a minute-level, month-level, or other rate limit. Use the `/account/usage` endpoint to check your usage.

Not Considering Error Messages [#not-considering-error-messages]

* Whenever you get an error response, there will be an `error` field at the top-level of the response body
* This field will tell you what went wrong and why
* In most cases, you should log this info and use it to help debug any problems you're encountering

Always Including includeAltLines=true in /events requests [#always-including-includealtlinestrue-in-events-requests]

* Don't include alt lines unless you actually need them
* They can significantly increase the response payload size and slow down your response times

Using startsAfter/startsBefore when unneeded [#using-startsafterstartsbefore-when-unneeded]

* The startsAfter and startsBefore parameters can impede query performance in some cases
* Performance suffers the most when it's combined with other less-performant parameters such as:
  * `playerID`, `bookmakerID`, `teamID`, `includeAltLines`
* Try to re-evaluate whether you can accomplish the same thing without these parameters (sometimes you can, sometimes you can't)

Using too many query parameters [#using-too-many-query-parameters]

* Queries are best optimized for requests that use 1-3 parameters (excluding `limit`, `cursor`, `apiKey`)
* Using more than this can make your queries slower in some cases

Filtering Results on the Client [#filtering-results-on-the-client]

* Our API can return very large payloads.
* Therefore, your goal should be to filter as much as possible at the API level and not in your code
* That way, you don't have to download and parse unnecessary data.
* This is best accomplished with query parameters

Using Wrong/Invalid Query Parameters [#using-wronginvalid-query-parameters]

* See our [Reference Docs](/docs/reference/) for more information on the valid query parameters for each endpoint

Not Monitoring Usage [#not-monitoring-usage]

* You want to keep track of your usage in order to optimize your usage patterns and avoid hitting your rate limits.
* Use the `/account/usage` endpoint to check your usage.