NAV
code

Introduction

Base URL:

api.sharpsports.io

The SharpSports API is the best way to securely connect sportsbook accounts at scale. Our API gives you the ability to access accounts, pull betting activity, and create bet slips. Use our Getting Started Guide and API Reference to integrate into any product experience.

The SharpSports API is organized around REST. We provide predictable resource-oriented URLs, accept form-encoded request bodies, return JSON-encoded responses, and use standard HTTP response codes, authentication, and verbs.

Current Version of SharpSports API: 1.29

Authentication

Example Request:

curl -H "Authorization: Token <API_KEY>" https://api.sharpsports.io/v1/books

Use API keys to authenticate requests. All requests should include the following header - "Authorization": "Token <API_key>".

Sign Up to grab your keys.

Sandbox API Key: Use this key for testing calls in the sandbox environment. This key only works with our test user credentials.

Live API Keys: Use these keys for linking real sportsbook accounts.

        Public: Use this key for everything except for GET requests on user data

        Private: Use this key for GET requests on user data. Only use this from your backend to protect the data in your users' accounts.

Getting Started

Overview

With the SharpSports API you can:

    1. Get authorized access to a sportsbook account via the bookLink UI

    2. Pull up-to-date historical and live betting activity from linked accounts

    3. [BETA] Offer betPlace links to pre-filled betslips on your users' accounts           Reach out for access.

Use the booklink button to direct users to SharpSports' hosted, whitelabeled UI. There, they can securely link new accounts and manage pre-existing linked accounts. Once an account is linked, you'll have API access to their full account history.

    Booklink Demo:

        This demo is built with a sandbox API key, so use the test creds:

        username: gooduser

        password: Test1

        See our full list of Test Users for more cases.

Use our pre-built packages for a quick and easy integration.

Web Browser Modal (html)

<div id="SSLink" style="margin-left:25px;"></div>

<script src="https://d388bvybj12fcd.cloudfront.net/button.js"

token = "public_API_key"
internalId = "your_internal_id"

buttonText='Link Sportsbook'
padding='15px 32px'
background-color='#4CAF50'
border='none'
color='white'
text-align='center'
text-decoration='none'
display='inline-block'
font-size='20px'
border-radius='8px'
font-family='Verdana, Geneva, sans-serif'>
</script>

- Web Browser Modal

SharpSports hosts the UI which enables linking and managing connected sportsbook accounts for your customers. Use the html snippet to the right to implement our booklink popup on a web browser.

- Mobile Packages

If you are integrating SharpSports into a mobile application we reccomend you use one of our mobile packages as they will give you access to our full suite of book integrations. There are three recommended mobile packages:

1) A typescript NPM package for React-Native applications

2) A Swift (SPM) package for iOS native applications

3) A Kotlin package for Android native applications

These packages are private, so please reach out to auth@sharpsports.io for access.

Some book integrations are only available through a mobile package, so make sure you follow our mobile package guidelines here: See the Mobile Only book Integrations section for details.

- SportsData.io Bet Tracking Widget

Our partners at sportsdata.io have built a pre-built bet tracking widget that can be integrated with just a few lines of code.

If you choose this path you can skip everything after step 2: configure the UI.

Alternative Integration Paths

2. Configure the UI

In your dashboard settings you'll see various options for configuring the booklink UI.

Company Name

Add the company name you'd like to display to your users.

Logo URL

Add a logo that will appear on the book list page.

Add Affiliate Links

Your users will have the opportunity to click the "Create Account" button in the booklink UI. If you have affiliate links, add them in the dashboard to make sure they are counted as valid conversions.

You can also add affiliate links via API endpoints.

Bettor Account Management Page

If you'd like to offer a page to users who already have at least one account linked to manage the connections (add, delete, refresh, and reauthorize) make sure the account management toggle is set to on.

Alternative Integration Paths

3. Subscribe to Webhook Events

Subscribe to Webhooks in the Dashboard > Settings > Webhooks.

Subscribe to the: refreshresponse.created event.

Set up a webhook listener that responds with a 200 status immediately (< 3 seconds).

You should process the data only after you respond to ensure you don't miss any data.

Alternative Paths

4. Initiating Refreshes

Endpoints

POST /v1/bettors/<internalID>/refresh

Request Example


curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettors/<internalId>/refresh

A refresh is the process by which SharpSports updates the data for a bettor and/or bettorAccount.

We automatically perform a refresh when an account is first linked, but you can also initiate a refresh with a POST request.

POST /v1/bettors/<internalID>/refresh - will initiate a refresh of all the bettorAccounts associated with a bettor. This will create a refreshresponse.created event for each associated bettorAccount.

If you are using the SharpSports mobile package you can use the SharpSports.Refresh() method instead of the above API call

See the Mobile Section section for more detail.

We recommend performing a refresh when a user logs into their account on your site/app. Users can refresh all their accounts on the bettor account management page at their discretion.

Alternative Integration Paths

5. Handling Refresh Responses

refreshresponse.created Payload

{
  "event": "refreshresponse.created",
  "sender": "SampleApp",
  "data": {
      "id": "RRES_95ac53f7a40e4911b96390d64d637e7b",
      "timeCreated": "2022-01-15T17:31:27.052529Z",
      "bettor": "BTTR_a0ebf8ba53304fde8b9b3d7f9605c841",
      "bettorAccount": "BACT_a679867dc9624bb4b75f6b9dc1e4a8c6",
      "status": 200,
      "detail": null,
      "requestId": "93947bc9c8374fb1a1177c2ea2654d95",
      "type": "manual",
      "betSlips": [
      { 
        "id": "SLIP_cad1b8c750264bd8a6a0295c8fe2bf67",
        "bets": [
          {
            "id": "BET_33d90803f71544b98f2f34c9c39d9aba",
            "line": -1.5,
            "live": false,
            "type": "straight",
            "event": {
              "id": "EVNT_64f9724ef7d241449e4b93ee490bc529",
              "name": "Cleveland Cavaliers @ Oklahoma City Thunder",
              "sport": "Basketball",
              "league": "NBA",
              "startDate": "2022-01-16",
              "startTime": "2022-01-16T01:00:00Z",
              "nameSpecial": null,
              "sportradarId": "1d00131f-f9fc-47d3-afac-544a35625d2b",
              "sportsdataioId": "20017337",
              "oddsjamId": "11464-19432-2022-01-15",
            },
            "status": "pending",
            "outcome": null,
            "segment": "1st Quarter",
            "position": "Cleveland Cavaliers",
            "incomplete": false,
            "propDetails": null,
            "proposition": "spread",
            "oddsAmerican": -115,
            "bookDescription": "Cleveland Cavaliers at Oklahoma City Thunder - 1st Quarter Spread - Cleveland Cavaliers",
            "marketSelection": "MRKT_b2b414b9ca0646708c017d0e77e5f8d0"
          }
        ],
        "book": {
          "id": "BOOK_IPBQaQQTCRxplZx7SYOA",
          "abbr": "ca",
          "name": "Caesars"
        },
        "type": "single",
        "toWin": 435,
        "atRisk": 500,
        "bettor": "BTTR_02fb0f062a5c4efb99ee6085a256f8d6",
        "status": "pending",
        "bookRef": "aca0a740-7625-11ec-9084-1936a6525167",
        "outcome": null,
        "subtype": null,
        "adjusted": {
          "line": null,
          "odds": false,
          "atRisk": null
        },
        "netProfit": null,
        "dateClosed": null,
        "incomplete": false,
        "timePlaced": "2022-01-15T17:07:52Z",
        "typeSpecial": null,
        "oddsAmerican": -115,
        "bettorAccount": "BACT_8728b28e698948d985a684900215270b"
      }]
}

A refresh will take 10-60 seconds on average, depending on how many new bets are being pulled. When it is complete, SharpSports will create a refreshresponse.created event that will include a refreshResponse object and the created/updated bets since the last request.

In your backend, set up a webhook receiver that saves the relevant data based on the case and responds to the webhook before performing any time consuming functions.

Cases to Handle

    1) 200: success

        - Save all the bets returned in the webhook payload

    2) 202: success (large data volume)

        - For especially large refresh payloads (usually the initial refresh that pulls the full history of an account) we don't return the betSlips in the webhook payload. Store the refreshResponseID and make a GET betslips request with refreshResponse query parameter to get the bets that would normally be present in the webhook payload. As these are large payloads you should also use Pagination query params. Make sure to respond to the webhook before fetching and processing these bets.

    3) 401: refresh not attempted - account is unverified

        - This means we were not able to access the account because the account is unverified bettoraccount.verified = false and possibly unverifiable bettorAccount.isUnverifiable = true. The bettor will have to reverify their account on the bettor account management page. You should prompt them to do so if you receive this response on one of their accounts.

    4) 403: refresh not attempted - access for this bettorAccount has been revoked

        - This means you, or the user has deactived their bettorAccount. You cannot perform refreshes on deactivated accounts. A bettor can go through the Book Link UI to reconnect the account if they wish.

     5) 406: refresh unsuccessful - bettor entered an incorrect (or null) One-Time-Password

         - If you do not use the bettorAccount management widget, you need to have OTP entry set up in your application. If you handle OTP entry in your app, the bettor should be prompted to try again to refresh the account

    6) 424: refresh not attempted - book or bookRegion is currently down for mantainence

        - Occasionally SharpSports will deactivate a book or a book region for mantainence.

    7) 429: refresh not attempted - rate limiting or refresh in progress

        - Account refreshes must be made at least 60 seconds apart and cannot overlap. Check the refreshInProgress flag on the bettorAccount to avoid this.

    7) 500: refresh unsuccessful - unhandled error

        - This type of error can occur if a sportsbook website is not available or the SharpSports API is down

Alternative Paths

6. Presenting Bets

Every betSlip contains all the details that make up a wager split into various attributes. For most wagers, we are able to parse all the details of the bet, but sometimes we are unable to get all the details. They will still be returned, but with bet.incomplete = true. You'll want to treat incomplete and complete bets differently.

Complete Bets

See the betSlip and bet models for a description of each field.

Every complete bet will have a sportsdata.io and an oddsjam event id associated with it if you’d like to pull additional information about the bet, or filter based on game, match, etc.

Add your sportradar api keys in the dashboard to have the sportradar event id's on betSlips.

Incomplete Bets

Incomplete bets will have all the relevant numerical information (atRisk, toWin, line, and odds) on the corresponding betSlip but the event, proposition, position and other qualitative information may not be full parsed.

For these bets we recommend using the bookDescription field to present all the relevant information to a user. This is a string that represents the info a user saw when placing the bet on the sportsbook and is present on all bets.

You can offer your users the ability to choose a bet on your platform and direct them straight to their sportsbook account with a pre-populated betSlip. During the Beta, we only support betPlace links for BetMGM, FanDuel, Caesars, PointsBet, and DraftKings, but more will be available soon.

Available Markets

During the Beta, the following represents the coverage of betPlace links.

Leagues

NFL, NBA, NHL, MLB, NCAAF, NCAAMB

Propositions

Spread, Moneyline, Total (Game), Total (Player)

Segments

All standard segments

Tailing Bets

Check betPlace Availability

curl -X GET -H "Authorization: Token <public_api_key>" https://api.sharpsports.io/v1/betSlips/<betSlipID>/betPlaceAvailability

Generate betPlace Link on Click

curl -X POST -H "Authorization: Token <public_api_key>" -d "internalId=<internal_id>&betSlip=<tailed_betslip_id>" https://api.sharpsports.io/v1/context/selection

Offer your users a link for placing the same wager as another bettor.

Use this endpoint to check if betPlace is available for this betSlip:

GET v1/betSlips/<betSlipID>/betPlaceAvailability

If the availability endpoint returns true, pass the betSlip.id and the internalId of the user placing the bet on click.

POST v1/context/selection

