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.
1. Integrate the BookLink UI
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.
Recommended Path
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
- Create a custom booklink button via API
- Create your own link button for each sportsbook
- Web Browser Full page Redirect
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
Recommended Path
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
- Subscribe to Webhooks via API.
- Store the SharpSports bettorId
- Custom bettor account management functionality via API
4. Initiating Refreshes
Recommended Path
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.
Recommended Path
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.
7. [BETA] Offering betPlace Links
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>
BetPlace Links for Markets
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
- PrizePicks only stores the last 60 betslips made on an account. The initial sync with this book will contain a maximum of 60 betslips.
BetMGM
- BetMGM only stores 3 months of bet history. The initial sync with this book will contain a maximum of 3 months of history.
Borgata
- Borgata only stores 3 months of bet history. The initial sync with this book will contain a maximum of 3 months of history.
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 |
league
param values:NFL
,NCAAF
,NBA
,NCAAMB
,MLB
,NHL
,UFC
sport
param values:Football
,Baseball
,Basketball
,Hockey
,Soccer
,Tennis
,Golf
,MMA
,Auto
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:
- Automatic refresh request when an account is first linked
- Automated refresh cadence set in the dashboard
- A manual refresh request with the
refresh
endpoints
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:
- The IDs of all bettorAccounts which are successfully scheduled for refresh will be returned in the "refresh" category of the response.
- If a bettorAccount has restricted access its ID will be listed in the "noAccess" category of the response.
- If a bettorAccount is unverified its ID will be listed in the "unverified" category of the response.
- If a bettorAccount is unverifiable its ID will be listed in the "isUnverifiable". This means it cannot be refreshed even with the
?reverify=true
query param - If a book is currently inactive (i.e. down for maintenance) then the associated bettorAccount will be listed in "bookInactive" or "bookRegionInactive" respectively.
- If the refresh request for a specific bettorAccount is rate-limited then it will be listed in "rateLimited"
- If a bettorAccount has Two Factor Authentication (2FA) turned on and requires a One Time Password (OTP) the account will be listed in "otpRequired".
In this case there will also be a
cid
in the response which can be used to enter OTPs. See Details
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
- Successfully pulled new data from the sportsbook account
2) 202
: refresh successful
- Successfully pulled new data from the sportsbook account but due to large data volume the betSlips are not included on the object
3) 500
: refresh unsuccessful - unhandled error
- This type of error occurs on less than 2% of refresh requests
4) 401
: refresh unsuccessful - a handled response from the sportsbook has caused the account to become unverified, or refreshes on this account are paused
- This could be due to a password change for this book, an update in the sportsbook terms of service, or activation of additional security measures on the account (such as 2FA).
5) 403
: refresh not attempted - access for this bettorAccount has been revoked
- See update access endpoint on the bettorAccount object
6) 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
7) 424
: refresh not attempted - book or bookRegion is currently down for mantainence
- Occasionally SharpSports will deactivate a book or a book region for mantainence
8) 429
: refresh not attempted - rate limiting or refresh in progress
- Account refreshes must be made at least 60 seconds apart and cannot overlap
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:
manual
- initiated from the/refresh
endpontverify
- initiated from a SharpSports Book Link UI sessionreverify
- initiated from the/refresh?reverify=true
endpontcadence
- initiated from the SharpSports Dashboard refresh cadencesystem
- initiated by Sharpsports, either to reverify an account or to update fields on existing betsgrade
- initiated by SharpSports. Includes bets automatically graded by SharpSports grading logic
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 |
position
param values:Over
,Under
, Standardized Team Namesproposition
param values:Spread
,Total
,Moneyline
,3-way
segment
param values: Standardized Segments Shorthandplayer
param values: Standardized Player Names (typically<First> <Last>
)team
param values: Standardized Team Namesmetric
param values: Standardized Prop Metrics
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
GET /v1/bettors
- Ordered by
timeCreated
- Ordered by
GET /v1/betSlips
- Ordered by
timePlaced
- Ordered by
GET /v1/bettors/<bettorID>/betSlips
- Ordered by
timePlaced
- Ordered by
GET /v1/bettorAccounts/<bettorAccountID>/betSlips
- Ordered by
timePlaced
- Ordered by
GET /v1/refreshResponses
- Ordered by
timeCreated
- Ordered by
GET /v1/marketSelections
- Ordered by
timeCreated
- Ordered by
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 |
league
param values: can be retrieved via thehttps://api.sharpsports.io/v1/standardized/leagues
endpoint. This parameter is for thestandardized/teams
andstandardized/players
endpoints only and should be used in instances where a standardized league value is available.sport
param values: can be retrieved via thehttps://api.sharpsports.io/v1/standardized/sports
endpoint. This parameter is for thestandardized/teams
andstandardized/players
endpoints only, and should be used in instances where no standardized league values are available for said sport (eg. Soccer).
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.
- When you request a refresh of bets at
bettors/<bettorID>/refresh
you can expect a webhook event for each verified and accessible bettorAccount for this bettor - When you request a refresh of bets at
bettorAccounts/<bettorAccountID>/refresh
, you can expect a single webhook event for this bettorAccount - SharpSports automatically refresh bets for any new bettorAccount and a webhook will be fired in this case as well.
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
- This user completes all actions without errors and without delay
- Has accounts on all sportsbooks and places bets on each sportsbook every day
- You will receive an
bettoraccount.verified
and arefreshresponse.created
webhook on login - If this is the first account you have linked with a give
internalId
, you will receive abettor.created
webhook on login
Successful Verification (delayed)
Username: realuser
Password: Test2
- This user completes all actions without error with artificial delay of 10 seconds on login and 30 seconds on refresh bet history
- Has accounts on all sportsbooks and places bets on each sportsbook every day
- You will receive an
bettoraccount.verified
and arefreshresponse.created
webhook on login - If this is the first account you have linked with a give
internalId
, you will receive abettor.created
webhook on login
Failed Verification
Username: errorloginuser
Password: Test3
- This user results in an error upon account verification. In production this could be caused a sportsbook site being down for maintenence
- If this is a first time attempt at verification for a specific sportsbook we will delete the bettorAccount altogether
- If this login is used on sportsbook with an existing bettorAccount we will maintain the same verified state
- You will receive an
bettoraccount.unverified
webhook when attempting to refresh a user with these credentials
Failed Bet Refresh
Username: errorbetuser Password: Test4
- This user successfully logs in and verifies their account on every sportbook
- When a bet refresh request is made for the verified bettorAccount the corresponding webhook contains a RefreshResponse object with a 500 error status due to a sportsbook's website being down or a SharpSports internal server error
- You will receive an
bettoraccount.unverified
webhook when attempting to refresh a user with these credentials
User Has Changed Password
Username: changepassworduser
Password: Test5
- This user successfully logs in and verifies their account on every sportbook
- When a bet refresh request is made for the verified bettorAccount the corresponding webhook contains a RefreshResponse object with a 401 error status due to a changed password
- You will receive an
bettoraccount.unverified
webhook when attempting to refresh a user with these credentials
User Has 2FA Enabled
Username: 2FAuser
Password: Test6
- Upon login with this user you will receive a UI prompt to enter an OTP
- The correct OTP for this user is
123456
- The correct OTP for this user is
- If you input a bad OTP or no OTP on a refresh the corresponding webhook contains a RefreshResponse object with a
406
error status. - If you input a good OTP (
123456
) you will receive abettoraccount.verified
and arefreshresponse.created
webhook on login - If this is the first account you have linked with a give
internalId
, you will receive abettor.created
webhook on login
Invalid Password
Any other username and password combo will result in the following:
- If this is a first time attempt at verification we will delete the bettorAccount altogether
- If this is a previously verified bettorAccount we will changed verified field to false
Alternative Integration Paths
Custom Booklink Button
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.
AffiliateLinks
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.
Create/Update an Affiliate Link
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 |
Read an Affiliate Link
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 |
Delete an Affiliate Link
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.