Skip to main content

Core concepts

Six ideas appear in every module. Learn them once here and the API reference reads easily.

virtualId — the user identity

virtualId is your pseudonymous identifier for a user. Cheggout never receives your customer's real identity.

PropertyRequirement
Owned byThe publisher. You generate it.
UniquenessUnique per user within your channel
StabilityImmutable — must not change for that user, ever
PIIMust not embed personal data (no raw email, mobile number or account number)

A virtualId must be immutable and must never be reassigned to a different person. Everything Cheggout holds for a user — reward history, coupons, eligibility and frequency caps — is keyed on it, so changing it or handing it to someone else is not recoverable from your side.

A reasonable virtualId
{ "virtualId": "pub_8f14e45fceea167a" }
Do not recycle identifiers

If you reassign a virtualId to a different person, that person inherits the previous user's rewards and coupons. Treat it as permanently burned once issued.

The iOS SDK names its launch parameter userID rather than virtualId, but it carries this same value.

CHANNELID / channelName — who you are

Your channel is your publisher identity on the platform, issued by Cheggout during onboarding. It appears as:

  • CHANNELID in signed request envelopes
  • X-CHANNELID as an HTTP header on Deals Store APIs
  • channelName / bName inside request payloads
  • channelName as a query parameter on widget and hosted URLs

It is an identifier, not a secret. It tells Cheggout which public key to verify your signature with, which campaigns apply, and which theme to use. Authentication comes from the signature or API key that accompanies it — never from the channel value alone.

Field naming is not consistent across APIs

The same value is called bName in one payload and channelName in another, and some payloads match keys case-sensitively. Each API reference page states the exact key that endpoint expects. Follow the page, not the pattern.

Placements — where things appear

A placement is a slot in your UI that Cheggout can fill. You integrate the slot once; Cheggout decides what goes in it and can change that at any time without an app release.

Placements are addressed by placementId — for example "01" for a banner position and "00" for the store row. Which IDs are valid for your channel is configured during onboarding.

TBD The full placement registry is not yet published. There is no self-service list of valid placementId values or a way to create placements yourself. Ask your Cheggout contact for your channel's placement map. Tracked in Open Items.

Trigger events — what happened

A trigger event tells Cheggout that a rewardable thing occurred. It is a predefined code agreed with Cheggout, not free text, and it maps to a campaign on Cheggout's side.

SurfaceParameterExamples seen in integrations
Mobile SDKtriggerEventTypePayment-type codes such as UPI, IMPS, RTGS, WITHINBANK; channel-prefixed variants also exist
Headless APItriggerEventTypeChannel-specific campaign codes
Web widgeteventTypeCAMPAIGN_ARTICLEREAD; the current examples also use the lowercase form article_read

Some flows also accept subTriggerEventType for a finer-grained sub-category.

TBD The authoritative trigger-code registry is not published. Codes differ by publisher and module, and the examples in circulation are inconsistent. Your codes are assigned during campaign setup — see Trigger events.

extTransactionId — idempotency and reconciliation

For any event that can produce a reward or a coupon, you supply extTransactionId: your own unique reference for that event.

PropertyRequirement
Owned byThe publisher
UniquenessGlobally unique. Never reused.
FormatAlphanumeric, maximum 256 characters
PurposeIdempotency key, and the join key for reconciliation and dispute resolution

A sensible format encodes the source and the moment:

PUB_OFFERBUY_20260213_000045

Replaying the same extTransactionId is how you retry safely after a network failure. Read the idempotency guidance before you rely on it — the guarantees differ by module and there are documented exceptions.

Cheggout returns tracking URLs alongside every reward, banner and store item. They arrive in one of two shapes.

As arrays, on rewards APIs:

{
"trackLink": ["https://tracking.cheggout.com/Tracker/Impression?..."],
"clicktrack": ["https://tracking.cheggout.com/Tracker/clicks?..."]
}

As a tagged string, on banner and store APIs — a pseudo-XML envelope carrying several URLs plus display metadata:

<click>https://example.com/destination</click>
<track>https://tracking.cheggout.com/...Impression...</track>
<clicktrack>https://tracking.cheggout.com/...clicks...</clicktrack>
<browser>Native</browser>
<expiryduration>60</expiryduration>
<id>placement_channel_unit</id>
<redirectURL>...</redirectURL>

The mobile SDKs parse this for you. If you are integrating headlessly, parse out the tag you need and fire the URLs directly with a plain GET.

The contract is simple and non-negotiable:

  • Fire impression URLs when the item becomes visible to the user.
  • Fire click URLs when the user taps or scratches it.

Attribution, billing and your reporting all derive from these calls. An integration that renders correctly but never fires tracking is not finished.

Putting it together

A typical scratch-card trigger
{
"channelName": "YOURCHANNEL",
"virtualId": "pub_8f14e45fceea167a",
"triggerEventType": "YOURCHANNEL_CAMPAIGN",
"extTransactionId": "PUB_TXN_20260731_000117",
"amount": 499.00,
"dateandtime": "31072026141530"
}

Your channel, your user, what happened, your unique reference for it. Everything else — whether a reward exists, which one, and whether this user has had too many already — is Cheggout's decision.

Next