Generate the link and populate a webview or window with the url below for the user. On mobile, this link will generate a URI to redirect the user to the sportsbook app (or the app store if the sportsbook app is not installed on the device).

ui.sharpsports.io/place/<cid>

 

Offer your users links to place bets directly from an odds table or anywhere you advertise bets. SharpSports stores betting options in the form of marketSelections. Start by getting the appropriate marketSelection.id for a particular bet.

Sportsdata.io Example

curl -X GET -H "Authorization: Token <public_api_key>" https://api.sharpsports.io/v1/marketSelections?sdioMarketId=<sdioMarketId>&position=<position>

Step 1 - Find a Market Selection

SportsData.io Users:

Find a particular marketSelection using the SDIO MarketID and position to get an available position. Review the standardized values section for position formats we accept.

Sportradar Example

curl -X GET -H "Authorization: Token <public_api_key>" https://api.sharpsports.io/v1/marketSelections?sportradarEventId=<sportsradar_event_id>&proposition=<proposition>&position=<position>

Sportradar Users:

Find a particular marketSelection using the SportRadar EventID, Proposition, Position and Segment query params for straight bets. For props, you can add in Player, Team, and/or Metric to find an available market. Reference the standardized values section for formats we accept.

Other:

If you don't use one of our supported data providers, pass a unique combination of Position, Segment, Player, Team, and Metric to get the marketSelection you are looking for. Without the specific event id, there may be cases where a list of available markets will be returned.

Visit the standard values section of the docs to see the list of potential values for those fields.

Step 2 - Get the betPlace Link

POST Context Call

curl -X POST -H "Authorization: Token <public_api_key>" -d "internalId=<internal_id>&marketSelection=<marketSelectionID>&bookAbbr=<book_abbreviation>" https://api.sharpsports.io/v1/context/selection

Create a button for the market that triggers the POST Context Selection call on click. Pass the internalId,marketSelectionId and book.bookAbbr.

This call will return a cid - add that to our betPlace URL structure (below).

ui.sharpsports.io/place/<cid>

Open a webview, modal or window with the url, which will open the users' sportsbook app or site. On mobile, this link will generate a URI to redirect the user to the sportsbook app (or the app store if the sportsbook app is not installed on the device).

BetPlace for Parlays

BetPlace for multiple marketSelections

curl -X POST -H "Authorization: Token <public_api_key>" -H "Content-Type: application/x-www-form-urlencoded" -d "internalId=<internal_id>&marketSelection=<marketSelectionID>,<marketSelectionID>&bookAbbr=<book_abbreviation>" https://api.sharpsports.io/v1/context/selection
curl -X POST -H "Authorization: Token <public_api_key>" -H "Content-Type: application/json" -d '{"internalId":"<internal_id>","marketSelection":"<marketSelectionID>,<marketSelectionID>","bookAbbr":"<book_abbreviation>"}' https://api.sharpsports.io/v1/context/selection

During the Beta, not all available sportsbooks support BetPlace for Parlays. Currently, parlays are supported on FanDuel, Caesars, and BetMGM. For PointsBet, we support deeplinking for a single bet only. For DraftKings, a BetPlace link will redirect the user to the event page for the particular bet

betSlips

When tailing a betSlip that is a parlay, the /betPlaceAvailability endpoint will return true if all bets attached to that betSlip are tailable, and false if any or all of the bets cannot be tailed. If the betSlip is on a book where parlays are not available for betPlace, this endpoint will return false

marketSelections

To generate a betPlace link for multiple marketSelections, simply pass in multiple comma separated marketSelection values to the /context/selection endpoint.

8. Testing

Sandbox

Your sandbox account comes loaded with one test_bettor, which you can see in the bettors table. Use the internalID input and the booklink button to create more bettors using the test users. Each test account will come with a large sample of bets, and new random bets will be generated every time you run a refresh.

Live Accounts

Upgrade your account to live once you're ready to test using real sportsbook accounts. You'll have to switch out the sandbox api key with your live api keys to test real accounts.

API Reference

Book

Endpoints

GET /v1/books

The book object represents a sportsbook that you can link with. This means they have allowed you to connect with their bettor's accounts and pull bet data.

The Book Object

Example book Object

 {
        "id": "BOOK_c81242f993894e67966b3ccfc4ba3a65",
        "name": "Barstool",
        "abbr": "bs",
        "status": "active",
        "mobileOnly": true,
        "refreshCadenceActive": true
  }

id (string)

A unique identifier representing the bookID. Each bookID will start with the unique character set 'BOOK_'.

name (string)

A descriptor that represents the common name of the sportsbook.

abbr (string)

A 2 character descriptor that represents the common abbreviation of the book's common name.

status (string)

The current status of the book - one of the following:

active - The sportsbook is available for new links and refreshes

inactive - The sportsbook is currently down for maintenence

coming - The sportsbook integration is in development

mobileOnly (boolean)

This field indictates if the integration with this book is only available through the SharpSports Mobile Packages

refreshCadenceActive (boolean)

This field indictates if the refresh cadence is currently available for this book.

Get a List of Books

Request


curl -X GET -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/books

Get a list of all the books associated with your account.

 

GET https://api.sharpsports.io/v1/books

 

Parameter Default Description Required Type
none - - - -

Supported Books

To see a list of supported books and their statuses go the the Dashboard > Settings > Account

SharpSports pulls the full bet history (maximum of 2000 bets) and balance of a sportsbook account with the following limitations:

PrizePicks

BetMGM

Borgata

BookRegion

Endpoints

GET /v1/bookRegions
GET /v1/bookRegions/<BookRegionID>

The bookRegion object represents a sportsbook in a specific region.

The BookRegion object

Example BookRegion Object

{
  "id": "BSTA_lqpNkqJjSSv5MwxCXSFbQ",
  "book": {
    "id": "BOOK_nhLZ9l5DRs6w6KcE2n7vnw",
    "name": "DraftKings",
    "abbr": "dk"
        },
  "name": "Iowa",
  "abbr": "ia",
  "status": "active",
  "country": "United States",
  "mobileOnly": true
}

id (string)

A unique identifier representing the bookRegionID.

book (hash)

The book object associated with this bookRegion

name (string)

A descriptor that represents the common name of the region.

abbr (string)

A 2 character descriptor that represents the common abbreviation of the region

status (string)

One of the following statuses:

active: Bettors can currently connect with accounts in this bookRegion

inactive: This bookRegion is currently under maintenence and Bettors are unable to connect

coming: An integration in this bookRegion is in progress and coming soon

unsupported: An integration in this bookRegion is not currently supported

country (string)

The country where the reigon is located: currently either United States or Canada

mobileOnly (boolean)

This field indictates if the integration with this bookRegion is only available through the SharpSports Mobile Packages

Get a BookRegion Details

Request


curl -X GET -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bookRegions/BRGN_503885669ff2458c917e6bb9040158e6

 

GET https://api.sharpsports.io/v1/bookRegions/<BookRegionID>

 

Parameter Default Description Required Type
BookRegionID null The ID of the bookRegion you are requesting yes string

Get a List of BookRegions

Request


curl -X GET -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bookRegions

Get a list of all the bookRegions

 

GET https://api.sharpsports.io/v1/bookRegions

 

Query Parameter Default Description Required Type
status null Filter by a bookRegion status no string
book null Filter by a bookID or abbreviation no string

Bettor

Endpoints

GET /v1/bettors
GET /v1/bettors/<bettorID>
GET /v1/bettors/<internalID>

Bettors represent your customers who have one or more sportsbook accounts. The Bettor object is created when they first successfully verify a sportsbook account with the Book Link UI.

The Bettor Object

Example Bettor Object

  {
    "id":"BTTR_Bz4xjCdtS4mlb42OHLJF0Q",
    "internalId":"12345",
    "betRefreshRequested":"2020-07-07T19:05:47.336370Z",
    "timeCreated":"2020-06-09T19:31:26.904934Z",
    "metadata": {
      "handle":10874239,
      "unitSize":30460,
      "netProfit":-251582,
      "winPercentage":43.03,
      "totalAccounts":1
    }
  }

id (string)

A unique identifier representing the bettorID. Each bettorID will start with the unique character set 'BTTR_'.

internalId (string)

Your internal unique identifier for a bettor.

betRefreshRequested (datetime)

The last time a refresh request was performed for this bettor. Other refreshes may have been performed at the bettorAccount level, but this value represents the last time a refresh was requested at the bettor level (for all bettorAccounts).

timeCreated (datetime)

A timestamp for the creation of the bettor object.

Get Bettor Details

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_ln131QtBRWmuUR8zyIxkA

With a specific bettorID you can retrieve a bettor object.

 

GET https://api.sharpsports.io/v1/bettors/<bettorID>

GET https://api.sharpsports.io/v1/bettors/<bettorID>/metadata

Parameter Default Description Required Type
bettorID null the SharpSports ID of the bettor you are requesting. yes string

 

GET https://api.sharpsports.io/v1/bettors/<internalID>

GET https://api.sharpsports.io/v1/bettors/<internalID>/metadata

 

Parameter Default Description Required Type
internalID null your internal ID of the bettor you are requesting. yes string

Get a List of Bettors

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettors

Get a list of all the bettors associated with your account.

 

GET https://api.sharpsports.io/v1/bettors

 

Query Parameters

GET https://api.sharpsports.io/v1/bettors?limit=100

limit | null | max number of bettors returned, ordered by timeCreated descending | no | int pageSize | null | see Pagination | no | int pageNum | null | see Pagination | no | int

Metadata Query Parameters

GET https://api.sharpsports.io/v1/bettors/bettorId?metadata=true&league=NFL

GET https://api.sharpsports.io/v1/bettors/bettorId/metadata?league=NFL

Query Parameters Default Description Required Type
metadata false Include bettor metadata in response no boolean
timePlacedStart null filters metadata to betslips placed after this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
timePlacedEnd null filters metadata to betslips placed before this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
league null filters metadata to betslips which include bets on events associated with this league no string
sport null filters metadata to betslips which include bets on events associated with this sport no string
type null filters metadata to betslips with either single or parlay no string
adjustedAtRisk null if true filters metadata to betslips with non-null adjusted.atRisk no boolean
adjustedOdds null filters metadata to betslips with corresponding adjusted.Odds no boolean
adjustedLine null filters metadata to betslips with corresponding adjusted.Line no boolean

 

BettorAccount

Endpoints

GET /v1/bettorAccounts/<bettorAccountID>
GET /v1/bettors/<bettorID>/bettorAccounts
GET /v1/bettors/<internalID>/bettorAccounts
PUT /v1/bettorAccounts/<bettorAccountID>/access
PUT /v1/bettorAccounts/<bettorAccountID>/paused

A bettorAccount represents a linked sportsbook for a specific bettor. A bettorAccount is created once we have verified the credentials for the account. A bettor may have several bettorAccounts, each representing their relationship with a different sportsbook.

The BettorAccount object

Example BettorAccount Object

{
        "id": "BACT_7daed31d9b4f4a79bdb4b30f2bf89852",
        "bettor": "BTTR_4d1ce9ad0b314290a775d2b89a5316c2",
        "book": {
            "id": "BOOK_nhLZ9l5DRs6w6KcE2n7vnw",
            "name": "DraftKings",
            "abbr": "dk"
        },
        "bookRegion": {
            "id": "BSTA_Okuj8vPwRPSMnYhROBE1Uw",
            "name": "Colorado",
            "abbr": "co",
            "status": "active",
            "country": "United States"
        },
        "verified": true,
        "access": true,
        "paused": false,
        "betRefreshRequested": "2021-11-12T11:05:37.399401Z",
        "latestRefreshResponse": {
            "id": "RRES_e09da01f563146d7af294abec834ebe7",
            "timeCreated": "2021-11-12T11:05:49.778529Z",
            "status": 200,
            "detail": null,
            "requestId": "326d9234c63545ff8d29a598a713a2c9"
        },
        "latestRefreshRequestId": "326d9234c63545ff8d29a598a713a2c9",
        "balance": 1158,
        "timeCreated": "2021-11-03T21:02:59.880554Z",
        "missingBets": 0,
        "isUnverifiable": false,
        "refreshInProgress": false,
        "TFA": false,
        "metadata": {
            "handle":10754420,
            "unitSize":30124,
            "netProfit":251592,
            "winPercentage":57.48,
            "walletShare":34.52
        }
    }

