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.
See code example

Request query 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. Send an empty value for identity-only access.
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 scopeNot applicable
SECURITY WARNING: Call this endpoint only from your backend. Never call it from browser or mobile frontend code. Your client secret must never be included in frontend application bundles, shipped to users, or exposed to clients.

Request query 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 scopeNot applicable
SECURITY WARNING: Call this endpoint only from your backend. Never call it from browser or mobile frontend code. Your client secret must never be included in frontend application bundles, shipped to users, or exposed to clients. Reusing a consumed refresh token revokes the token family and associated grant.

Request query 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 scopeNot applicable
SECURITY WARNING: Call this endpoint only from your backend. Never call it from browser or mobile frontend code. Your client secret must never be included in frontend application bundles, shipped to users, or exposed to clients.

Request query 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.

Checkout

Create a checkout session

Create a hosted checkout session that wraps the Juice Reel purchase flow. Redirect the user's browser to checkoutUrl; after checkout succeeds, Juice Reel shows the OAuth consent screen and then redirects to successUrl with a short-lived authorization code and the supplied state. A cancelled checkout redirects to cancelUrl with its status and state. Exchange the authorization code at /oauth2/token; access tokens and client secrets must never be placed in URLs.

POST/checkout/sessions
AuthenticationHTTP Basic: client ID and client secret
Required scopeNot applicable
SECURITY WARNING: Call this endpoint only from your backend. Never call it from browser or mobile frontend code. Your client secret must never be included in frontend application bundles, shipped to users, or exposed to clients.

Request body

FieldTypeDescription
successUrlrequiredstringExact redirect URI registered on the OAuth application for a successful checkout.
cancelUrlrequiredstringExact redirect URI registered on the OAuth application for a cancelled checkout.
scopesrequiredstring[]Requested OAuth scopes. May be an empty array for identity-only access; otherwise scopes must be unique and a subset of the scopes approved for the OAuth application.
staterequiredstringOpaque value generated by your backend and returned unchanged to your successUrl or cancelUrl.
codeChallengerequiredstringPKCE S256 code challenge generated by your backend for the authorization-code exchange.

Response

201 · application/json
FieldTypeDescription
checkoutSessionIdstringUnique identifier for the checkout session.
checkoutUrlstringURL to open in the user's browser to begin checkout.
expiresAtstring (ISO 8601)Time at which the checkout session expires.

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
idintegerStable Juice Reel user identifier for the authorization grant.
displayNamestringUser's current public display name.

Subscribers

List all subscribers

List everyone who has ever subscribed to the OAuth application owner, including expired and sandbox subscriptions.

GET/oauth2/subscribers/current
AuthenticationHTTP Basic: client ID and client secret
Required scopeNone
SECURITY WARNING: Call this endpoint only from your backend. Never call it from browser or mobile frontend code. Your client secret must never be included in frontend application bundles, shipped to users, or exposed to clients. The OAuth client credentials identify the application owner whose subscribers are returned.

Response

200 · application/json
FieldTypeDescription
subscribersarrayAll subscriber records for the OAuth application owner, including expired subscriptions, ordered by latest expiration and creation time.
subscriptionProductIdstringStable identifier of the subscription product purchased from the application owner.
userIdintegerSubscriber's stable Juice Reel user ID.
expiresDatedatetimeISO 8601 expiration or renewal boundary.
isCurrentlySubscribedbooleanTrue when expiresDate is later than the time of the API request.
User.idintegerSubscriber's stable Juice Reel user ID.
User.displayNamestringSubscriber's current Juice Reel display name.
SubscriptionProduct.durationstringBilling duration: WEEKLY, MONTHLY, or YEARLY.

Subscribers

Get subscription status

Check whether the user represented by the access token is currently subscribed to the OAuth application owner.

GET/oauth2/subscribers/status
AuthenticationBearer token and X-OAuth-Client-Id
Required scopesubscribers.read
Returns true without a subscription field when the authenticated user owns the OAuth application. Expired and never-subscribed users receive false without a subscription field.

