Juice ReelJuice Reel

Juice Reel developer platform

Build with verified betting data

Connect a Juice Reel account with OAuth 2.0, then securely read subscriber relationships and the connected user's open or settled bets from your backend.

Authorization URLhttps://www.juicereel.com/oauth2/authorize
API base URLhttps://external-api.juicereel.com
1Create an applicationRegister callbacks and request only the scopes you need.
2Authorize with PKCEValidate state and exchange the short-lived code server-side.
3Call the APISend both the bearer token and X-OAuth-Client-Id header.

OAuth 2.0

Authorize a user

Send the user to Juice Reel to sign in and approve access. This is a browser redirect, not a server-to-server API call.

GEThttps://www.juicereel.com/oauth2/authorize
AuthenticationJuice Reel browser session
Required scopeNone
Keep the PKCE verifier on your backend. Only its S256 challenge is sent to Juice Reel.

Request parameters

FieldTypeDescription
client_idrequiredstringYour approved OAuth client ID.
redirect_urirequiredstringAn exact redirect URI registered on the application.
response_typerequiredstringMust be code.
scoperequiredstringSpace-delimited requested scopes.
staterequiredstringUnpredictable value created and validated by your application.
code_challengerequiredstringBase64url SHA-256 digest of your PKCE verifier.
code_challenge_methodrequiredstringMust be S256.

Response

302 · redirect
FieldTypeDescription
codestringShort-lived, single-use authorization code exchanged by your backend.
statestringThe original state. Reject the callback if it does not exactly match your stored value.

OAuth 2.0

Exchange an authorization code

Exchange the callback code for an access token and rotating refresh token. Perform this request only from your backend.

POST/oauth2/token
AuthenticationHTTP Basic: client ID and client secret
Required scopeNone

Request parameters

FieldTypeDescription
grant_typerequiredstringMust be authorization_code.
coderequiredstringCode received by your redirect URI.
redirect_urirequiredstringMust exactly match the URI used during authorization.
code_verifierrequiredstringOriginal PKCE verifier used to create the challenge.

Response

200 · application/json
FieldTypeDescription
access_tokenstringBearer token used for resource requests. Store server-side.
refresh_tokenstringSingle-use token used to obtain a replacement token pair.
token_typestringBearer.
expires_inintegerAccess-token lifetime in seconds; currently 3600.
scopestringSpace-delimited scopes granted by the user.

OAuth 2.0

Refresh tokens

Use a refresh token once to receive a new access token and a replacement refresh token.

POST/oauth2/token
AuthenticationHTTP Basic: client ID and client secret
Required scopeNone
Reusing a consumed refresh token revokes the token family and associated grant as a replay-protection measure.

Request parameters

FieldTypeDescription
grant_typerequiredstringMust be refresh_token.
refresh_tokenrequiredstringThe current unused refresh token.

Response

200 · application/json
FieldTypeDescription
access_tokenstringNew one-hour bearer token.
refresh_tokenstringReplacement refresh token. Discard the token used for this request.
token_typestringBearer.
expires_inintegerAccess-token lifetime in seconds.
scopestringScopes retained by the authorization grant.

OAuth 2.0

Revoke tokens

Revoke an access token or refresh-token grant when a user disconnects Juice Reel from your application.

POST/oauth2/revoke
AuthenticationHTTP Basic: client ID and client secret
Required scopeNone

Request parameters

FieldTypeDescription
tokenrequiredstringAccess token or refresh token to revoke.
token_type_hintstringOptional access_token or refresh_token hint.

Response

200 · application/json
FieldTypeDescription
HTTP 200empty objectRevocation is idempotent and does not reveal whether the token existed.

Account

Get the connected user

Return the Juice Reel user ID represented by the access token.

GET/oauth2/me
AuthenticationBearer token and X-OAuth-Client-Id
Required scopeNone
This endpoint is always available to a valid access token and requires no optional scope.

Response

200 · application/json
FieldTypeDescription
juiceReelUserIdintegerStable Juice Reel user identifier for the authorization grant.

Subscribers

List current subscribers

List unique users with a current, non-sandbox subscription to the connected creator.

GET/oauth2/subscribers/current
AuthenticationBearer token and X-OAuth-Client-Id
Required scopesubscribers.read

Response

200 · application/json
FieldTypeDescription
subscribersarrayUnique active subscribers, ordered by latest expiration and creation time.
juiceReelUserIdintegerSubscriber's stable Juice Reel user ID.
subscriptionProductIdstring | nullIdentifier of the purchased subscription product.
purchaseDatedatetime | nullISO 8601 initial purchase time.
expiresDatedatetimeISO 8601 expiration or renewal boundary.
periodTypestring | nullBilling period classification reported by the store.
storestring | nullPurchase provider, such as APP_STORE, PLAY_STORE, or STRIPE.