id (string)

A unique identifier representing the bettorAccountID. Each bettorAccountID will start with the unique character set 'BACT_'.

bettor (hash)

An object representing the bettor who owns the bettorAccount. You can reference the bettorID to store and match the bettorAccount with the right record in your database.

book (hash)

An object representing the book where the account was created. This includes the bookID, and two string descriptors.

bookRegion (hash)

An object representing the book-region relationship where the account was created. This object provides both the name and abbreviation of the region where the account is located.

verified (bool)

Represents the status of the current set of credentials we have on file for this bettorAccount. Verified will be true if the credentials are up to date allow access to the sportsbook account. If verified is false, then the credentials have been changed or the account has been deactivated and you should prompt the bettor to address or unlink the account.

isUnverifiable (bool)

If an account cannot be verified after several attempts then it becomes unverifiable. This means that the only way for the bettor to re-link this account is by re-entering their credentials through the BookLink button.

access (bool)

Represents the permissions granted by the bettor on this bettorAccount. Access will be true once they grant access, but if they request to revoke it, access should be set to false. If access is false, then no refresh requests can be made associated with this bettorAccount.

paused (bool)

Represents the current state of bet syncing for a linked bettorAccount. If paused is true, then no refreshes will be done on the account but you can still access betslips and other data associated with this account.

betRefreshRequested (datetime)

Represents the last time a refresh was performed for this bettorAccount (except those throttled due to rate-limiting).

latestRefreshResponse (hash)

An object representing the refreshResponse from the latest refresh request performed on this bettorAccount (that was not throttled due to rate-limiting).

latestRefreshRequestId (string)

The id from the latest refresh request associated with this bettorAccount (that was not throttled due to rate-limiting). If this does not match the requestId on the latestRefreshResponse, then a refresh is currently in progress.

balance (integer)

The current available balance (in cents) in the linked bettorAccount (updated on account refresh). This field will not be included if the bettorAccount has access = false

missingBets (integer)

Occasionally SharpSports will not be able to pull a bet from the sportsbook due to an unrecognized format. This field represents the number of bets we were unable to pull from this account.

refreshInProgress (boolean)

This flag indicates if the bettorAccount is currently being refreshed. You cannot request a refresh on a bettor account if there is already a refresh in progress

TFA (boolean)

This flag indicates that a bettorAccount has Two-Factor-Authentication enabled and will require a code to be entered on every refresh

timeCreated (datetime)

A timestamp for the creation of the bettorAccount object.

Get a BettorAccount Details

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_25ko1xXuSmaX393YqBuM4w

With a specific bettorAccountID you can retrieve a bettorAccount object. A common reason for retrieving a bettorAccount is to check its verified/access status.

 

GET https://api.sharpsports.io/v1/bettorAccounts/<bettorAccountID>

GET https://api.sharpsports.io/v1/bettorAccounts/<bettorAccountID>/metadata

 

Parameter Default Description Required Type
bettorAccountID null the ID of the bettorAccount you are requesting. yes string

Get a List of BettorAccounts by Bettor

With a specific bettorID or internalID you can retrieve a list of bettorAccount objects associated with this bettor.

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_Gz4vUZFIQd+oO0lhMQPdCw/bettorAccounts

With a specific bettorID or internalID you can retrieve a list of the bettorAccount objects associated with a bettor. A common reason for retrieving a list of bettorAccounts is to provide information to a bettor about their linked sportsbooks.

 

GET https://api.sharpsports.io/v1/bettors/<bettorID>/bettorAccounts

 

Parameter Default Description Required Type
bettorID null the Sharpsports ID of the bettor whose bettorAccounts you are requesting. yes string

 

GET https://api.sharpsports.io/v1/bettors/<internalID>/bettorAccounts

 

Parameter Default Description Required Type
internalID null your internal ID of the bettor whose bettorAccounts you are requesting. yes string

Get a List of All BettorAccounts

You can requests a list of all bettorAccount linked by SharpSports (typically used with query parameters)

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettorAccounts?limit=100&verified=true

 

GET https://api.sharpsports.io/v1/bettorAccounts

 

Update a BettorAccount

With a specific bettorAccountID you can manually update the access and paused fields on a BettorAccount.

Request


curl -X PUT -d "access=false" -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_25ko1xXuSmaX393YqBuM4w/access

 

PUT https://api.sharpsports.io/v1/bettorAccounts/<bettorAccountID>/access

Note: You can only set access to false using this API endpoint since this bettor has requested that their data for this account cannot be accessed. The bettor must relink their account in order to turn access back on.

 

Parameter Default Description Required Type
bettorAccountID null the ID of the bettorAccount you are updating. yes string
access null desired access value (passed as data) true bool

Request


curl -X PUT -d "paused=true" -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_25ko1xXuSmaX393YqBuM4w/paused

 

PUT https://api.sharpsports.io/v1/bettorAccounts/<bettorAccountID>/access

 

Parameter Default Description Required Type
bettorAccountID null the ID of the bettorAccount you are updating. yes string
paused null desired paused value (passed as data) true bool

 

Query Parameters

GET https://api.sharpsports.io/v1/bettorAccounts?limit=100&access=true

Query Parameters Default Description Required Type
access null filter based on access=true/false no boolean
verified null filter based on verified=true/false no boolean
isUnverifiable null filter based on isUnverifiable=true/false no boolean
limit null max number of bettors returned, ordered by timeCreated descending no int
pageSize null see Pagination no int
pageNum null see Pagination no int

Metadata Query Parameters

GET https://api.sharpsports.io/v1/bettorAccounts/bettorAccountId?metadata=true&league=NFL

GET https://api.sharpsports.io/v1/bettorAccounts/bettorAccountId/metadata?league=NFL

Query Parameters Default Description Required Type
metadata false Include bettorAccount metadata in response no boolean
timePlacedStart null filters metadata to betslips placed after this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
timePlacedEnd null filters metadata to betslips placed before this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
league null filters metadata to betslips which include bets on events associated with this league no string
sport null filters metadata to betslips which include bets on events associated with this sport no string
type null filters metadata to betslips with either single or parlay no string
adjustedAtRisk null if true filters metadata to betslips with non-null adjusted.atRisk no boolean
adjustedOdds null filters metadata to betslips with corresponding adjusted.Odds no boolean
adjustedLine null filters metadata to betslips with corresponding adjusted.Line no boolean

 

Metadata

Endpoints

GET /v1/bettors/<bettorID>?metadata=true
GET /v1/bettorAccounts/<bettorAccountID>?metadata=true
GET /v1/bettors/<bettorID>/metadata
GET /v1/bettorAccounts/<bettorAccountID>/metadata

Metadata objets include aggregate statistics about a bettorAccount or bettor

The Metadata Object

Example Metadata Object

{
    "metadata": {
        "handle": 11183479,
        "unitSize": 30640,
        "netProfit": -251592,
        "winPercentage": 43.08,
        "totalAccounts": 1
    }
}

Request


curl -X GET -H 'Authorization: Token <private_API_key>' https://api.sharpsports.io/v1/bettors/BTTR_1ffb474a5b8e4b05a1728cf7207aee6a/metadata'

handle (integer)

The aggregated amount (in cents) that have been wagered (atRisk).

unitSize (integer)

The average wager (atRisk) amount (in cents).

winPercentage (float)

The percentage of aggregate betSlips won.

totalAccounts (integer)

A bettor's total number of linked sportsbook accounts (only available for bettor.metadata)

walletShare (float)

The percentage of handle a bettor places on one of their bettorAccounts.

Query Parameters

GET https://api.sharpsports.io/v1/bettors/bettorId?metadata=true&league=NFL

GET https://api.sharpsports.io/v1/bettorAccounts/bettorAccountId?metadata=true&league=NBA

GET https://api.sharpsports.io/v1/bettors/bettorId/metadata?league=MLB

GET https://api.sharpsports.io/v1/bettorAccounts/bettorAccountId/metadata?sport=tennis

Query Parameters Default Description Required Type
metadata false Include bettor or bettorAccount metadata in response no boolean
timePlacedStart null filters metadata to betslips placed after this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
timePlacedEnd null filters metadata to betslips placed before this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
league null filters metadata to betslips which include bets on events associated with this league no string
sport null filters metadata to betslips which include bets on events associated with this sport no string
type null filters metadata to betslips with either single or parlay no string
adjustedAtRisk null if true filters metadata to betslips with non-null adjusted.atRisk no boolean
adjustedOdds null filters metadata to betslips with corresponding adjusted.Odds value no boolean
adjustedLine null filters metadata to betslips with corresponding adjusted.Line value no boolean

BetSlip

Endpoints

GET /v1/bettors/<bettorID>/betSlips
GET /v1/bettors/<internalID>/betSlips
GET /v1/bettorAccounts/<bettorAccountID>/betSlips
GET /v1/betSlips

Bet slips are pulled from a bettor's sportsbook account on refresh. Once in the SharpSports database, bet slips can be requested using any of our betSlip endpoints / queries.

A BetSlip resource represents a wager placed by a bettor with their sportsbook. A bet slip can have multiple bets attached in the case of a parlay, teaser or other multiple outcome wager type.

The BetSlip Object

Example BetSlip Object

