Back to the blog

InviteGuard: let people in with a code, take it back with one call

I built InviteGuard to hand out codes for my ARKD BOX games: beta testers, early access players, features for specific people. A hosted version is coming, and the waitlist is open.

· 3 min read

I have a shelf of ARKD BOX games in different stages of done, and every one of them needs the same thing before launch: a way to let some people in and keep everyone else out.

Beta testers need access before anyone else. Early access players need a key that works for a while and then stops. Some features I only want a handful of people to see until they’re ready. Writing that logic once per game got old fast, so I built InviteGuard and put all of it in one place.

How I use it

Recruiting testers is the first job. I create a batch of codes for a game, send them out, and the dashboard shows me who actually redeemed one and who never got past the email. When the beta ends, I close the door.

Early access works the same way, with a time limit. A code can start a 14 day window the moment a player redeems it. When the window closes, the game knows and can decide what to show next.

Then there are the features I keep back for specific people: a new mode for the testers who found the most bugs, a level for the friends who’ve played every build. Their code says they’re in, everyone else’s says they’re not.

And I’ll probably use codes to sell my web games. Someone pays, gets a code, and the code unlocks the full game. No new system needed.

Three calls

A game talks to InviteGuard with three API calls:

  • POST /api/v1/verify at sign-up. It checks every rule on the code, records who redeemed it and uses it up.
  • POST /api/v1/check-access at login. A read-only call that answers one question: is this player still allowed in? If the code started a timed window, it also says how many days are left.
  • POST /api/v1/revoke when I need it. Cut off a code, an email or a user ID. The next access check says no. Restoring it is just as quick.

Splitting verify from check-access was the decision that mattered most. Verify changes state and runs once. Check-access is cheap and the game can call it as often as it likes, which makes it a kill switch I can flip from the dashboard without shipping a new build. If a beta key leaks to a forum, it stops working the next time anyone opens the game.

Rules you can stack

Each code carries settings, and they combine:

One use, N uses, or unlimited until I revoke it. Locked to a single email address. An expiry date. And a timed grant, so redeeming the code starts a 7 or 14 day window.

So one code can be locked to ada@example.com, work once, expire next week and grant 14 days of access when it’s redeemed. A public beta link is one unlimited code with an end date. A code for a meetup is 100 uses that stop on Sunday night.

A request looks like this

curl "$INVITEGUARD_URL/api/v1/verify" \
  -H "Authorization: Bearer $INVITEGUARD_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "code": "LUMEN-7XK2-M9QP", "email": "ada@example.com" }'

Plain JSON over HTTPS. When a check fails, the game gets a reason it can show the player, like CODE_EXHAUSTED or EMAIL_MISMATCH, instead of a bare false.

The boring parts I cared about

Invite systems look trivial until two people redeem the last use of a code at the same moment. Redemption in InviteGuard is a single conditional database update, and there’s a test that fires 20 concurrent verifies at a one-use code and expects exactly one winner.

The rest is what I’d want from anything holding my players’ access. Codes and API keys are stored hashed and shown once. The API is rate-limited. Default codes look like LUMEN-XXXX-XXXX and have about a trillion combinations, so guessing one at the allowed rate isn’t a plan.

Want it for your own app?

Right now InviteGuard runs for my games only. A hosted version anyone can sign up for is the obvious next step, but I’m not building sign-up and billing on a hunch. There’s a waitlist on inviteguard.com. If enough people join, I’ll build it. If you leave a line about what you’d gate (a game beta, a SaaS trial, a community), that tells me what to build first.

And if you’re about to write your own invite code table for the fifth time, maybe don’t.

Back to the blog