Skip to main content

Tokens & sessions

Signatures and API keys authenticate your backend. Tokens scope individual requests. Cheggout issues three kinds, and using the wrong one is the most frequent integration error.

The three credentials

CredentialMinted byScopeAccepted by
Reference tokengetSecuredReferenceTokenYour channelGetReward
User tokenGetAuthTokenOne userFetchRewardInfo, GetAllScratchCardsByUserId
Session IDGenerateSessionInfoV2One user's sessionSDK launch, hosted microsite launch

Reference token — channel-scoped

Identifies you, not a user. GetReward takes the user identity from the virtualId in the request body instead.

That means one token serves all your users, so fetch it on a schedule and cache it — hourly, from a background job. Do not mint one per request.

Scheduled job (hourly) ──► getSecuredReferenceToken ──► cache
Every GetReward call ──► read from cache

User token — user-scoped

Carries a specific user's Cheggout customer identity. Reveal and history endpoints reject a reference token, because acting on a specific user's reward requires proving which user.

Mint one when a user session starts, cache it for that user, and refresh when it expires.

Session ID — SDK and hosted launches

Not a bearer token but a session handle. Your backend requests it with a signed call and passes it, with the virtualId, to the SDK or a launch URL. Cheggout validates it and the user lands already signed in.

Lifetimes

CredentialLifetime
Reference tokenRefresh hourly from a scheduled job
User tokenVaries by channel — commonly 1 hour
Session IDBounded; treat as valid for the user's active session only

TBD Exact lifetimes are configured per channel and are not self-service. Responses carry an expireDate field, but its format is not yet formally specified, so do not parse it as a contract. Confirm your channel's lifetimes with Cheggout, and build a refresh path that reacts to a 401 rather than one that predicts expiry.

Refresh strategy

There is no refresh endpoint. You re-mint by calling the same signed token API again.

Rules that keep this safe:

  • Retry once. A second consecutive auth failure is a configuration problem, not a stale token — do not loop.
  • De-duplicate concurrent refreshes. Under load, many requests will notice expiry at once. Use a single-flight lock so one refresh serves them all.
  • Refresh proactively for the reference token: a scheduled job with a margin (for example every 50 minutes for an hourly token) means user-facing calls never pay the refresh cost.
  • Never retry a business failure as if it were auth. "rewards": [] or REWARD NOT FOUND mean the platform answered successfully — re-minting a token changes nothing.

Using tokens

Bearer tokens go in the Authorization header:

Authorization: Bearer <token>

The Bearer prefix is required, with exactly one space. Sending a bare token is rejected.

Tokens are bearer credentials

Anyone holding a token can act within its scope until it expires. Keep them out of URLs, out of logs, out of analytics, and off the client except where the surface requires it (the widget and SDK legitimately hold a user token). Never put a reference token on a client — it is channel-wide.

Choosing the right token

I want to…Use
Create a scratch card after a paymentReference token
Reveal what's behind a cardUser token
Show a user's reward historyUser token
Launch the SDK or a micrositeSession ID
Read the deals catalogueNeither — API key

If a reveal returns an authentication failure while card creation works, you are almost certainly sending the reference token where a user token is required.

Next