{
    "id": "SLIP_b2d0fded980345b39ca728e0240e45d4",
    "bettor": "BTTR_4a8ff3b74a394bb3a928b9ca53147faf",
    "book": {
      "id": "BOOK_nhLZ9l5DRs6w6KcE2n7vnw",
      "name": "DraftKings",
      "abbr": "dk"
    },
    "bettorAccount": "BACT_44c71c332f4d4c61a90440eaff473bd1",
    "bookRef": "637779508179321312",
    "timePlaced": "2022-01-16T17:26:57Z",
    "type": "parlay",
    "subtype": null,
    "oddsAmerican": 13000,
    "atRisk": 500,
    "toWin": 65000,
    "status": "completed",
    "outcome": "loss",
    "refreshResponse": "RRES_da3df19bc3a74975a2d76113b761eac2",
    "incomplete": true,
    "netProfit": -500,
    "dateClosed": "2022-01-16",
    "typeSpecial": null,
    "bets": [
      {
        "id": "BET_b71653bf80ca4ba69e8913904e817582",
        "type": null,
        "event": {
          "id": "EVNT_aa034faf62bd434fa8046ab9200e6e32",
          "sportsdataioId": "17981",
          "sportradarId": "130c05e4-aade-4bbe-a654-b9f14812f963",
          "oddsjamId": "17233-42288-2022-01-16",
          "league": "NFL",
          "sport": "Football",
          "name": "Philadelphia Eagles @ Tampa Bay Buccaneers",
          "nameSpecial": null,
          "startTime": "2022-01-16T18:00:00Z",
          "startDate": "2022-01-16"
        },
        "proposition": null,
        "segment": null,
        "position": null,
        "line": null,
        "oddsAmerican": null,
        "status": "completed",
        "outcome": "loss",
        "live": false,
        "incomplete": true,
        "bookDescription": "PHI Eagles @ TB Buccaneers - 1st Touchdown Scorer - 1st Half - Mike Evans",
        "marketSelection": null,
        "propDetails": null
      },
      {
        "id": "BET_f92a6c26dccc427c86ccfcb26ef07112",
        "type": "straight",
        "event": {
          "id": "EVNT_aa034faf62bd434fa8046ab9200e6e32",
          "sportsdataioId": "17981",
          "sportradarId": "130c05e4-aade-4bbe-a654-b9f14812f963",
          "oddsjamId": "17233-42288-2022-01-16",
          "league": "NFL",
          "sport": "Football",
          "name": "Philadelphia Eagles @ Tampa Bay Buccaneers",
          "nameSpecial": null,
          "startTime": "2022-01-16T18:00:00Z",
          "startDate": "2022-01-16"
        },
        "proposition": "total",
        "segment": null,
        "position": "Under",
        "line": 57.5,
        "oddsAmerican": null,
        "status": "completed",
        "outcome": "win",
        "live": false,
        "incomplete": false,
        "bookDescription": "PHI Eagles @ TB Buccaneers - Alternate Total Points - Under 57.5",
        "marketSelection": null,
        "propDetails": null
      },
      {
        "id": "BET_0f9c662b736a420fb369dc2de6f6ac81",
        "type": "prop",
        "event": {
          "id": "EVNT_aa034faf62bd434fa8046ab9200e6e32",
          "sportsdataioId": "17981",
          "sportradarId": "130c05e4-aade-4bbe-a654-b9f14812f963",
          "oddsjamId": "17233-42288-2022-01-16",
          "league": "NFL",
          "sport": "Football",
          "name": "Philadelphia Eagles @ Tampa Bay Buccaneers",
          "nameSpecial": null,
          "startTime": "2022-01-16T18:00:00Z",
          "startDate": "2022-01-16"
        },
        "proposition": "total",
        "segment": null,
        "position": "Over",
        "line": 2.5,
        "oddsAmerican": null,
        "status": "completed",
        "outcome": "loss",
        "live": false,
        "incomplete": false,
        "bookDescription": "PHI Eagles @ TB Buccaneers - Tom Brady Passing Touchdowns - 3+",
        "marketSelection": null,
        "propDetails": {
          "future": false,
          "player": "Tom Brady",
          "team": null,
          "matchupSpecial": null,
          "metricSpecial": "Passing Touchdowns"
        }
      },
      {
        "id": "BET_76e1c9f659ed47b798f03d1aa6b4f21d",
        "type": "prop",
        "event": {
          "id": "EVNT_aa034faf62bd434fa8046ab9200e6e32",
          "sportsdataioId": "17981",
          "sportradarId": "130c05e4-aade-4bbe-a654-b9f14812f963",
          "oddsjamId": "17233-42288-2022-01-16",
          "league": "NFL",
          "sport": "Football",
          "name": "Philadelphia Eagles @ Tampa Bay Buccaneers",
          "nameSpecial": null,
          "startTime": "2022-01-16T18:00:00Z",
          "startDate": "2022-01-16"
        },
        "proposition": "total",
        "segment": null,
        "position": "Over",
        "line": 49.5,
        "oddsAmerican": null,
        "status": "completed",
        "outcome": "loss",
        "live": false,
        "incomplete": false,
        "bookDescription": "PHI Eagles @ TB Buccaneers - Jalen Hurts Rushing Yards - Over 49.5",
        "marketSelection": null,
        "propDetails": {
          "future": false,
          "player": "Jalen Hurts",
          "team": null,
          "matchupSpecial": null,
          "metricSpecial": "Rushing Yards"
        }
      },
      {
        "id": "BET_4277054b4b714b35930a7c6b83dbd5d2",
        "type": "prop",
        "event": {
          "id": "EVNT_aa034faf62bd434fa8046ab9200e6e32",
          "sportsdataioId": "17981",
          "sportradarId": "130c05e4-aade-4bbe-a654-b9f14812f963",
          "oddsjamId": "17233-42288-2022-01-16",
          "league": "NFL",
          "sport": "Football",
          "name": "Philadelphia Eagles @ Tampa Bay Buccaneers",
          "nameSpecial": null,
          "startTime": "2022-01-16T18:00:00Z",
          "startDate": "2022-01-16"
        },
        "proposition": "total",
        "segment": null,
        "position": "Over",
        "line": 4.5,
        "oddsAmerican": null,
        "status": "completed",
        "outcome": "win",
        "live": false,
        "incomplete": false,
        "bookDescription": "PHI Eagles @ TB Buccaneers - Dallas Goedert Receptions - 5+",
        "marketSelection": null,
        "propDetails": {
          "future": false,
          "player": "Dallas Goedert",
          "team": null,
          "matchupSpecial": null,
          "metricSpecial": "Receptions"
        }
      },
      {
        "id": "BET_15225680b00c424f9354ff7b82d85b33",
        "type": "straight",
        "event": {
          "id": "EVNT_aa034faf62bd434fa8046ab9200e6e32",
          "sportsdataioId": "17981",
          "sportradarId": "130c05e4-aade-4bbe-a654-b9f14812f963",
          "oddsjamId": "17233-42288-2022-01-16",
          "league": "NFL",
          "sport": "Football",
          "name": "Philadelphia Eagles @ Tampa Bay Buccaneers",
          "nameSpecial": null,
          "startTime": "2022-01-16T18:00:00Z",
          "startDate": "2022-01-16"
        },
        "proposition": "spread",
        "segment": null,
        "position": "Philadelphia Eagles",
        "line": 10.5,
        "oddsAmerican": null,
        "status": "completed",
        "outcome": "loss",
        "live": false,
        "incomplete": false,
        "bookDescription": "PHI Eagles @ TB Buccaneers - Alternate Spread - PHI Eagles +10.5",
        "marketSelection": null,
        "propDetails": null
      }
    ],
    "adjusted": {
      "odds": false,
      "line": null,
      "atRisk": null
    }
  }

id (string)

A unique identifier representing the betID. Each betID will start with the unique character set 'SLIP_'.

refreshResponse (hash)

A object representing the refreshResponse that is associated with the bet. This attribute corresponds to the most recent refreshResponse that has created or updated this bet object.

bettor (hash)

An object representing the associated bettor. The BettorID can be used to store the bet with the correct bettor.

book (hash)

An object representing the book where the bet was placed. If you want to organize your bets by where they were placed you can use the book object which includes an ID and multiple string descriptors.

bettorAccount (hash)

A object representing the bettorAccount where the bet was made. If you'd like to associate the bet with the specific bettor / sportsbook combination, you can utilize the bettorAccountID.

bookRef (string)

The book's unique identifier for this particular betslip. Each sportsbook has their own system for identifying specific bets. This can be used for support, or for deeper integrations with sports books.

timePlaced (datetime)

The date and time the bet was placed. This field will be null if the sportsbook does not provide this information.

type (string)

A bet slip can be one of the following types:

single - this is a betslip that contains one single "bet" or wager

parlay - any betslip that contains multiple combined "bets"

subtype (string)

Some combination bets have traits that distinguish them from standard parlays. This standardized string provides additional information about the type of the bet, and can be one of the following:

round robin

teaser

typeSpecial (string)

This field can contain an unstandardized string that describes the bet further. For example, By 3's for some round robin bets or Can't Lose Parlay for a specially named boosted bet.

oddsAmerican (integer)

Represents the American odds agreed on by the bettor and sportsbook for this bet. If the bet is a parlay, then the odds for each individual bet will differ.

status (string)

Status of the bet slip as of the most recent refresh - completed or pending. At the current state, we rely on the sportsbooks for the bet status. You'll need to run frequent refreshes and/or calculate results to have the most up to date status.

atRisk (integer)

Represents the amount of money (in cents) put up by the bettor in the betslip. This is the amount they will lose if the outcome is loss.

toWin (integer)

Represents the max amount of profit (in cents) that will be paid out to the bettor if the outcome is win. This is calculated based on the amount atRisk and the odds set by the sportsbook. If the bet is a parlay this will be calculated using the parlay odds. This value never changes over the lifetime of a betSlip; for example if the bet is a parlay and one leg is a push the updated winnings/payout will be represented in the netProfit field.

netProfit (integer)

Represents the profit generated by the wager (in cents). Typically this field is equal to the toWin field if the bet has outcome win and is negative atRisk if the outcome is loss. However in the case of a multi-leg bet with variable winnings you can use this field as the source of truth for how much the wager paid out once it was completed. You can also determine how much money was refuned in the case of outcome = cashout.

outcome (string)

A string descriptor of the bet outcome. The most common outcomes are as follows - win / loss / push / void / cashout. For Asian Handicap soccer bets and some futures bets outcomes can also be halfwin and halfloss. This value will be null until status = completed.

incomplete (boolean)

A bet slip is incomplete if any of the attached bets are incomplete.

dateClosed (date)

The date when the wager status changed from pending -> completed. This field will be null if the sportsbook does not provide this information.

bets (list)

A list of serialized bets which determine bet slip outcome.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Getting a BetSlip Details

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/betSlips/SLIP_e67ae0773c264061a30dfcb91a4346db

With a specific betSlipID you can retrieve a betSlip object.

GET https://api.sharpsports.io/v1/betSlips/<betSlipID>

Parameter Default Description Required Type
betSlipID null the ID of the betSlip you are requesting yes string

Getting a List of BetSlips

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_vsiAC+D7Tqu8D4gMGjZEbA/betSlips

 

GET https://api.sharpsports.io/v1/betSlips

GET https://api.sharpsports.io/v1/bettors/<bettorID>/betSlips

GET https://api.sharpsports.io/v1/bettors/<internalID>/betSlips

GET https://api.sharpsports.io/v1/bettorAccounts/<bettorAccountID>/betSlips

 

Parameter Default Description Required Type
bettorID null the SharpSports ID of the bettor assoicated with the requested betSlips no string
internalID null your internalID of the bettor assoicated with the requested betSlips no string
bettorAccountID null the SharpSports ID of the bettorAccount assoicated with the requested betSlips no string

Query Parameters

GET https://api.sharpsports.io/v1/betSlips?refreshResponse=RRES_3nAMdOPTTMi68ahdyxGTwg&abbr=wh&status=pending&limit=5

 

Query Parameter Default Description Required Type
refreshResponse null the ID of a refreshResponse associated with a betSlip no string
book null the ID of book where a betSlip wager was placed no string
abbr null the abbreviation of book where a betSlip wager was placed no string
status null the status of a betSlip no string
limit null max number of betSlips returned, ordered by timePlaced no int
pageSize null see Pagination no int
pageNum null see Pagination no int
timePlacedStart null filters betslips to after this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
timePlacedEnd null filters betslips to before this datetime no %Y-%m-%dT%H:%M:%S OR %Y-%m-%d (string)
league null filters betslips to those including bets on events associated with this league no string
sport null filters betslips to those including bets on events associated with this sport no string
type null filters betslips to either single or parlay no string
adjustedAtRisk null if true filters betslips to only those with non-null adjusted.atRisk no boolean
adjustedOdds null filters based on adjusted.Odds no boolean
adjustedLine null filters based on adjusted.Line no boolean

Adjusted

adjusted is an object that contains all necessary information to determine whether info on the BetSlip object has been adjusted by a promotion from the sportsbook.

The adjusted object

Example adjusted

{
  "odds":true,
  "atRisk":null,
  "line":null
}

odds (boolean)

This field will be true if the odds of a slip have been adjusted from their original value. This can happen due to various promotions provided by the sportsbooks (i.e. odds boosts, profit boosts, etc.).

atRisk (int)

This field represents the actual stake at risk to the bettor if it has been adjusted. For example, in the case of a free bet this value will be 0.

line (boolean)

This field will be true if the line on a slip has been adjusted from its original value due to a promotion from the sportsbook.

Bet

A bet represents an individually graded element on the bet slip. Different slip types have different logic that governs how the individually graded bets will interact to generate a slip outcome.

The Bet Object