Response

200 · application/json
FieldTypeDescription
isCurrentlySubscribedbooleanTrue when the authenticated user has a non-expired subscription to the OAuth application owner.
subscriptionobject | omittedActive subscription record. Omitted when no active record exists or the authenticated user owns the application.
subscription.subscriptionProductIdstringStable identifier of the purchased subscription product.
subscription.userIdintegerSubscriber's stable Juice Reel user ID.
subscription.expiresDatedatetimeISO 8601 expiration or renewal boundary.
subscription.isCurrentlySubscribedbooleanTrue when this subscription record has not expired.
subscription.SubscriptionProduct.durationstringBilling duration: WEEKLY, MONTHLY, or YEARLY.

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
If neither datePlacedAfter nor datePlacedBefore is supplied, all available open-bet history is considered. The after boundary is inclusive and the before boundary is exclusive. Results are ordered by descending bet ID. Never modify or decode the cursor to drive application logic.

Request query parameters

FieldTypeDescription
datePlacedAfterstringOptional inclusive lower bound for bet placement time, as an ISO 8601 datetime. Omit to include the earliest available bets.
datePlacedBeforestringOptional exclusive upper bound for bet placement time, as an ISO 8601 datetime. Omit to include the latest available bets.
cursorstringOpaque nextCursor from the previous response. Omit for the first page; reuse the same date filters when requesting the next page.

Response

200 · application/json
FieldTypeDescription
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.
BetA bet in descending ID order for the connected Juice Reel user.

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
If neither dateClosedAfter nor dateClosedBefore is supplied, all available settled-bet history is considered. The after boundary is inclusive and the before boundary is exclusive. A null nextCursor and hasMore: false indicate that paging is complete.

Request query parameters

FieldTypeDescription
dateClosedAfterstringOptional inclusive lower bound for settlement time, as an ISO 8601 datetime. Omit to include the earliest available settled bets.
dateClosedBeforestringOptional exclusive upper bound for settlement time, as an ISO 8601 datetime. Omit to include the latest available settled bets.
cursorstringOpaque nextCursor from the previous response. Omit for the first page; reuse the same date filters when requesting the next page.

Response

200 · application/json
FieldTypeDescription
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.
BetA bet in descending ID order for the connected Juice Reel user.

Bets

List changed bets

Return the connected user's open and settled bets together in one cursor-paginated feed for reconciliation.

GET/oauth2/bets/changed
AuthenticationBearer token and X-OAuth-Client-Id
Required scopebets.open.read + bets.settled.read
Results include open, closed, and cancelled bets with no status filter. They are ordered by updatedAt descending, with bet ID descending as the tie-breaker. Use updatedAtAfter as an inclusive ISO 8601 lower bound when reconciling from a checkpoint. Store the newest updatedAt checkpoint from each page and stop when a returned bet is older than your stored checkpoint. Use nextCursor and hasMore for pagination; the cursor is opaque and must not be modified.

Request query parameters

FieldTypeDescription
updatedAtAfterstringOptional inclusive lower bound for updatedAt, as an ISO 8601 timestamp. Only bets updated at or after this time are returned.
cursorstringOpaque nextCursor from the previous response. Omit for the first page; reuse it until hasMore is false.

Response

200 · application/json
FieldTypeDescription
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.
BetA bet in descending ID order for the connected Juice Reel user.

Usage

Rate limits

API requests are limited in five-minute buckets.

1,000 requestsPer IP address per five-minute bucket
25,000 requestsPer client ID per five-minute bucket

Need a higher limit? Email support@juiceintegration.com.

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.

403Only the OAuth client owner can access this resource

The subscribers endpoint may only be called with a token issued for the user who owns the OAuth application.

429Rate limit exceeded

The IP address or OAuth client ID has exceeded its five-minute request limit. Wait for the bucket to reset before retrying.

5xxInternal server error

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

Create a checkout session | Juice Reel API Docs