Pulse Studio

The operator console: configure your wheel, streaks, leaderboards, raffles, promo codes, and VIP program yourself — every change validated with the platform's own budget rules and versioned, live on save. Hosted by Pulse; added to your admin portal with a link.

Getting access

  1. Ask your Pulse account manager for a Studio key (pss_…).
  2. Open https://admin.playwithpulse.com/studioand sign in with it — once per browser; it's held in an httpOnly cookie.
  3. You'll see a tab for every feature your plan includes — author configs, hit Save, and the change governs the very next spin/claim/draw.

Adding it to your admin portal

Two modes. The simple one is a link-out:

<a href="https://admin.playwithpulse.com/studio" target="_blank">
  Rewards Studio
</a>

Or embed it in-panel (signed embed)

For a true in-dashboard tab, your backend mints a single-use embed URL and you iframe it — the operator is auto-signed-in, no key typing, no third-party-cookie login:

POST https://api.playwithpulse.com/v1/studio/embed-token
Authorization: Bearer <PULSE_API_KEY>          // backend only, as always
-> {"token": "pse_...", "expires_in": 60,
    "embed_url": "https://admin.playwithpulse.com/studio/embed?token=pse_..."}

<iframe src={embed_url} style="width:100%;height:85vh;border:0" />

Pair it with an embedded Player 360 panel on your customer-view page (via your backend, using your normal API key) — the profile read is PII-free by design, so support staff can see VIP tier, LTV, churn band, and RG status without touching personal data. The agent prompt below builds both.

The Studio key security model

prw_ API keypss_ Studio key
Lives inyour server environmenta staff browser (httpOnly cookie)
Scopeeverything — money, PII, eventsreward configs only
Can edit reward configsyesyes (its purpose)
Can mint embed sessionsyesno (401)
Can edit your billing planno, ever
Rotation impactbreaks your integration until redeployednone — rotate freely on staff changes

Every save is validated (an over-budget wheel cannot be saved) and versioned — you can always see what changed and when. Ask Pulse to rotate the Studio key whenever someone with access leaves.

Integrate with your coding agent

Building with Claude, Cursor, Copilot, or another AI agent? Paste this prompt — it contains the complete contract, the security rules, and an acceptance checklist, so your agent can implement the integration without reading these docs.

Add "Pulse Rewards" to this back-office / admin portal. Pulse is the
gamification platform this site already integrates (wheel, streaks,
raffles, promos, VIP, CRM). Two pieces: a link-out to the hosted Studio,
and (optional but recommended) an embedded Player 360 panel.

## Non-negotiable rules
1. TWO different keys, never confused:
   - PULSE_API_KEY ("prw_..."): backend-only, moves money/PII. Already in
     our server env. NEVER used in anything browser-facing.
   - The Studio key ("pss_..."): configs-only. It is NOT stored in this
     codebase at all - a human enters it once on Pulse's hosted Studio
     sign-in page, which keeps it in an httpOnly cookie on Pulse's domain.
2. Two integration modes - pick ONE:
   - LINK-OUT (simplest): a nav link to the hosted Studio; operator signs
     in once with their pss_ key.
   - SIGNED EMBED (in-panel iframe): our backend mints a single-use embed
     URL per page-load and we iframe it - the operator never types a key.
     Never cache or reuse embed URLs; they are single-use and expire in 60s.
3. The Player 360 panel calls Pulse through OUR backend with PULSE_API_KEY
   and renders the PII-free profile - safe for support staff.

## Build these pieces
A. EITHER a back-office nav item "Rewards Studio" -> opens
   https://admin.playwithpulse.com/studio in a new tab (hint: "sign in
   with your Pulse Studio key, pss_..."),
   OR the signed embed: a staff-authenticated backend endpoint
   GET /api/admin/studio-embed that calls
   POST https://api.playwithpulse.com/v1/studio/embed-token
   (Authorization: Bearer PULSE_API_KEY - the FULL prw_ key; the pss_
   Studio key deliberately CANNOT mint embed tokens and returns 401)
   -> {embed_url, expires_in: 60}
   and returns embed_url; the admin page then renders
   <iframe src={embed_url} style="width:100%;height:85vh;border:0"/>.
   Mint a FRESH token on every page view (single-use, 60s TTL). The
   session inside the iframe persists via a partitioned cookie afterward.
B. (Recommended) A "Player" panel on our customer-view page:
   backend GET /api/admin/pulse-profile?player_id=... (staff-authenticated)
   -> proxies GET https://api.playwithpulse.com/v1/crm/players/{id}/profile
   with PULSE_API_KEY, returns as-is. Render: VIP tier + progress, LTV,
   churn band, streak, wagered_30d, days_since_purchase, rg_status badge,
   messageable badges. This response is PII-free by design.
C. (Optional) same pattern for GET /v1/vip/players/{id} (claim states) and
   GET /v1/raffles/{id}/winners on an ops dashboard.

## Acceptance checklist
- [ ] Studio opens from our nav; no pss_ key stored anywhere in this repo.
- [ ] The profile panel renders for a real player id; shows RG badge.
- [ ] PULSE_API_KEY appears nowhere in built frontend assets.
- [ ] Staff without back-office auth cannot reach the proxy endpoints.
Ask me for: where the back-office nav is defined, the customer-view page,
and how staff authentication works in this codebase.