Example Bet Object

      {
        "id": "BET_d6495d9d9cb34b599072b3dee9f2f766",
        "type": "straight",
        "event": {
          "id": "EVNT_937797be824a48d79cb17ecbdb584536",
          "sportsdataioId": "17990",
          "sportradarId": "2cc5f37c-a7ea-41a8-8956-8e93db052186",
          "oddsjamId": "78014-42288-2022-01-23",
          "league": "NFL",
          "sport": "Football",
          "name": "Los Angeles Rams @ Tampa Bay Buccaneers",
          "nameSpecial": null,
          "startTime": "2022-01-23T20:00:00Z",
          "startDate": "2022-01-23"
        },
        "proposition": "spread",
        "segment": null,
        "position": "Tampa Bay Buccaneers",
        "line": -2.5,
        "oddsAmerican": -115,
        "status": "pending",
        "outcome": null,
        "live": false,
        "incomplete": false,
        "bookDescription": "LA Rams @ TB Buccaneers - Spread - TB Buccaneers -2.5",
        "marketSelection": "MRKT_73a64c308bf646798df9fcd7a11d8a2f",
        "propDetails": null,
        "autograde": false
      }

id (string)

A unique identifier representing the bet. Each bet ID will start with the unique character set 'BET_'.

type (string)

bet type refers to the type of wager it represents. The two types are straight and prop. A straight bet is a wager on the result of an event, or a segment of an event. A prop is anything that is not a wager on the result of an event, or a segment of an event. Standard spreads, moneylines and totals on a full game, period or half would be straight bets, while an individual player to score over a certain number of points would be a prop.

event (object)

An object representing the event the bet outcome is based on. The event object includes a unique id, some descriptive information about the bet, and some associated data provider identifiers. If you use a specific sports data feed, we recommend you use their identifier to associate the bet with your own event infrastructure.

proposition (string)

Proposition represents the aspect of the event that is being bet on. In the case of a straight bet, this will always be one of spread, moneyline, total or 3-way. In the case of a prop bet, this can be one of those four options, or a description of unique aspect like gatorade color poured on winning head coach.

propDetails (object)

An object representing the propDetails: a list of structured information that further defines the prop. This will be null unless bet.type = prop.

segment (string)

This represents the specific half, quarter, or other specific segment of the event that the bet is based on.

position (string)

A position represents which side of a wager the bettor is taking against the book. In the case of a total, the position would be Over or Under, while in the case of a spread the position would be a team.

line (float)

Represents the line set by the sportsbook for this particular bet. In the case of a total or spread proposition this will contain a value, otherwise it will be null.

oddsAmerican (integer)

Represents the American odds agreed on by the bettor and sportsbook for this bet. If the bet is a parlay, then the odds for each individual bet will differ.

status (string)

Status of the bet slip as of the most recent refresh - completed or pending. At the current state, we rely on the sportsbooks for the bet status. You'll need to run frequent refreshes and/or calculate results to have the most up to date status.

outcome (string)

A one character descriptor of the bet outcome. Possible values include - win / loss / push / void. This value will be null until status is completed.

live (boolean)

A value representing whether the bet was placed during a specific matchup.

incomplete (boolean)

An incomplete bet is one that is not fully parsed (yet). Incomplete bets will always include the accounting information (on the betSlip), and a bookDescription, but may not include other structured information.

bookDescription (string)

This field represents the unparsed version of the book's description of the bet. For incomplete bets, this should represent most of the missing information.

marketSelection (hash)

A reference to a marketSelection objects associated with this bet.

autograde (boolean)

If you have enabled the autograde feature in the dashboard settings, then all pending bets will be resulted by the SharpSports grading engine with needing an account refresh. If a bet was graded automatically, then autograde will be true. In this case, the result will be based on the grading engine.

PropDetails

propDetails is an object that contains all necessary information to categorize prop bets. This object is additive to the proposition field on a bet, and will be null, unless there is additional information necessary. These fields are standardized otherwise they will be null and the bet will be incomplete.

The propDetails object

Example propDetails


{
  "player":"James Harden",
  "team":null,
  "matchupSpecial":null,
  "metricSpecial":"Free Throws",
  "future":false
}

player (string)

This field represents the player that the bet concerns in the case of a player prop.

team (string)

This field represents the team that the bet concerns in the case of a team prop.

matchupSpecial (string)

This field represents the matchup that the bet concerns if it not a matchup specifically sanctioned by the governing body. For instance, bets on Tiger Woods vs. Phil Mickelson when the event is "The Masters".

metricSpecial (string)

This field represents the relevant metric if the bet concerns a stat other than the primary result metric. For instance, this field would be Field Goals if this was a prop on the total field goals in a game.

future (boolean)

This field will be true if the bet represents a future bet. Future bets are defined as props placed on an event without a defined, sanctioned matchup. For instance, a bet on the SuperBowl winner is a future, until the matchup is defined. At that point it becomes a straight bet, or non-future prop. All bets on the winner of a tournament, or other field based contest are considered futures.

RefreshResponse

Endpoints

POST /v1/bettors/<bettorID>/refresh
POST /v1/bettors/<internalID>/refresh
POST /v1/bettorAccounts/<bettorAccountID>/refresh

GET https://api.sharpsports.io/v1/refreshResponses
GET https://api.sharpsports.io/v1/bettors/<bettorID>/refreshResponses
GET https://api.sharpsports.io/v1/bettorAccounts/<bettorAccountID>/refreshResponses
GET https://api.sharpsports.io/v1/refreshResponses/<refreshResponseID>

A refresh is the process by which SharpSports updates the data for a bettor and/or bettorAccount. A refresh can be initiated in three ways:

Since refreshes are an asynchronous process (5-30 seconds) and can occur at different times for different bettorAccounts, we create a RefreshResponse object to close the loop for every refresh request and notify you with a webhook event refreshresponse.created.

There are two endpoints for initiating a manual refresh (bettor level & bettorAccount level). Refreshes for a bettorAccount are rate-limited 1 refresh / bettorAccount / minute. In the event a refresh takes longer than a minute overlapping refreshes will also be rate limited.

Refresh Endpoint (Bettor Level)

Request


curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_Gz4vUZFIQd+oO0lhMQPdCw/refresh

Response

{
  "betRefreshRequested":"2020-07-07T22:53:43.404962Z",
  "refresh":
    [
      "BACT_25ko1xXuSmaX393YqBuM4w",
      "BACT_rJo4qSt2QOacX2ED9O4dDA"
    ],
  "noAccess":[],
  "unverified":[],
  "isUnverifiable":[],
  "bookInactive":[],
  "bookRegionInactive":[],
  "rateLimited":[],
  "otpRequired":[],
  "requestId":"11e7736d01294ac39f7376c937171445",
  "cid": null
}

This endpoint refreshes bet slips for each bettorAccount associated with the bettor. A RefreshResponse for each bettorAccount will be created and sent asynchronously via webhook.

The immediate response to the request includes a timestamp, a requestId and status of the refreshes for each bettorAccount:

NOTE: All the information provided in the immediate response to a refresh request is also provided in the corresponding refreshResponse object/webhook as well.

 

POST https://api.sharpsports.io/bettors/<bettorID>/refresh

 

Parameter Default Description Required Type
bettorID null the SharpSports ID of the bettor you want to refresh yes string

 

POST https://api.sharpsports.io/bettors/<internalID>/refresh

 

Parameter Default Description Required Type
internalID null your internal ID of the bettor you want to refresh yes string

Refresh Endpoint (BettorAccount level)

Request


curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_RHcNmovNT1+pX5RZjrjwbQ/refresh

Response

{
  "betRefreshRequested":"2020-07-07T22:53:43.404962Z",
  "refresh":["BACT_RHcNmovNT1+pX5RZjrjwbQ"],
  "noAccess":[],
  "unverified":[],
  "isUnverifiable":[],
  "bookInactive":[],
  "bookRegionInactive":[],
  "rateLimited":[],
  "otpRequired":[],
  "requestId":"11e7736d01294ac39f7376c937171445",
  "cid": null
}

This endpoint refreshes betSlips for a specific bettorAccount. The timestamp and identifier for the request are returned immediately, and a single refreshResponse is returned asynchronously via webhook.

 

POST https://api.sharpsports.io/bettorAccounts/<bettorAccountID>/refresh

POST https://api.sharpsports.io/bettorAccounts/<bettorAccountID>/refresh?reverify=true

 

Parameter Default Description Required Type
bettorAccountID null the ID of the bettorAccount you want to refresh bets for. yes string
reverify false setting to true allows you to attempt a refresh on a currently unverified account no boolean

 

The RefreshResponse object

Example RefreshResponse Object

{
  "id":"RRES_A3oU0aruRmmijUqllZbnfQ",
  "bettorAccount":
    {
      "id":"BACT_RHcNmovNT1+pX5RZjrjwbQ",
      "bettor":"BTTR_9pp7EAlYTRmwJn5+QjYAA",
      "book":
        {
          "id":"BOOK_E4tSsP31QrWSd2nSiLmGpg",
          "name":"William Hill",
          "abbr":"wh"
        }
    },
  "timeCreated":"2020-07-09T17:58:14.086593Z",
  "status":200,
  "requestId":"11e7736d01294ac39f7376c937171445",
  "detail":null,
  "type": "manual",
  "betSlips": [
      {
          "id": "SLIP_CPNUi3RSWENfeyJN8M8A",
          "bettor": "BTTR_J7ekiA9uTPaqkyspW7JVw",
          "book": {
              "id": "BOOK_IPBQaQQTCRxplZx7SYOA",
              "name": "William Hill",
              "abbr": "wh"
          },
          "bettorAccount": "BACT_8TxQsO8RcW8U2Q8Zkqg",
          "bookRef": "23c12ad2-f2a6-3df9-9e14-a5ac3273857e",
          "timePlaced": "2020-12-26T21:20:31Z",
          "type": "single",
          "oddsAmerican": -140,
          "atRisk": 200,
          "toWin": 143,
          "netProfit": -200,
          "status": "completed",
          "outcome": "loss",
          "incomplete":false,
          "dateClosed": "2020-12-26",
          "bets": [
              {
                  "id": "BET_fU4asS1OSxSOTlcRfVKVCw",
                  "type": "straight",
                  "event": {
                      "id": "EVNT_AgTJ1tgTkuFFBy9tOS6Q",
                      "sportsdataioId": null,
                      "sportradarId": null,
                      "oddsjamId": null,
                      "league": "NBA",
                      "name": "Atlanta Hawks @ Memphis Grizzlies",
                      "nameSpecial": null,
                      "startTime": "2020-12-26T22:00:00Z",
                      "startDate": "2020-12-26"
                  },
                  "proposition": "moneyline",ww
                  "propDetails": null,
                  "segment": null,
                  "position": "Memphis Grizzlies",
                  "line": null,
                  "oddsAmerican": -140,
                  "status": "completed",
                  "outcome": "loss",
                  "live": false,
                  "incomplete": false,
                  "bookDescription": "Atlanta Hawks at Memphis Grizzlies - Money Line - Memphis Grizzlies"
              }
          ]
      },
      {
          "id": "SLIP_pUIbpAxfR9qGaRZNBOeakQ",
          "bettor": "BTTR_J7ekiA9uTPaqkyspW7JVw",
          "book": {
              "id": "BOOK_IPBQaQQTCRxplZx7SYOA",
              "name": "William Hill",
              "abbr": "wh"
          },
          "bettorAccount": "BACT_8TxQsO8RcW8U2Q8Zkqg",
          "bookRef": "636e16e8-074b-3b67-b558-79dbc9ca06e0",
          "timePlaced": "2020-12-26T21:21:26Z",
          "type": "single",
          "oddsAmerican": -110,
          "atRisk": 200,
          "toWin": 182,
          "netProfit": 182,
          "status": "completed",
          "outcome": "win",
          "incomplete":false,
          "dateClosed": "2020-12-27",
          "bets": [
              {
                  "id": "BET_1Hy3dOIXQDiV5lQYrlK7aA",
                  "type": "straight",
                  "event": {
                      "id": "EVNT_IbFywpO4QRKvx4bbXiJELg",
                      "sportsdataioId": null,
                      "sportradarId": null,
                      "oddsjamId": null,
                      "league": "NCAAMB",
                      "name": "Robert Morris Colonials @ Purdue Fort Wayne Mastodons",
                      "nameSpecial": null,
                      "startTime": "2020-12-27T00:00:00Z",
                      "startDate": "2020-12-27"
                  },
                  "proposition": "total",
                  "segment": null,
                  "position": "Over",
                  "propDetails": null,
                  "line": 139.0,
                  "oddsAmerican": -110,
                  "status": "completed",
                  "outcome": "win",
                  "live": false,
                  "incomplete": false,
                  "bookDescription": "Robert Morris Colonials at Purdue Fort Wayne Mastodons - Total Points - Over"
              }
          ]
      }
  ]
}

