Documentation

← Panda Auth

For Developers · Monetization & Growth

Key Streaks

Key Streaks reward users for coming back. Every day a user completes your get-key flow, their streak goes up by one, and you decide what reaching a given day is worth: extra time on the key, Panda Token Credits, or a webhook you can hang anything off. Designed for retention: turning a one-off visitor into a daily habit.

What a streak is

A streak is a count of consecutive days on which a user successfully finished your checkpoint flow and received a key. Finish today and tomorrow, and your streak is 2. Miss enough days and it goes back to 1 and starts over.

Who a streak belongs to: the device, identified by its HWID. That is deliberate. The get-key page has no login: the visitor is an anonymous device, and the HWID is what the key binds to anyway. If the same browser also happens to be signed in to a PandaAuth account, that account is recorded alongside the streak, but it is never the identity. A user who signs in halfway through a streak keeps the streak they already built.

Per service. Streaks do not pool across your services. A user with a 12 day streak on one service starts at zero on another.

What counts as a qualifying day

One qualification per day, per user

A day counts once. The first completion of the day advances the streak; everything after it that day is recorded as a normal key issue and changes nothing. A user cannot get to day 30 in an afternoon by refreshing.

Counted:

  • Finishing the last checkpoint of your get-key flow
  • Returning successfully from an ad provider on the final step
  • The ad-callback variant of the same flow

Not counted:

  • Opening or refreshing the page, or reaching an ad
  • An intermediate checkpoint, before the flow is finished
  • A retried request that hands back a key the user already has, rather than issuing a new one
  • Instant Access, which has no checkpoints and would be farmable for the length of the window
  • Keys you create yourself: the bulk key API, a service import, or an HWID reset, which re-issues a key the user already earned

Grace Period

What it does: decides how forgiving a missed day is. A user who misses their bus on Tuesday should probably not lose a 40 day streak, but you choose how much slack that is worth.

The rule, exactly as the system applies it: a user whose last qualifying day was day D is due on day D+1. They keep the streak if they qualify at any point from the start of D+1 until the grace period elapses after the END of D+1.

The deadline is measured against the real completion time, not rounded to a day. "12 hours" means twelve hours.

  • Strict: no slack at all. The next day or the streak resets.
  • 12 hours: last qualified on the 5th, due on the 6th, and the streak survives until noon on the 7th.
  • 24 hours (default): exactly one skipped day is forgiven. Last qualified on the 5th, so anywhere on the 6th or the 7th keeps it, and the 8th resets it.
  • 48 hours: two skipped days are forgiven. Last qualified on the 5th, so anywhere up to the end of the 8th keeps it.

A grace day is not a free day

Grace only stops the streak from breaking. It does not award the skipped day. A user who qualifies on the 5th, skips the 6th and qualifies on the 7th under 24 hour grace goes from 4 to 5, not to 6.

Day Boundary

What it does: shifts the moment a streak day rolls over. By default the day rolls at 00:00 UTC. The offset is in minutes, so if your community is mostly in one region and you would rather the day break at their local midnight, set the offset to their UTC offset.

Why it is UTC and not server time: PandaAuth runs on more than one node. If the boundary followed each machine's local clock, a user served from Europe and a user served from Singapore would disagree about which day it is, and the same completion could count twice or not at all. One fixed boundary per service, applied everywhere, is what makes the streak consistent.

Changing the offset mid-streak

Moving the boundary shifts which day a completion lands in, so a user who qualified just either side of the old boundary can find that the new one puts two of their completions in the same day. Nothing is lost, but the change is best made when you set the feature up rather than while streaks are running.

Reward Mode

  • Milestone: pays only on the days you configured. Day 3, day 7, day 30, whatever you set. Nothing on the days in between.
  • Daily: pays the same small reward on every qualifying day, and ignores milestones.
  • Hybrid: pays the daily reward AND any milestone that lands on the same day. A user reaching day 7 gets both.

