UUnlockHub docsOpen dashboard

UnlockHub handbook

Build an unlock flow people understand.

A practical guide to configuring your gateway, choosing the right reward path, and connecting UnlockHub to your own product or Discord community.

Editor guide Updated for current flows

Start here

The project editor in three moves

  1. Create a project and decide how users receive access.
  2. Shape the gateway, offers, paid unlock, and optional integrations.
  3. Save the project, open a test session, and publish the gateway link.

The editor preview is a live rendering of the gateway. It reflects the saved project values and most unsaved changes immediately.

01 / Identity

Project settings

Project name and slug identify the gateway in your dashboard and determine its public link. The title, subtitle, and reward description are visitor-facing content, so keep them short enough to scan on a phone.

Test sessions use the project settings stored on the server, so save before opening one when you need to verify the public flow.

02 / Presentation

Gateway design and color controls

Layout controls the structure of the gateway. Color scheme controls the visual tokens used by that layout. Custom overrides win over the selected scheme and stay attached when you switch layouts.

Design labels

These are layout-specific labels such as route names, stamps, and small editorial markers. Disable them when your own title and reward copy should carry the page.

Every field shows on every design

A design changes how the page looks, not which of your fields appear on it. Title, subtitle, reward description, content name and the trust footnotes each have their own switch, and every design renders every one of them. Switching design never drops a field you filled in. The Header switch only removes the design's own frame and branding (top lines, brand names, status labels); your content stays put.

Switched on is not the same as filled in

Turning a field on only means it may appear. What it shows depends on whether it has something to show. Most fields carry a default, so they appear the moment you switch them on: the title falls back to the project name, the reward description to the line that design ships with, the content name to "Tasks", the task button to "Unlock Content", the trust footnotes to "Server verified" and "Instant delivery", and every design label to its own wording (its placeholder in the editor is that default). The subtitle is the exception: it has no default, so an empty subtitle shows nothing at all until you write one.Emptying a design label on purpose works the same way round: a cleared box removes that label from the design instead of falling back to the default. A field you switch off never appears whatever it holds. Its text is kept, so switching it back on brings the text back.

Project logo

Turn on Project logo and upload an image: it is cropped to a square and shown as a circle to the left of your title, the way a community icon sits beside a server name. Designs that already print an icon next to the title (the people mark on Blueprint) show your logo in its place rather than beside it. PNG or is what the gateway stores; JPEG and WebP uploads are accepted and converted on the way in, and anything bigger than a 300 KB square is refused with the reason. The logo belongs to the project, so it appears on the live gateway and in the editor preview alike, and switching the toggle off hides it without deleting it.

Uploads are re-written, never stored as sent

What you pick is not what gets saved. The editor decodes the file, draws the centre square onto a canvas and re-encodes a fresh 256×256 PNG, and the server then checks the file's own chunk structure, inflates the pixel data under a hard ceiling, so a tiny file cannot expand into gigabytes, and drops anything after the final chunk. The result is a clean square PNG and nothing else, which means an image cannot smuggle a script or a second file into your gateway.

03 / Delivery

Choose a reward flow

Pick the flow that matches where access should be delivered. The available Discord option appears after the Discord server flow is enabled in Project Details.

Code checked by your own API or botUnlockHub issues the code and your own app decides who may use it.
Code checked by Discord Bot and user gets roleLet the connected bot verify the code and assign the configured Discord role.
Redirect WebsiteSend the visitor to the configured callback URL after a successful unlock.

If a Discord bot flow is already configured for the project, it keeps working regardless of the reward type. The bot verifies codes, grants roles and expires access on its own, so switching to Code checked by your own API or bot or Redirect Website later will not disable or break your existing Discord configuration.

Instructions on the unlocked screen

For the two code-based reward types the Reward settings section also takes an Instructions text field. It is shown under the access key on the reward-unlocked screen. Use it for the steps the visitor has to follow: where to redeem the key, which ticket to open, who to contact on Discord. Leaving it empty keeps the default text.

Who may use a key

How a key is spent depends on the reward type, because only one of them knows who is asking.

With Code checked by Discord Bot and user gets role the bot knows the Discord account, so People who can redeem this key decides how many different accounts one key lets in. One person locks it to whoever redeems it first; a limited or unlimited key hands out a seat to each new account, and the same account redeeming again never takes a second one. This is what makes a subscription key usable by a group: it keeps working for everyone while the subscription is active, and when the subscription ends every seat loses access at the date that was paid for.