id (string)

A unique identifier representing the refreshResponseID. Each refreshResponseID will start with the unique character set 'RRES_'.

bettorAccount (hash)

A object representing the bettorAccount that was refreshed. A bettorAccount that has been refreshed must be verified and accessible, so only core information about the bettorAccount (bettor and book) are included in the serialization.

timeCreated (datetime)

A timestamp for the creation of the refreshResponse object.

status (integer)

This status code indicates the result of the refresh request. The possible codes are:

1) 200: refresh successful

2) 202: refresh successful

3) 500: refresh unsuccessful - unhandled error

4) 401: refresh unsuccessful - a handled response from the sportsbook has caused the account to become unverified, or refreshes on this account are paused

5) 403: refresh not attempted - access for this bettorAccount has been revoked

6) 406: refresh unsuccessful - bettor entered an incorrect (or null) One-Time-Password

7) 424: refresh not attempted - book or bookRegion is currently down for mantainence

8) 429: refresh not attempted - rate limiting or refresh in progress

requestId (string)

The id of the refresh request that initiated this refreshResponse.

detail (string)

An error message associated with the status code.

type (string)

Indicates how the refresh was initiated. One of the following:

betSlips (list)

A list of json formatted betSlip objects updated or created by this refreshResponse. This attribute represents the state of the betSlips at the time of this RefreshResponse event. To get up to date bet slips you must query the betSlip object directly.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Getting a RefreshResponse Details

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/refreshResponses/RRES_A3oU0aruRmmijUqllZbnfQ

With a specific refreshResponseID you can retrieve a refreshResponse object.

 

GET https://api.sharpsports.io/v1/refreshResponses/<refreshResponseID>

 

Parameter Default Description Required Type
refreshResponseID null the ID of the refreshResponse you are requesting yes string

Getting a List of RefreshResponses

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/refreshResponses

With this endpoint you can get a history of all refreshResponses associated with your account. You can also filter using the requestId as a query parameter. This allows you to search for all the refreshResponses that were initiated by a single refresh request.

 

GET https://api.sharpsports.io/v1/refreshResponses

GET https://api.sharpsports.io/v1/bettors/<bettorID>/refreshResponses

GET https://api.sharpsports.io/v1/bettors/<internalID>/refreshResponses

GET https://api.sharpsports.io/v1/bettorAccounts/<bettorAccountID>/refreshResponses

Parameter Default Description Required Type
bettorID null the SharpSports ID of the bettor associated with the RefreshResponse no string
internalID null the internalID of the bettor associated with the RefreshResponse no string
bettorAccountID null the SharpSports ID of the bettorAccount associated with the RefreshResponse no string

Query Parameters

 

GET https://api.sharpsports.io/v1/refreshResponses?requestId=11e7736d01294ac39f7376c937171445&status=500

 

Query Parameter Default Description Required Type
requestId null The identifier of the request that initiated the refresh no string
status null The status code of a refreshResponse no string
limit null The max number of RefreshResponse objects to be returned, ordered by timeCreated no string
pageSize null see Pagination no int
pageNum null see Pagination no int

Event

The Event Object

Example Event Object

{
  "id":"EVNT_G6JvTtYoTriXos41COV2Qw",
  "sportsdataioId":22558,
  "sportradarId":"b87a1595-d3c8-48ea-8a53-0aab6378a64a",
  "oddsjamId": "28014-42288-2020-07-07",
  "league":"Premier League",
  "sport":"Soccer",
  "name":"Chelsea FC @ Crystal Palace FC",
  "nameSpecial":null,
  "startTime":"2020-07-07T17:00:00Z"
}

id (string)

A unique identifier representing the event. Each event id will start with the unique character set 'EVNT_'.

sportsdataioID (string)

A unique identifier coresponding to the event in the sportsdata.io database.

oddsjamID (string)

A unique identifier coresponding to the event in the oddsjam database.

sportradarID (string)

A unique identifier coresponding to the event in the sportradar database. This will be null unless you provide your API keys for this third party provider.

league (string)

A representation of the league where the event is taking place. In the case of non-sporting events this will be the associated governing body or null.

sport (string)

A string representation of the sports associated with the event.

name (string)

The name will represent the description of the event. For head to head matchups, this will be 'away' @ 'home' or 'player 1' vs 'player 2'. '@' represents a game with a home advantage, and vs represents a neutral location match. For tournaments and other events that have a competitive field, 'name' will represent the Proper name of the event i.e. The Masters.

The team names that we use for MLB, NBA, NHL, NFL, NCAAF, NCAAMB and Soccer are standardized from Sports Reference.

nameSpecial (string)

If the event is a head to head matchup, but is also known by another name then nameSpecial will contain that description. For instance, once the SuperBowl contestants are known the 'name' would be 'team 1' vs 'team 2' but nameSpecial would be 'SuperBowl 52'. In the case of futures (when a bet is made without a head to head mathcup) both the 'name' and 'nameSpecial' field will represent the Proper name of the event. For instance, if a bettor wagers that the Packers will win the SuperBowl before the matchup is known, then the 'name' and 'nameSpecial' fields will be 'SuperBowl 52'.

startTime (datetime)

The scheduled start time for the event.

startDate (date)

The scheduled start date for the event.

MarketSelection

Endpoints

GET /v1/marketSelections
GET /v1/marketSelections/<marketSelectionID>

A MarketSelection is an object representing a wager/selection for a specific betting market.

The MarketSelection object

Example MarketSelection Object

{
  "id": "MRKT_25c6022201e8433e8e38eb8f20d17ba1",
  "event": {
    "id": "EVNT_b744ef87ea6c4e9db09661d1aac721ed",
    "league": "NFL",
    "sport": "Football",
    "name": "Baltimore Ravens @ Miami Dolphins",
    "nameSpecial": null,
    "startTime": "2021-11-12T01:20:00Z",
    "startDate": "2021-11-12"
  },
  "type": "prop",
  "proposition": "total",
  "segment": null,
  "position": "Under",
  "propDetails": {
    "future": false,
    "player": "Lamar Jackson",
    "team": null,
    "metricSpecial": "Passing Yards"
  },
  "sportsdataio": {
    "marketId": "145081",
    "eventId": "17818"
  },
  "sportradar": {
    "eventId": "a75c0978-2356-4a39-8180-6a93c2d43d7b",
    "marketId": "sr:market:225"
  },
  "betPlaceAvailability": {
    "dk": false,
    "wb": false,
    "bs": false,
    "b3": false,
    "ca": true,
    "fd": false,
    "bo": false,
    "mg": true,
    "fb": false,
    "pb": false,
    "ud": false,
    "pp": false
  }
}

id (string)

A unique identifier representing the MarketSelectionID. Each MarketSelectionID will start with the unique character set 'MRKT_'.

event (hash)

Represents the SharpSports event object associated with this MarketSelection.

type (string)

Represent the type of market associated with this MarketSelection - either straight or prop

proposition (string)

In the case of a straight bet, this will always be one of spread, moneyline, total or 3-way. In the case of a prop bet, this can be one of those four options, or a description of unique aspect like gatorade color poured on winning head coach.

segment (string)

This represents the specific half, quarter, or other specific segment of the event that the MarketSelection is based on.

position (string)

The positions taken in this MarketSelection. In the case of a total, the position would be Over or Under, while in the case of a spread the position would be a standardized team name.

propDetails (hash)

An object representing the propDetails: a list of structured information that further defines the prop. This will be null unless type = prop.

sportsdataio.marketId (string)

The sportsdata.io market ID associated with this MarketSelection

sportsdataio.eventId (string)

The sportsdata.io event ID associated with this MarketSelection

sportradar.eventId (string)

The sportradar event ID associated with this MarketSelection

sportradar.marketId (string)

The sportradar market ID associated with this MarketSelection

betPlaceAvailability (json)

A list of book abbreviation boolean pairs indicating if SharpSports BetPlace links are available for this MarketSelection

Get MarketSelection Detail

curl -X GET -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/marketSelections/<marketSelectionID>

GET https://api.sharpsports.io/v1/marketSelections/<marketSelectionID>

Parameter Default Description Required Type
marketSelectionID null the SharpSports ID of marketSelection no string

Get a List of MarketSelections

curl -X GET -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/marketSelections

Note: The marketSelection list endpoint returns a list of only marketSelections with an available betPlace url

GET https://api.sharpsports.io/v1/marketSelections

Query Parameters

GET https://api.sharpsports.io/v1/marketSelections?sdioMarketId=145081&position=Under

Note: For standardized query param values make sure you use a proper URI encoding

Query Parameter Default Description Required Type
sdioMarketId null the Sportsdata.io Market ID associated with this MarketSelection no string
sdioEventId null the Sportsdata.io Event ID associated with this MarketSelection no string
sportradarEventId null the Sportradar Event ID associated with this MarketSelection no string
sportradarMarketId null the Sportradar Market ID associated with this MarketSelection no string
eventId null the SharpSports Event ID associated with this MarketSelection no string
position null the position of the marketSelection no string
propositon null the proposition of the marketSelection no string
segment null the game segment of the marketSelection no string
player null the player associated with a MarketSelection (only for props) no string
team null the team associated with a MarketSelection (only for props) no string
metric null the metric associated with a MarketSelection (only for props) no string
pageSize null see Pagination no int
pageNum null see Pagination no int
limit 500 The max number of MarketSelection objects to be returned, ordered by timeCreated no string

Pagination

Example Request

curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettors?pageSize=2&pageNum=1
Parameter Default Description Required Type
bettorID null the SharpSports ID of the bettor assoicated with the requested betSlips no string

Example Response

{
  "objects":
    [{
      "id":"BTTR_623bdb8a0908408ba97b185138b12345",
      "internalId":"2f01d7946b9840ada8102633460bc5c0",
      "betRefreshRequested":null,
      "timeCreated":"2021-09-13T21:21:55.109355Z"
    },
    {
      "id":"BTTR_0afca19e264549d0882b115934112345",
      "internalId":"9dd5449d42d24ac3a11208fa5026256b",
      "betRefreshRequested":null,
      "timeCreated":"2021-09-13T20:54:52.970591Z"
    }],
  "totalPages":150
}

API endpoints that allow you to access large lists of data come with optional pagination query parameters. In order to use pagination you must include both pageSize and pageNum query params, both of which are integers. When these two query parameters are entered together the format of the response changes. You will recieve both a list of objects (objects) and the total number of pages that you can access (totalPages). The pageNum query param must be a value between 1 and totalPages.

The endpoints that come with pagination, as well as their default ordering, are listed below

Standardized Values

Endpoints

GET /v1/standardized/leagues
GET /v1/standardized/teams
GET /v1/standardized/players
GET /v1/standardized/metrics
GET /v1/standardized/segments