Bets

List open bets

Return the connected user's open bets using cursor-based pagination.

GET/oauth2/bets/open
AuthenticationBearer token and X-OAuth-Client-Id
Required scopebets.open.read
Results are ordered by descending bet ID. Never modify or decode the cursor to drive application logic.

Request parameters

FieldTypeDescription
cursorstringOpaque nextCursor from the previous response. Omit for the first page.

Response

200 · application/json
FieldTypeDescription
betsarray<Bet>Bets in descending ID order for the connected Juice Reel user.
nextCursorstring | nullPass this opaque value as cursor on the next request. Null means paging is complete.
hasMorebooleanTrue when another page is available. Equivalent to nextCursor being non-null.
bets[].idintegerUnique Juice Reel bet identifier.
bets[].userIdintegerJuice Reel user that owns the bet.
bets[].oddsAmericannumberAmerican odds recorded for the overall bet.
bets[].amountRiskednumberAmount staked in currencyCode.
bets[].toWinnumberPotential profit, excluding returned stake, in currencyCode.
bets[].netResultnumber | nullSettled profit or loss. Positive is profit; negative is loss.
bets[].resultstring | nullHuman-readable settlement result, such as Won, Lost, Push, or Cancelled.
bets[].datePlaceddatetime | nullISO 8601 timestamp when the wager was placed.
bets[].dateCloseddatetime | nullISO 8601 settlement timestamp. Usually null for open bets.
bets[].isAdjustedOddsbooleanWhether the recorded odds were manually adjusted.
bets[].isAdjustedLinebooleanWhether the recorded line was manually adjusted.
bets[].adjustedRisknumber | nullManual risk adjustment, when one exists.
bets[].clvPctnumber | nullClosing-line value percentage, when available.
bets[].createdAtdatetimeISO 8601 creation timestamp in Juice Reel.
bets[].updatedAtdatetimeISO 8601 timestamp of the last update.
bets[].currencyCodestring | nullISO 4217 currency code for monetary values.
bets[].BetTypeobject | nullBet classification with id and typeName, such as Straight or Parlay.
BetType.idintegerUnique bet-type identifier.
BetType.typeNamestringHuman-readable bet classification.
bets[].BetStatusobject | nullLifecycle status with id and statusName.
BetStatus.idintegerUnique bet-status identifier.
BetStatus.statusNamestringHuman-readable lifecycle status.
bets[].Siteobject | nullSportsbook or platform with id and name.
Site.idintegerUnique Juice Reel sportsbook identifier.
Site.namestringSportsbook or platform name.
bets[].Subbetsarray<Subbet>Individual legs that make up the bet.
Subbet.idintegerUnique bet-leg identifier.
Subbet.userIdintegerJuice Reel user that owns the leg.
Subbet.subbetTypestringMarket type, such as Moneyline, Spread, Total, or Player Prop.
Subbet.positionstring | nullSelected team, player, or outcome.
Subbet.valuenumber | nullSelected market line or threshold.
Subbet.oddsAmericannumberAmerican odds for this individual leg.
Subbet.durationstring | nullMarket duration, such as full game or first half, when available.
Subbet.startDatedatetime | nullISO 8601 scheduled start time for the leg.
Subbet.wasLiveBetbooleanWhether this leg was placed after the event began.
Subbet.descriptionstring | nullNormalized human-readable description.
Subbet.scrapeDescriptionstring | nullDescription captured from the originating sportsbook.
Subbet.metricstring | nullPlayer-prop statistic, when this is a player prop.
Subbet.createdAtdatetimeISO 8601 leg creation timestamp.
Subbet.updatedAtdatetimeISO 8601 timestamp of the last leg update.
Subbet.TruthTeam / OppTruthTeamTeam | nullSelected and opposing normalized teams.
Team.idintegerUnique normalized team identifier.
Team.namestringCanonical team name.
Team.displayNamestring | nullDisplay-ready team name.
Subbet.Player / OppPlayerPlayer | nullSelected and opposing normalized players.
Player.idintegerUnique normalized player identifier.
Player.firstNamestringPlayer's first or given name.
Player.lastNamestringPlayer's last or family name.
Player.namestringCanonical full player name.
Player.teamIdinteger | nullNormalized current team identifier.
Player.sportIdinteger | nullNormalized sport identifier.
Player.leagueIdinteger | nullNormalized league identifier.
Player.TruthTeamTeam | nullNormalized team associated with the player.
Subbet.Eventobject | nullNormalized sporting event associated with the leg.
Event.idintegerUnique normalized event identifier.
Event.namestring | nullEvent or tournament name when one exists.
Event.startDatedatetime | nullScheduled event start in ISO 8601 format.
Event.exactStartTimedatetime | nullConfirmed exact start time, when available.
Event.typestringEvent classification, such as Game, Match, or Tournament.
Event.player1Id / player2Idinteger | nullNormalized participant identifiers for head-to-head player events.
Event.homeTeamId / awayTeamIdinteger | nullNormalized home and away team identifiers.
Event.statusstring | nullEvent lifecycle status, such as Scheduled, Live, or Final.
Event.parentEventIdinteger | nullParent tournament or event identifier.
Event.sportIdinteger | nullNormalized event sport identifier.
Event.leagueIdinteger | nullNormalized event league identifier.
Event.descriptionstring | nullAdditional event description when available.
Event.Player1 / Player2EventPlayer | nullNormalized event competitors.
EventPlayer.idintegerUnique normalized player identifier.
EventPlayer.firstNamestringCompetitor's first or given name.
EventPlayer.lastNamestringCompetitor's last or family name.
EventPlayer.teamIdinteger | nullCompetitor's normalized team identifier.
Event.HomeTeam / AwayTeamTeam | nullNormalized home and away teams using the Team fields above.
Event.ParentEventobject | nullParent tournament or event, using the same external event fields.
Event.Sport / LeagueAffiliation | nullNormalized sport and league.
Subbet.BetResultobject | nullLeg settlement result with id and name.
BetResult.idintegerUnique leg-result identifier.
BetResult.namestringHuman-readable leg settlement result.
Subbet.Sport / LeagueAffiliation | nullNormalized sport and league for the leg.
Affiliation.idintegerUnique sport or league identifier.
Affiliation.namestringCanonical sport or league name.