With Code checked by your own API or bot UnlockHub never sees who is asking, so there is nothing to lock a person to. You choose Usage instead: One time use accepts the first verification and refuses every later one, while Infinite uses keeps accepting the key for as long as it is valid. Locking a key to one person is then your own call. See the API examples below.

Redemption window

Redemption window (hours) limits the key itself: after that many hours it can no longer be redeemed. Leave it empty and the key never expires. Subscription payments ignore it, because their keys last exactly as long as the subscription does.

Emailed rewards

"Email the reward to the payer" sends the access key (or the redirect link) to the address used at checkout, so a customer who closes the tab still receives it. It only applies to paid unlocks: a reward unlocked by completing offers is never emailed, because there is no address to send it to and no payment to tie it to.

The email never names your project. A project's name is an internal label for your dashboard, so the message carries only the key, the instructions you wrote above, and UnlockHub's own footer.

03a / Developer flow

API code validation

API codes are designed for a bot, backend, or website that wants to control the final access decision. The project key is masked by default in the editor, with reveal, copy, and regenerate controls. Store it in your server environment and never expose it in browser code.

If your traffic and content are on Discord only, consider configuring the flow directly on UnlockHub. Enable the "Does your traffic come from a Discord Server?" checkmark to be able to configure Discord related settings, and set the reward type to"Code checked by Discord Bot and user gets role".

In theory, you can instead select the "Code checked by your own API or bot" reward type, use your own bot and embeds on your Discord, and check the validity of the codes yourself, completely bypassing the UnlockHub bot. That's just redundant.

Normally this reward type is used when your Community or Content platform is off Discord, or when you want your own backend to decide who gets in.

The API validation flow is:

  1. Generate a project API key in Reward settings.
  2. Let a completed session reveal its code.
  3. POST the code to /api/reward/verify with the project key.
  4. Grant access only when the response is valid and a seat is free.

Redeem a code

curl -X POST https://www.unlockhub.xyz/api/reward/verify \
  -H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key":"REWARD_CODE_FROM_SESSION","redeemerId":"end-user-123"}'

Fresh seat

{"valid":true,"alreadyClaimed":false,"seatsTotal":25,"seatsLeft":24}

Every seat taken

{"valid":false,"alreadyClaimed":true,"reason":"seats-exhausted"}

Check without consuming

curl -X POST https://www.unlockhub.xyz/api/reward/verify \
  -H "Authorization: Bearer YOUR_PROJECT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"key":"REWARD_CODE_FROM_SESSION","consume":false}'

In this example, YOUR_PROJECT_API_KEY authenticates your server and REWARD_CODE_FROM_SESSION is the code the visitor received. Grant access only for a fresh seat; the second response means the key is fully used and nobody else may be let in.

consume: false is a pure read: it reports whether the key is still valid, how many seats are free and when the access ends, without redeeming anything. Use it when your own backend decides who gets in, for example to keep accepting one shared key for as long as the subscription behind it is active.

Which usage mode do I want?

Both modes are shown by the reward type Code checked by your own API or bot, in Reward settings under Usage.

One time use is the classic code: hand it to exactly one person. Lock it to that person yourself by always sending the same identity with the code, so they can come back and check again while nobody else can take it:

One time use + your own identity = locked to one person

# first check: takes the key
{"key":"...","redeemerId":"user-42"}  →  {"valid":true,"alreadyClaimed":false}

# the same person checks again: already theirs
{"key":"...","redeemerId":"user-42"}  →  {"valid":true,"alreadyClaimed":true}

# anybody else
{"key":"...","redeemerId":"user-99"}  →  {"valid":false,"reason":"seats-exhausted"}

Infinite uses = keep validating for as long as it is valid

# every call is accepted, so you always ask first
{"key":"...","consume":false}  →  {"valid":true,"seatsLeft":null,"accessUntil":null}

# one call that consumes and hands out the access
{"key":"...","redeemerId":"user-42"}  →  {"valid":true,"alreadyClaimed":false}

