API reference

Base URL: https://api.myadrewards.com. All endpoints speak JSON; timestamps are RFC 3339. This page documents the public integration surface — the same endpoints the tag, the earn mark, the wallet, and the portals use.

Authentication

Viewer & business sessions — email code

POST /v1/auth/otp/request     { "email": "[email protected]" }   → 202, empty body
POST /v1/auth/otp/verify      { "email": "…", "code": "123456" }
                              → { "session_token": "…", "expires_at": "…" }

Codes are 6 digits, live 10 minutes, are single-use, and are rate-limited (5 requests per rolling hour per email). A wrong code returns 401. The session token is an opaque credential valid for 30 days; send it as Authorization: Bearer <session_token>. GET /v1/auth/me returns { email, roles }; POST /v1/auth/logout ends the session. Every account holds the user role implicitly; publisher and advertiser roles are granted by the My Ad Rewards team and gate the business portal.

Google sign-in

GET /v1/auth/google/start redirects to Google; the callback (GET /v1/auth/google/callback) exchanges the code and mints the same 30-day session, handing it to the browser via a postMessage handoff (or as JSON with ?format=json). Returns 503 where Google sign-in isn't configured.

Identity tokens (devices & screens)

Separate from sessions: an identity token binds a publisher_id to one account user and one device, and is what events carry.

POST /v1/identity/tokens      (session)
{ "publisher_id": "pub_123", "user_id": "…", "device_id": "…", "ttl_seconds": 86400 }
→ 201 { "token": "…32 hex chars…", "expires_at": "…" }     (default TTL 24 hours)

GET  /v1/identity/device-state?publisher_id=pub_123&identity_token=…
→ { "registered": true, "publisher_id": "pub_123" }        (booleans only, no session)

Only server-minted tokens make a device registered — a token a tag generated for itself never counts, which is what keeps the earn mark and CTV notifications honest.

Operator key

Platform administration uses an X-Operator-Key header instead of a session. It fails closed: no key configured, no access. Operator endpoints are marked below and are not part of the integrator surface.

Events & receipts

Method & pathAuthPurpose
POST /v1/eventsnoneIngest one report (delivery_report, viewability_confirm, completion_confirm). Answers 202 with the outcome; 422 on validation failure. Deduplicated on (source, nonce); timestamps older than 24 h or >5 min in the future are rejected. A publisher report with "claim_surface": true also mints a scan-to-claim token (see earning surfaces).
GET /v1/events/receipts/{nonce}none — the nonce is the capabilityOne view's receipt: { id, status, points_issued, points_claimable, claim_expires_at, mode, user_id, settled_at, expired_at, created_at }. Statuses: pending → matched → claimable → settled / expired.
POST /v1/events/receipts/{nonce}/claimidentity token in bodyThe earn-mark claim: { "identity_token": "…" }. Claims the verified reward for that token's viewer.

Claims

Method & pathAuthPurpose
POST /v1/claims/impressions/{nonce}sessionWallet claim of a verified view (the phone-claim path for CTV). Outcomes: 200 claimed · 404 unknown · 403 not the owner · 409 already claimed · 410 expired · 402 funding insufficient.
POST /v1/claims/redeemsession + ?user_token=Redeem a scan-to-claim token; the scanning viewer earns. See earning surfaces.
GET /v1/notificationssessionClaimable CTV rewards waiting on the viewer: { notifications: [{ id, nonce, points, status, created_at, expires_at }], total }.

Identity, devices & pairing

Method & pathAuthPurpose
POST /v1/identity/tokenssessionMint a server-side identity token (above).
GET /v1/identity/device-statenoneRegistration check used by the earn mark: { registered, publisher_id }.
/v1/identity/devicessession + ?user_token=The viewer's device enrollments (list / create / revoke).
POST /v1/identity/pairing-codessessionMint a screen pairing code: 201 { code } — 8 chars (XXXX-XXXX), 10-minute TTL, single-use.
POST /v1/identity/pairing/confirmnone — the code is the capabilityA screen redeems a code: { code, device_id, label, kind } → the registered screen record. Idempotent for the same screen + account; refused if the screen belongs to another account. Paired screens can be listed and revoked from the wallet.

Cashback & capture

Method & pathAuthPurpose
POST /v1/cashback/claimssession + ?user_token=Receipt cashback claim — the receipt image is hashed on-device and never uploaded with line items. Details on the earning surfaces page.
POST /v1/ooh/claimssessionOut-of-home capture claim — a perceptual hash + location, never the photo. Details on the earning surfaces page.

Business portal

The business portal (for publisher- and advertiser-role accounts) is backed by session-authenticated endpoints scoped to the signed-in account: your funding programs, deposits, bindings, balances, and transactions if you fund rewards; your traffic, settled pairs, and earnings if you publish. Ownership is enforced server-side — another account's program returns 404. Day-to-day work happens in the portal UI; the funding plane behind it is administered with our team and listed under Operator below.

Webhooks

Configured per deployment at onboarding (one endpoint URL + shared secret). Events: points.issued and survey.response. Envelope: { event, data, sent_at }, signed with X-AdRewards-Signature: <hex HMAC-SHA256 of the raw body>. Delivery is attempted up to 5 times with backoff from 1 s, doubling, on network errors, 5xx, and 429; other 4xx responses are permanent failures. Payload fields are in the advertiser guide.

Restricted — operator endpoints. The endpoints below require the X-Operator-Key header and exist for platform administration by the My Ad Rewards team. They are documented for completeness; integrators never call them.

Operator (restricted)

Method & pathPurpose
PUT /v1/operator/accounts/rolesGrant/revoke the publisher and advertiser roles on an account.
/v1/funding/programsFunding programs (create / read); PUT /v1/funding/programs/{id} updates a program including its per-action action_rates.
/v1/funding/depositsRecord a deposit ({ amount } in points) against a program.
/v1/funding/bindingsBind a program to a publisher_id, creative_id, or campaign_id.
/v1/funding/balance, /v1/funding/transactionsProgram balance and ledger transaction history.
GET /v1/reports/daily?date=YYYY-MM-DDPlatform day report: events ingested, pairs matched/settled, receipts expired, points issued by funding kind, distinct users/creatives/publishers.
GET /v1/reports/publisher/{id}Per-publisher reconciliation: events, pairs settled, points settled on the publisher's inventory by funding kind, points funded by the publisher's own programs, programs and bindings in effect.
GET /v1/reports/ledger, GET /v1/ledger/integrityLedger export and integrity check.
GET /v1/webhooks/deliveriesWebhook delivery audit log.

Merchant enrollment for receipt cashback and out-of-home site/flight setup are also operator-administered — see the earning surfaces page.