The Standardized endpoint returns an object representing a list of standardized values for a specific field.

Response Objects

leagues

A list of currently standardized leagues to be used as query params (where applicable) on other /v1/standardized/ endpoints.

sports

A list of currently standardized sports.

teams

A list of standardized team names for the standardized league or sport specified as a query parameter in the request.

players

A dictionary containing standardized player names for a specific standardized league or sport (inputted as a query parameter). This dictionary is formatted with standardized team names as keys, with a list of players on that teams as values.

metrics

A list of currently standardized prop bet metrics.

segments

A list of currently standardized segments.

Query Parameters

GET https://api.sharpsports.io/v1/standardized/teams?league=NBA

Query Parameter Default Description Required Type
league null the standardized league name to retrieve data for no string
sport null the standardized sport name to retrieve data for no string

NOTE: Both the standardized/teams and standardized/players endpoints require one of the above query parameters in order to function.

Get a List of Teams

curl -X GET -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/standardized/teams?league=NBA

GET https://api.sharpsports.io/v1/standardized/teams?league=NBA

Webhooks

SharpSports implements webhooks to notify you of three different events: bettor creation, bettorAccount verification, and refreshes of bets via a refreshResponse object. These hooks allow you to close the data loop initiated by our Book Link UI or by refreshing bets.

You can create and manage your webhooks in the dashboard

Events

All webhook events are categorized by a string "{object}.{action}". The payload of the webhook will contain the "event" and "data" containing the details of the object described in the event. For example in the bettorAccount.verified event payload, the data consists of attributes of the relevant bettorAccount object. The webhook also includes a "sender" field which is simply your application name in our database.

Bettor Creation

Payload

{
    "event": "bettor.created",
    "sender": "SampleApp",
    "data": {
        "id": "BTTR_5nrgeCfwQjyUDHoK72kQ",
        "internalId": "12345"
    }
}

The first time a bettor using your application attempts to verify a sportsbook account a new bettor object is created in our database. In order to use our API it is essential that you store the bettorID next to your internalId that you use to uniquely identify this bettor in your database. In order to facilitate this process we fire a webhook event

bettor.created

with a payload containing both the SharpSports bettorID and your internalId. In the rare case that you miss this initial webhook and receive a different webhook event referencing a bettorID that you do not have stored, you can always use the GET /v1/bettors/<bettorID> to view the corresponding internalId.

BettorAccount Verified

Payload

{
    "event": "bettoraccount.verified",
    "sender": "SampleApp",
    "data": {
        "id": "BACT_IqNr2pZR1Wrs6r1XOKMVQ",
        "bettor": "BTTR_cahAECmtTe2l+Or9Ust5Ag",
        "book": "wh",
        "region":"New Jersey"
    }
}

Whenever a new bettorAccount is verified in the BookLink UI we fire a webhook event

bettoraccount.verified

with a payload containing basic info about the bettorAccount. You can use this information to show bettors the status of their currently linked accounts as well as setting up access controls for each account.

 

 

BettorAccount Unverified

Payload

{
    "event": "bettoraccount.unverified",
    "sender": "SampleApp",
    "data": {
        "id": "BACT_IqNr2pZR1Wrs6r1XOKMVQ",
        "bettor": "BTTR_cahAECmtTe2l+Or9Ust5Ag",
        "book": "wh",
        "region":"New Jersey"
    }
}

Whenever a new bettorAccount is unverified (verified=False) for any reason we fire a webhook event

bettoraccount.unverified

with a payload containing basic info about the bettorAccount. You can use this information to show bettors the status of their currently linked accounts.

A bettor account can become unverified for a variety of reasons including password change, sportsbook site maintenance, or sportsbook identity verification requests. We won't attempt refreshes on any 'unverified' accounts. The Bettor must either relink the account through the booklink UI, or via the refresh?reverify=true endpoint.

We'll periodically attempt to reverify accounts that have become unverified but you should flag to a user that their account is unverified so they can reverify using the booklink button or via a refresh?reverify=true post. You can rely on the 'verified' attribute on a bettor account to determine their current state.

 

 

BettorAccount Inaccessible

Payload

{
    "event": "bettoraccount.inaccessible",
    "sender": "SampleApp",
    "data": {
        "id": "BACT_IqNr2pZR1Wrs6r1XOKMVQ",
        "bettor": "BTTR_cahAECmtTe2l+Or9Ust5Ag",
        "book": "wh",
        "region":"New Jersey"
    }
}

Whenever a new bettorAccount becomes inaccessible (access=False) for any reason we fire a webhook event.

bettoraccount.inaccessible

with a payload containing basic info about the bettorAccount. This means a bettor has revoked access to this account and you can no longer refresh or access information about this account. Note that there is no webhook for when access is turned on (access=True) since this is redundant with the bettoraccount.verified webhook. Whenever an account is verified you can assume that access has been turned on.

RefreshResponse Creation

Payload

{
    "event": "refreshresponse.created",
    "sender": "SampleApp",
    "data": {
        "id": "RRES_95ac53f7a40e4911b96390d64d637e7b",
        "timeCreated": "2021-05-17T05:04:30.065796Z",
        "bettor": "BTTR_a0ebf8ba53304fde8b9b3d7f9605c841",
        "bettorAccount": "BACT_a679867dc9624bb4b75f6b9dc1e4a8c6",
        "status": 200,
        "detail": null,
        "type": "manual",
        "requestId": "93947bc9c8374fb1a1177c2ea2654d95",
        "betSlips" : []
    }
}

Whenever the bets for a specific bettorAccount are refreshed we fire a webhook event

refreshresponse.created

with a payload containing the details of a refreshResponse object. This webhook lets you track the asynchronous responses to your refresh requests, and get new bets filtered by refreshReponse.

Subscriptions

Request


curl -X POST -H  "Authorization: Token <private_API_key>" -H "Content-Type: application/json" -d '{"event": "bettor.created", "url":"http://sampleapp.com/webhooks/bettorcreated"}' https://api.sharpsports.io/hooks/

Response

{
    "event":"bettor.created",
    "url":"http://sampleapp.com/webhooks/bettorcreated",
    "content_type":"application/json",
    "user":2,
    "id":"79640a98-7cc2-48b4-8427-b98bad7f6013",
    "created_at":"2020-07-08T19:31:27.750397Z",
    "updated_at":"2020-07-08T19:31:27.750422Z",
    "subscription":"https://api.sharpsports.io/hooks/79640a98-7cc2-48b4-8427-b98bad7f6013/",
    "hmac_secret":"}XsOUY&nr#),>~Jqwx|q[9Q$$4Idi:e2dq~Q(eM|_.Pv|Fz)L6%dyI;q$!j0+8",
    "hmac_digest":"sha256"
}

In order to receive information via webhook you can subscribe using the endpoint below, or subscribe in the dashboard:

POST https://api.sharpsports.io/hooks/

An example subscription to the bettor.created event is shown in code. We recommend that you subscribe to each event individually at a unique url that the webhook data is posted to. Upon reciept of your request you will get a response describing the details of your subscription. Please store this information in your database. SharpSports uses Thorn for our webhook infrastructure and more info about subscription request and responses can be found here.

Webhook Receivers

Webhook Receiver Example (php)

$app->post('/bettorcreated', function(Request $request) use($app) {

  $hook = json_decode($request->getContent(), true);
  $sender = $hook['sender'];
  $data = $hook['data'];
  $id = $data['id'];
  $internalId = $data['internalId'];

   ## store the bettorID associated with the internalID
  $add_query = $app['pdo']->prepare("INSERT INTO bettor (id,internal_id) VALUES ('$id','$internalId');");
  $add_query->execute();

  return new Response('Webhook recieved!', 200);

});

Once you have subscribed to the above events you must set up a webhook receiver for each subscription to deal with incoming webhook messages. Please store the payload data and respond with status code 200 before taking other action so that we do not try to send multiple webhooks with the same data. An example webhook receiver for the bettor.created endpoint written in php is shown in code.

HMAC Verification (Optional)

SharpSports provides an HMAC secret key in the response to your webhook subscription that can be used to verify incoming webhook event messages. Example HMAC verification for Django, Ruby and PHP can be found here.

Sandbox and Test Users

To test the API before pushing to production, we provide several sets of test credentials. Your sandbox API environment will come with a test bettor/bettorAccount with a extensive bet history containing a variety of representative bet types.

You can create new bettors and bettorAccounts using the book link button (test credentials below). Every time a refresh is performed on a bettorAccount, a few random live bets on real events will be generated. These bets are graded after the events are completed.

Test Users

Successful Verification (no delay)

Username: gooduser

Password: Test1

Successful Verification (delayed)

Username: realuser

Password: Test2

Failed Verification

Username: errorloginuser

Password: Test3

Failed Bet Refresh

Username: errorbetuser Password: Test4

User Has Changed Password

Username: changepassworduser

Password: Test5

User Has 2FA Enabled

Username: 2FAuser

Password: Test6

Invalid Password

Any other username and password combo will result in the following:

Alternative Integration Paths

Example BookLink PopUp (JavaScript)