Read accessUntil to know how long the access you just granted should last, and subscription to tell whether it follows a subscription. A key tied to a subscription answers valid: false with reason: "entitlement-ended" once that subscription stops paying, so nothing needs to expire on your side.

Managing keys afterwards

Every project with a code reward has a Manage access page (button in the top right of the editor). It lists the keys, and for each one: how many times it was redeemed, how many seats are in use, when the key stops being redeemable, when the access ends, and who redeemed it with the Discord user ids when the reward is handled by the bot. From there you can revoke a single person's access or the whole key (revoking a seat frees it for somebody else, so restoring is refused if the seat was taken meanwhile), and generate a new key by hand. A hand-made key is a normal key: same seats, same window, same rules, and it is never emailed because there is no payment behind it.

The Rewards list in the dashboard

Dashboard → Rewards is the same list across all of your projects, with a column naming the project of every key and a project filter (all projects by default), so you can look at one key, one project, or everything at once. Filters are limited to what can be counted exactly: never redeemed, redeemed or revoked, because a list whose counts disagree with its rows is worse than no filter at all; everything else (window closed, no seats left, subscription ended) is shown as a badge on the key's row.

Redemption is atomic

Validation and claiming happen together on the server, so two requests cannot both take the same last seat. Give the key a single seat and it behaves exactly like a classic one-time code; give it more and it becomes a shareable key that your own API decides how to hand out.

04 / Pricing

Offers, paid unlocks, and discount rules

The access model controls whether visitors can use offers, a one-time payment, subscriptions, or a combination. Offer wait adds a delay before the free route becomes available. You can also choose how many tasks are needed for the free unlock. How long the granted role lasts is set per Discord server in the Discord configuration.

Regional pricing and discount reveals

Enable discounts and regional prices in the Monetization section to offer different effective prices to different regions. Each rule can target a country, a continent, or everyone. Tiers use a discount percentage plus relative odds; the visitor's country selects the first matching rule. The result can be revealed with either a spinning wheel or a gift box that unboxes the discount. The animation is only the presentation layer; the server chooses and records the discount.

Custom perceived odds (wheel only)

By default each slice of the wheel is sized by its discount rank, so the picture says nothing about how likely a discount is. Turn on Custom perceived odds to size every slice yourself with a "perceived chance weight" per tier. The wheel then shows the odds you want visitors to believe. This is cosmetic only: the discount actually granted is still decided by each tier's chance weight, so a bigger slice never wins more often.

The editor shows the resulting one-time and monthly prices beside every tier, so you can check the regional pricing before saving. If discounts are disabled, visitors see the normal configured prices without a reveal animation.

How payouts work

You are credited every sale in full, minus the card processor's fee for it. UnlockHub only takes its cut when you withdraw, as a flat platform fee.

Current policy

What you earn

Offers and tasks100%
Paid unlocks and subscriptions100%

When you withdraw

Minimum request$100
Platform fee25%

Offer payouts are credited exactly as the provider reports them, and paid unlocks are credited for the amount that reaches the UnlockHub account after the card processor's fees. No commission is taken from either. The fee only applies at withdrawal: request $100 and you are paid $75, while the full $100 is what leaves your balance. If a sale is refunded or charged back, that credit is reversed. The customer keeps the access they were given.

Wallet and cashouts

Revenue lands in your wallet the moment a conversion or payment is confirmed, and you can see the running balance, every transaction and breakdowns by project, device, country and access model under Wallet in the dashboard. A cashout request leaves your balance immediately and shows as pending until the payment is sent, so the same money cannot be requested twice. If a request is rejected, the full amount (fee included) returns to your balance.

Requesting a cashout

In the Wallet, type the amount or press All to cash out the whole balance; the fee calculator shows what you receive before you commit. Requesting asks for confirmation, then explains the next step: payment method and delivery are arranged with us on our Discord server, so open a ticket there. The status of every request, pending, delivered or rejected (including any note we leave), is on your Payouts page, which only ever shows your own requests.

Preview parity

The editor preview creates a synthetic session and renders the sameGatewayBody used by the public locker page. It does not maintain a second set of design templates, so what you see there is what a visitor gets.

05 / Community

Discord integration

Enable the Discord flow when a bot should verify codes and manage roles. Install the bot, choose the portal server and channels, then place the bot role above every role it must assign.

Single server