Bets

List settled bets

Return the connected user's closed and cancelled bets using cursor-based pagination.

GET/oauth2/bets/settled
AuthenticationBearer token and X-OAuth-Client-Id
Required scopebets.settled.read
A null nextCursor and hasMore: false indicate that paging is complete.

Request parameters

FieldTypeDescription
cursorstringOpaque nextCursor from the previous response. Omit for the first page.

Response

200 · application/json
FieldTypeDescription
betsarray<Bet>Bets in descending ID order for the connected Juice Reel user.
nextCursorstring | nullPass this opaque value as cursor on the next request. Null means paging is complete.
hasMorebooleanTrue when another page is available. Equivalent to nextCursor being non-null.
bets[].idintegerUnique Juice Reel bet identifier.
bets[].userIdintegerJuice Reel user that owns the bet.
bets[].oddsAmericannumberAmerican odds recorded for the overall bet.
bets[].amountRiskednumberAmount staked in currencyCode.
bets[].toWinnumberPotential profit, excluding returned stake, in currencyCode.
bets[].netResultnumber | nullSettled profit or loss. Positive is profit; negative is loss.
bets[].resultstring | nullHuman-readable settlement result, such as Won, Lost, Push, or Cancelled.
bets[].datePlaceddatetime | nullISO 8601 timestamp when the wager was placed.
bets[].dateCloseddatetime | nullISO 8601 settlement timestamp. Usually null for open bets.
bets[].isAdjustedOddsbooleanWhether the recorded odds were manually adjusted.
bets[].isAdjustedLinebooleanWhether the recorded line was manually adjusted.
bets[].adjustedRisknumber | nullManual risk adjustment, when one exists.
bets[].clvPctnumber | nullClosing-line value percentage, when available.
bets[].createdAtdatetimeISO 8601 creation timestamp in Juice Reel.
bets[].updatedAtdatetimeISO 8601 timestamp of the last update.
bets[].currencyCodestring | nullISO 4217 currency code for monetary values.
bets[].BetTypeobject | nullBet classification with id and typeName, such as Straight or Parlay.
BetType.idintegerUnique bet-type identifier.
BetType.typeNamestringHuman-readable bet classification.
bets[].BetStatusobject | nullLifecycle status with id and statusName.
BetStatus.idintegerUnique bet-status identifier.
BetStatus.statusNamestringHuman-readable lifecycle status.
bets[].Siteobject | nullSportsbook or platform with id and name.
Site.idintegerUnique Juice Reel sportsbook identifier.
Site.namestringSportsbook or platform name.
bets[].Subbetsarray<Subbet>Individual legs that make up the bet.
Subbet.idintegerUnique bet-leg identifier.
Subbet.userIdintegerJuice Reel user that owns the leg.
Subbet.subbetTypestringMarket type, such as Moneyline, Spread, Total, or Player Prop.
Subbet.positionstring | nullSelected team, player, or outcome.
Subbet.valuenumber | nullSelected market line or threshold.
Subbet.oddsAmericannumberAmerican odds for this individual leg.
Subbet.durationstring | nullMarket duration, such as full game or first half, when available.
Subbet.startDatedatetime | nullISO 8601 scheduled start time for the leg.
Subbet.wasLiveBetbooleanWhether this leg was placed after the event began.
Subbet.descriptionstring | nullNormalized human-readable description.
Subbet.scrapeDescriptionstring | nullDescription captured from the originating sportsbook.
Subbet.metricstring | nullPlayer-prop statistic, when this is a player prop.
Subbet.createdAtdatetimeISO 8601 leg creation timestamp.
Subbet.updatedAtdatetimeISO 8601 timestamp of the last leg update.
Subbet.TruthTeam / OppTruthTeamTeam | nullSelected and opposing normalized teams.
Team.idintegerUnique normalized team identifier.
Team.namestringCanonical team name.
Team.displayNamestring | nullDisplay-ready team name.
Subbet.Player / OppPlayerPlayer | nullSelected and opposing normalized players.
Player.idintegerUnique normalized player identifier.
Player.firstNamestringPlayer's first or given name.
Player.lastNamestringPlayer's last or family name.
Player.namestringCanonical full player name.
Player.teamIdinteger | nullNormalized current team identifier.
Player.sportIdinteger | nullNormalized sport identifier.
Player.leagueIdinteger | nullNormalized league identifier.
Player.TruthTeamTeam | nullNormalized team associated with the player.
Subbet.Eventobject | nullNormalized sporting event associated with the leg.
Event.idintegerUnique normalized event identifier.
Event.namestring | nullEvent or tournament name when one exists.
Event.startDatedatetime | nullScheduled event start in ISO 8601 format.
Event.exactStartTimedatetime | nullConfirmed exact start time, when available.
Event.typestringEvent classification, such as Game, Match, or Tournament.
Event.player1Id / player2Idinteger | nullNormalized participant identifiers for head-to-head player events.
Event.homeTeamId / awayTeamIdinteger | nullNormalized home and away team identifiers.
Event.statusstring | nullEvent lifecycle status, such as Scheduled, Live, or Final.
Event.parentEventIdinteger | nullParent tournament or event identifier.
Event.sportIdinteger | nullNormalized event sport identifier.
Event.leagueIdinteger | nullNormalized event league identifier.
Event.descriptionstring | nullAdditional event description when available.
Event.Player1 / Player2EventPlayer | nullNormalized event competitors.
EventPlayer.idintegerUnique normalized player identifier.
EventPlayer.firstNamestringCompetitor's first or given name.
EventPlayer.lastNamestringCompetitor's last or family name.
EventPlayer.teamIdinteger | nullCompetitor's normalized team identifier.
Event.HomeTeam / AwayTeamTeam | nullNormalized home and away teams using the Team fields above.
Event.ParentEventobject | nullParent tournament or event, using the same external event fields.
Event.Sport / LeagueAffiliation | nullNormalized sport and league.
Subbet.BetResultobject | nullLeg settlement result with id and name.
BetResult.idintegerUnique leg-result identifier.
BetResult.namestringHuman-readable leg settlement result.
Subbet.Sport / LeagueAffiliation | nullNormalized sport and league for the leg.
Affiliation.idintegerUnique sport or league identifier.
Affiliation.namestringCanonical sport or league name.

Errors

Common error responses

Resource errors use an error field. OAuth protocol errors use error and error_description.

400X-OAuth-Client-Id header is required

Every external API request must identify its OAuth client.

400cursor is invalid

The supplied bet cursor is malformed or was not issued by Juice Reel.

400invalid_request / invalid_grant

OAuth form fields are malformed, the code is expired or consumed, PKCE failed, or the refresh token is invalid.

401Invalid OAuth access token

The bearer token is missing, expired, revoked, belongs to another client, or its grant is no longer active.

401invalid_client

Client ID, client secret, or HTTP Basic authentication is invalid.

403The access token requires the requested scope

The grant does not contain the scope required by this resource.

5xxInternal server error

A transient server failure occurred. Retry idempotent GET requests with exponential backoff.

API Documentation | Juice Reel