A reward set to day 0 is the daily reward. Any positive number is a milestone on that day of the streak.

Reward types

Key Duration

What it does: adds minutes to the key that completion issues. Reach day 7 with a +60 reward and that key lasts an hour longer than your normal key duration.

It applies to one key, not to your service

The bonus is added to the single key the user just earned. It does not change your service's key duration setting, and it does not carry over to the next key. Tomorrow's key is a normal key again, plus whatever tomorrow's reward is worth.

Panda Token Credits

What it does: credits Panda Tokens to the user's PandaAuth account.

They are permanent. Credits land in the persistent balance, the same bucket purchases and redeem codes use. The monthly allowance reset on the first of the month never touches them. A user who earns 5 credits in March still has them in December.

Requires a signed-in user

An anonymous device has no account and therefore nowhere to put tokens. When an anonymous user reaches a token milestone the reward is recorded in history and the milestone is marked as used for that cycle, but nothing is credited, and the get-key page says so rather than claiming a credit that never arrived. If token rewards matter to you, tell your community to sign in to PandaAuth in the same browser before they claim.

Webhook

What it does: fires a webhook when the milestone is reached, carrying the streak day, the user's longest streak, a summary of the other rewards paid, and your custom message. Use it for a Discord announcement, a role grant through your own bot, or anything else you want to drive off a milestone.

Where it goes: the dedicated streak webhook URL if you set one, otherwise your service's existing Discord webhook, so you do not have to configure a second one.

A failed delivery costs the user nothing. The streak is committed to the database before delivery is even attempted, and the result is stamped onto the reward history as sent or failed. A webhook that is down cannot roll back a day the user legitimately earned.

Cycles, and rewards that repeat

Every unbroken run is a cycle. When a streak breaks, the next qualifying day starts a new one. Reward history is tracked per cycle, which is what lets a milestone pay more than once: a user who reaches day 7, drops off, comes back and reaches day 7 again is in a new cycle and is paid again.

Within one cycle each milestone pays exactly once. That holds even if you edit the reward. Changing "day 7 = +1 hour" into "day 7 = +2 hours" applies from each user's next cycle. A user who already collected day 7 in their current cycle does not collect the difference.

Show to users

What it does: controls whether the get-key page shows the user their streak and the reward they are working towards. Turn it off and the feature keeps running silently: days still count, rewards still pay, the user just does not see a counter.

Most operators want this on. The counter is most of the reason the feature works.

Turning it off

Disabling preserves everything

Switching Key Streaks off stops processing. It does not delete anything: every streak, every qualifying day and every reward already paid stays exactly where it is. Switch it back on and the feature resumes from the state it was frozen in. Users who were away longer than your grace period naturally land in a new cycle, which is the same thing that would have happened had the feature never been off.

How Key Streaks work

Five things to remember

  • One day, one qualification. The first completed flow of the day counts. Everything after it that day is just a key.
  • Grace saves the streak, it does not fill the gap. A forgiven day still does not increment the counter.
  • Duration bonuses are one-shot. They extend the key that was just issued and never touch your service's configured duration.
  • Token credits are permanent, and need an account. The monthly reset never claws them back, and an anonymous device cannot receive them.
  • A streak never costs a user their key. If the streak bookkeeping fails for any reason, the key is still issued. The streak is a bonus on top, never a gate.

Recommended defaults

For a service that just wants users coming back:
  • Grace Period: 24 hours. Forgiving enough that one busy day does not undo a month, strict enough that the streak still means something.
  • Reward Mode: Milestone, with rewards on day 3, day 7 and day 30. Early wins keep new users going, the long one gives regulars something to protect.
  • Day Boundary: 0 unless your community really is concentrated in one region.
  • Show to users: On.
Start with Key Duration rewards. They cost you nothing, they are instantly understood, and they work for anonymous users. Add Panda Token Credits once enough of your community is signed in for them to land.