The same server promotes the gateway and owns the access roles. The bot posts the configured embed and grants the selected role after a successful redemption.

Dual server

Use a portal server for promotion and a content hub for shared access. Multiple projects can point to the same content hub.

Example: six portals, one content hub

  1. Create six projects, one for each marketing server, and choose Dual server setup for each.
  2. Give every project its own portal server and gateway.
  3. Point all six projects at the same content hub.
  4. The first project that connects the hub owns the shared hub embed; keys from any portal can still redeem through the connected content flow.

Refresh channels and roles after installing the bot. Discord only permits role assignment below the bot's highest role, so hierarchy is the first thing to check when a role is visible but cannot be granted.

06 / Operations

Webhooks and security

Completion webhooks are optional server-to-server notifications for your own bot or backend. Configure the URL and shared secret in Misc settings; UnlockHub signs the payload so your receiver can verify it came from your project.

Keep credentials server-side

Never put the API key or webhook secret in browser code. Store both in environment variables and rotate the key if it is exposed.

07 / Distribution

Portal domains

Your gateway link is served from a portal domain, not from the dashboard URL. Links live in Discord messages, descriptions and reuploads, so they have to keep working; keeping them on their own hostnames means a hostname that gets flagged can be replaced without touching the project.

Our pool

Shared hostnames we own. Several gateways can sit behind one (the slug in the path says which), and every project is given one the moment it is created, so you always have a link to share. Some hostnames are kept back for particular uses: they can be chosen by hand but are never handed out automatically, and a restricted one only appears for accounts that are allowed to see it.

Your own domain

Optional, and free: connect a domain you own and your link is served from it. It stays bound to a single project. Add it in the Portal domain section, publish the two records shown (a TXT record proving the domain is yours, and one CNAME, or an A record for a bare domain, pointing it here), then press Check now.

When a domain goes live

A hostname only becomes your link once it answers over https, so a half-configured domain never breaks a link somebody already copied. Until then your links keep using the current host, and the panel says what is still missing.

Keep the path, change the host

Every portal is /g/your-slug on whichever hostname it uses. Change the domain freely: visitors, sessions and earnings are unaffected. A changed slug is a new link, so share it again.

08 / Reporting

Dashboards and platform admin

There are two dashboards on purpose. Yours answers "how are my gateways doing", and the platform one answers "is the platform healthy". A single screen that silently changes meaning depending on who is looking is how numbers get misread. Both report a period against the one before it, so a number is never shown without something to compare it to.

Your dashboard

Earnings, conversions, conversion rate, earnings per conversion, sessions and keys. Each with the change against the previous period, where there is one. All time is the default; 7, 30 and 90 days compare against the period before them. Plot earnings, conversions or sessions on the trend chart, and see which countries the sessions came from and what each one earned.

Platform overview

The same metrics across every account, plus what is waiting on a human: pending payout requests, open contact messages, suspended or banned accounts, and the latest actions from the log.

Sessions

Filterable by project (all projects by default) and status. The account view covers the gateways you own; Admin → All sessions covers every gateway on the site and names its owner.

Admin area

Super admins get an extra Admin block in the sidebar: accounts, all sessions, all projects, payout requests, the ledger, portal domains, the action log and contact replies.

What the numbers leave out

Test sessions are excluded from every figure. They pass through the same pipeline as real traffic, and mixing them into a conversion rate would make the rate meaningless. The dashboard says how many were skipped in the period it is showing.

Account standing: active, suspended, banned

A suspension pauses sign-in until a date you pick (1, 7 or 30 days) and then lifts itself, so nothing has to be remembered and undone. A ban holds until you clear it. Both accept a reason, which is shown to the account at sign-in. An unexplained refusal only creates support tickets. Standing is checked after the password, so it never reveals whether a username exists.

Turning a gateway off

On Dashboard → Projects, each of your gateways has a Disable button next to its status: it asks once, then stops the gateway handing out new sessions and stops your bot or API accepting its keys. A super admin can do the same for any gateway from Admin → All projects. Nothing is deleted. Sessions, keys, rewards and earnings stay exactly as they are, and Enable puts it straight back.

Who sees what

The account screens only ever look at the projects that account owns, for everyone including a super admin: your sessions, your rewards, your payouts, your dashboard. Anything platform-wide is behind the Admin block.