async function postContext(data = {}) {

  const response = await fetch('https://api.sharpsports.io/v1/context', {
    method: 'POST',
    headers: {
      'Authorization': `Token ${token}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(data)
  });
  return response.json();
}

function popupWindow(url, title, win, w, h) {
    const y = win.top.outerHeight / 2 + win.top.screenY - ( h / 2);
    const x = win.top.outerWidth / 2 + win.top.screenX - ( w / 2);
    return win.open(url, title, `toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=no, resizable=no, copyhistory=no, width=${w}, height=${h}, top=${y}, left=${x}`);
}

function onClickButton() {
  postContext({internalId:internal_id})
    .then(data => popupWindow(`https://ui.sharpsports.io/link/${data.cid}`,'SharpSports',window,500,600))
}

Create your own booklink button and run the POST context call on click. This will return a cid, which you can substitute into the link url (below) to direct users to the linking experience.

ui.sharpsports.io/link/<cid>

The code snippet is for a desktop web integration. A similar experience can be created for a mobile application by using a webview rather than a popup.

If creating a custom mobile webview you will need a way to dismiss the webview when the linking experience is completed. One option for this is to hook onto the following URL:

ui.sharpsports.io/done

Create Your Own Button for Each Book

GET BookRegions

curl -X GET -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bookRegions

POST Context

curl -X POST -H "Authorization: Token <public_API_key>" -d "internalId=<your_internal_id>" https://api.sharpsports.io/v1/context

If you'd prefer to direct users straight to the booklogin page, you can use a modified version of the POST context call.

First, get a list of BookRegions.

GET v1/bookRegions

You can see which bookRegions are currenlty active by looking at the status field, or you can filter using the status and book query parameters.

Then, create a button for each active BookRegion by running the POST context call on click.

POST -d "internalId=<your_internal_id>" https://api.sharpsports.io/v1/context

This will return a cid, which you can append to the end of the link url (below) to direct users to the linking experience.

ui.sharpsports.io/link/<cid>/region/<bookRegionID>/login

Full Page Redirect

POST Context

curl -X POST -H "Authorization: Token <public_API_key>" -d "internalId=<your_internal_id>&redirectUrl=<https://www.mysite.com/desired_page>" https://api.sharpsports.io/v1/context

If you'd like to make the booklink button a full page redirect, you can pass a redirect URL to the POST Context call, which will direct the user back to the page of your choice when they are done with the linking process.

Run the post context call with the appropriate data on click of the booklink button you put on your site.

POST -d "internalId=<your_internal_id>&redirectUrl=<https://www.mysite.com/desired_page>" https://api.sharpsports.io/v1/context

Custom Bettor Account Management Functionality

Once your users link a sportsbook account, they'll need the ability to manually refresh, pause, remove and see the status of accounts they've linked. We provide this as part of the UI, but if you'd like to include it in your app, you can use the API to build your own experience.

Refreshing Accounts

Use the POST refresh button to allow users the ability to refresh their accounts on command. Each refresh will take 10-60 seconds.

The bettorAccount refresh can be used for individual sportsbook accounts.

BettorAccount Refresh Request

curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_RHcNmovNT1pX5RZjrjwbQ/refresh

POST v1/bettorAccounts/<bettorAccountID>/refresh

The bettor refresh can be used for refreshing all accounts associated with a bettor.

Bettor Refresh Request

curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_Gz4vUZFIQdoO0lhMQPdCw/refresh

POST v1/bettors/<bettorID>/refresh POST v1/bettors/<internalID>/refresh

See documentation related to the Refresh Endpoint for more details See documentation related to the 2FA Handling for details on refreshing accounts with Two-Factor-Authentication

Pausing Accounts

Sometimes users want to pause syncing for a particular account. You can give users the ability to pause an account with the pause call.

Pause BettorAccount Request

curl -X PUT -d "paused=true" -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_25ko1xXuSmaX393YqBuM4w/paused

PUT -d "paused=<true/false>" v1/bettorAccounts/<bettorAccountID>/paused

Removing Accounts

You can remove an account by changing access to false on a specific bettorAccount. When bettorAccount.access=false, you will no longer be able to refresh the account or get any associated information. When a user links the account again, the account will change to access = true and you will have access to refreshes and account data again.

Remove BettorAccount Request

curl -X PUT -d "access=false" -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_25ko1xXuSmaX393YqBuM4w/access

PUT -d "access=<true/false>" v1/bettorAccounts/<bettorAccountID>/access

Accout Verified State

A bettorAccount can be in one of three verified states: verified, unverified, unverifiable. Everytime a refresh is run, the bettorAccount verified state might update.

These states are represented by the following fields:

bettorAccount.verified = true/false

bettorAccount.isUnverifiable = true/false

GET BettorAccount Request

curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_25ko1xXuSmaX393YqBuM4w

You can use GET v1/bettorAccounts/<bettorAccountId> to view these values.

Subscribe to the bettorAccount.verified and bettorAccount.unverified webhooks to get notified when a change on bettorAccount.verified. You can use this information, along with bettorAccount.latestRefreshResponse.detail to prompt the owner of the account to fix the issue.

Reverifying Accounts

An individual bettorAccount can be verified, unverified or unverifiable. For unverified and unverifiable accounts, you'll need to provide the user a path to reverifying their account.

Reverify Request

curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_RHcNmovNT1pX5RZjrjwbQ/refresh?reverify=true

Unverified:

bettorAccount.verified = false

An account becomes unverified when a refresh is unsuccessful. This could be the result of a change in password, an error on the sportsbook site, or a prompt from the sportsbook to accept new terms of services or other actions. We will attempt to reverify unverified accounts periodically, but the user can trigger a reverification themselves with the reverify endpoint POST v1/bettorAccounts/<bettorAccountId>/refresh?reverify=true. These requests are treated the same as normal refresh requests, except they will attempt to connect to the sportsbook even if the account is unverified (but not unverifiable).

Unverifiable:

bettorAccount.isUnverifiable = true

Multiple reverification attempts will result in the bettorAccount becoming unverifiable. Unverifiable accounts can only be reverified by the user relinking their account in the UI. For these users, you'll need to direct the users to the UI using one of the account linking paths.

Store the SharpSports BettorID

Each bettor has a unique internalID (provided by you) and a bettorID (provided by SharpSports). You can make most calls using the internalID, but if you'd like to rely on the SharpSports bettorID, you can subscribe to the bettor.created webhook to be notified when a new bettor is created and store the bettorID.

Refresh Cadence

If you'd like to have bettorAccounts refreshed more often, you can utilize the refresh cadence setting in the dashboard. We will automatically run a refresh on every bettorAccount linked to your product every X minutes according to your setting.

Manual Refresh Button

Use the POST refresh button to allow users the ability to refresh their accounts on command. Each refresh will take 10-60 seconds.

BettorAccount Refresh Request

curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettorAccounts/BACT_RHcNmovNT1pX5RZjrjwbQ/refresh

The bettorAccount refresh can be used for individual sportsbook accounts.

POST v1/bettorAccounts/<bettorAccountID>/refresh"

Bettor Refresh Request

curl -X POST -H "Authorization: Token <public_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_Gz4vUZFIQdoO0lhMQPdCw/refresh

The bettor refresh can be used for refreshing all accounts associated with a bettor.

POST v1/bettors/<bettorID>/refresh POST v1/bettorAccounts/<internalID>/refresh

See documentation related to the Refresh Endpoint for more details

Poll for Refreshes

GET BettorAccounts Request

curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_Gz4vUZFIQd+oO0lhMQPdCw/bettorAccounts

If you'd prefer to avoid using webhooks for notifications when a refresh is complete, you can instead poll GET v1/bettors/<bettorID>/bettorAccounts endpoint.

Then look at the bettorAccount.refreshInProgress attribute to see if the refresh is still ongoing.

GET BetSlips Request

curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bettors/BTTR_vsiAC+D7Tqu8D4gMGjZEbA/betSlips

Once refreshInProgress goes from true to false, use the GET v1/betSlips endpoint to fetch the up to date list of bets.

Mobile Only Book Integrations

There are a few book integrations that are only accessible via mobile. These mobile only integrations allow us to offer support for more books, and the refreshes are performed much faster; however we cannot perform cadence refreshes for these books.

Important Note: For mobile only books, refresh and context calls can only be made through the mobile package method calls in the client. These methods work for all books, while the context and refresh API calls will only work for the other books.

The Sharpsports Mobile Packages:

1) A typescript NPM package for React-Native applications

2) A Swift (SPM) package for iOS native applications

3) A Kotlin package for Android native applications

These packages are private, so please reach out to auth@sharpsports.io for access.

Endpoints

POST /v1/books/<BookID>/affiliateLink
GET /v1/books/<BookID>/affiliateLink
DELETE /v1/books/<BookID>/affiliateLink

POST /v1/bookRegions/<BookRegionID>/affiliateLink
GET /v1/bookRegions/<BookRegionID>/affiliateLink
DELETE /v1/bookRegions/<BookRegionID>/affiliateLink

You can update the affiliate links associated with a Book or BookRegion using the affiliateLink endpoints. If you assign an affiliate link to a Book then it will cascade to any BookRegion associated with this Book that does not have a specific affiliate link already assigned.

Request


curl -X POST -H "Authorization: Token <private_API_key>" -d "affiliateLink=https://www.mylink.com" https://api.sharpsports.io/v1/books/<BookID>/affiliateLink

curl -X POST -H "Authorization: Token <private_API_key>" -d "affiliateLink=https://www.mylink.com" https://api.sharpsports.io/v1/bookRegions/<BookRegionID>/affiliateLink

 

POST https://api.sharpsports.io/v1/books/<BookID>/affiliateLink

 

Parameter Default Description Required Type
BookID null The BookID of affiliate link you are updating yes string

 

POST https://api.sharpsports.io/v1/bookRegions/<BookRegionID>/affiliateLink

 

Parameter Default Description Required Type
BookRegionID null The BookRegionID of affiliate link you are updating yes string

 

Request


curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/books/<BookID>/affiliateLink

curl -X GET -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bookRegions/<BookRegionID>/affiliateLink

 

GET https://api.sharpsports.io/v1/books/<BookID>/affiliateLink

 

Parameter Default Description Required Type
BookID null The BookID of affiliate link you are requesting yes string

 

GET https://api.sharpsports.io/v1/bookRegions/<BookRegionID>/affiliateLink

 

Parameter Default Description Required Type
BookRegionID null The BookRegionID of affiliate link you are requesting yes string

 

Request


curl -X DELETE -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/books/<BookID>/affiliateLink

curl -X DELETE -H "Authorization: Token <private_API_key>" https://api.sharpsports.io/v1/bookRegions/<BookRegionID>/affiliateLink

 

DELETE https://api.sharpsports.io/v1/books/<BookID>/affiliateLink

 

Parameter Default Description Required Type
BookID null The BookID of affiliate link you are deleting yes string

 

GET https://api.sharpsports.io/v1/bookRegions/<BookRegionID>/affiliateLink

 

Parameter Default Description Required Type
BookRegionID null The BookRegionID of affiliate link you are deleting yes string

 

2FA Handling

OTP Entry Page

Response

{
  "betRefreshRequested":"2020-07-07T22:53:43.404962Z",
  "refresh":
    [
      "BACT_25ko1xXuSmaX393YqBuM4w",
      "BACT_rJo4qSt2QOacX2ED9O4dDA",
      "BACT_RHcNmovNT1+pX5RZjrjwbQ"
    ],
  "noAccess":[],
  "unverified":[],
  "isUnverifiable":[],
  "bookInactive":[],
  "bookRegionInactive":[],
  "rateLimited":[],
  "otpRequired":[
    "BACT_RHcNmovNT1+pX5RZjrjwbQ",
    "BACT_25ko1xXuSmaX393YqBuM4w"
  ],
  "requestId":"11e7736d01294ac39f7376c937171445",
  "cid": "0029c316-3371-4855-a0e5-9b2770ebd8e4"
}

Some bettorAccounts require 2FA on every login, which means you'll need to accept a OTP (one-time-password) for every refresh performed.

You'll know an account requires a OTP if the immediate response to a refresh request includes a bettorAccount in the otpRequired list. The response will also include a cid.

In this case, route your user to https://ui.sharpsports.io/otp/<cid> in a popup or webview where they can enter the necessary code(s) they receive from their sportsbook account.

Once they submit the code(s) you can close the popup/webview by hooking on to /done in the URL.

 

 

 

 

 

 

Full Page Redirect for OTP entry

Request


curl -X POST -H "Authorization: Token <public_API_key>" -d "redirectUrl=<www.mysite.com/desired_page>" https://api.sharpsports.io/v1/bettorAccount/<BACT_ID>/refresh

On a desktop website you can also have the OTP entry page redirect to a webpage of your choice rather than creating and exiting a popup.

To do this, simply pass a redirectUrl as data to any of the /refresh endpoints and the page https://ui.sharpsports.io/otp/<cid> will route to this url after the user submits their 2FA code(s).

You can look at bettorAccount.TFA flag to see if this account will require a OTP on every refresh; however, the redirectUrl data parameter will have no affect if the refresh does not require OTP entry.

Custom OTP Entry

Request


curl -X PUT -H "Authorization: Token <public_API_key>" -H 'Content-Type: application/json' -d '{"otp":{"BACT_RHcNmovNT1+pX5RZjrjwbQ":"123456","BACT_25ko1xXuSmaX393YqBuM4w:"11111"}}' https://api.sharpsports.io/v1/contexts/<cid>

If you would like customize the user experience around entering OTPs rather than routing to https://ui.sharpsports.io/otp/<cid>, you can enter OTPs using the PUT v1/context/<cid> endpoint.

1) (Optional) Check the bettorAccount.TFA boolean to see if this account will require OTP entry on refresh. You may want to confirm with your user that they are ready to enter a code before refreshing the account.

2) Submit all OTPs for a given refresh to PUT /contexts/<cid> using the cid returned by the /refresh endpoint. The OTPs must be formatted as json using the bettorAccountIDs as keys and the OTP codes as values. See the example request which submits the OTPs 123456 and 111111 for the bettorAccounts BACT_RHcNmovNT1+pX5RZjrjwbQ and BACT_25ko1xXuSmaX393YqBuM4w respectively.

3) If you recieve a 406 status code in the RefreshResponse webhook from a refresh, this indicates that there was an incorrect or null OTP code. You must initiate a new refresh by hitting the /refresh endpoint again. You cannot re-submit a new OTP code from a previous refresh using the same cid as before.