How to Enroll User Using Invitation Code in Authentik
I want to invite users using invitation code instead of the long string of invitation URL provided in Authentik. I can't believe I haven't been able to find a tutorial for this, so here we go.
With this setup you will just have to give the invitation flow URL (not the long one like the default Authentik invitation) with a working code to your user.

Create a new Prompt
- Go to Flow and Stages > Prompts > Create
- Fill the name with invitation-code-prompt
- Fill the field key with invite_code
- You can put whatever label you want
- Set the type to Test: Simple Text Input
- Toggle the Required button
You can change the fields value if you know what you are doing

(Optional) Create New User Creation Prompts
This step is optional, I created new prompts because I want the user creation from invitation to have the fields in specific order. You can use the default prompts with their own fields order.
- Still in the Prompt page, click Create
- Create a new prompt for each Username, Email, Password, and Password (repeat)
- Make sure to fill the Order fields too
| Field | Username | Password | Password (repeat) | |
|---|---|---|---|---|
| Name | invitation-code-username | invitation-code-email | invitation-code-password | invitation-code-password-repeat |
| Field Key | username | password | password_repeat | |
| Label | Username | Password | Password (repeat) | |
| Type | Username... | Email... | Password... | Password... |
| Required | True | True | True | True |
| Order | 0 | 1 | 2 | 3 |
Create a New Invite Code Policy
- Go to Customization > Policies > Create
- Pick Expression Policy
- Fill the name with invite-code-check
- Fill the expression field with the code below, change the allowed dictionary with the invitation codes and their expiry date-time in line 8 and 9, you can have as many codes as you want
from datetime import datetime
from zoneinfo import ZoneInfo
code = (context.get("prompt_data", {}).get("invite_code") or "").strip().upper()
# Dictionary: CODE -> Expiry datetime string
allowed = {
"TESCODEIFEXPIRE": "2025-12-31 23:59:59",
"TESCODEFORTHISYEAR": "2026-12-31 23:59:59",
}
if code not in allowed:
ak_message("Invalid invite code. Dude, are you sure you are invited? Check your code again.")
return False
jakarta = ZoneInfo("Asia/Jakarta")
# Parse expiry time
expiry_str = allowed[code]
expiry = datetime.strptime(expiry_str, "%Y-%m-%d %H:%M:%S").replace(tzinfo=jakarta)
# Check expiration
now = datetime.now(jakarta)
if now > expiry:
ak_message("This invite code has expired. You are too late, go get a new code.")
return False
return True
You can change the code as you need. Don't forget to change the timezone also. As it is the user have to input an active case-sensitive code to pass the check.
You can also change the error messages in line 13 and 25.
Create a New Invite Code Stage
- Go to Flow and Stages > Stages > Create
- Pick Prompt Stage
- Fill the name with invite-code-stage
- Pass the invite-code-check policy to Selected Policies

Create a New Account Creation Stage
- Go to Flow and Stages > Stages > Create
- Pick Prompt Stage
- Fill the name with invitation-create-account
- Pass all the newly created user creation prompts to the stage

(Optional) Create a New Write Stage and Login Stage
- For the write stage, the type is User Write Stage, mine is named invitation-enrollment-user-write-internal with the Always create new user toggled and account type internal
- For the login stage, the type is User Login Stage, mine is named invitation-enrollment-user-login
Create a New Invitation Flow
- Go to Flows and Stages > Flows > Create
- Fill the name and slug invite, that way you'll just have to share short link to your user e.g. http://authentik.company/if/flow/invite/ instead of long invitation string
- Pick the Enrollment designation
- Pick Require no authentication for authentication

- Open the flow and go to the Stage Bindings tab
- Bind existing stage invite-code-stage and fill the order with 10
- Bind existing stage invitation-create-account and fill the order with 20
- Bind existing stage invite-code-stage and fill the order with 20
- Bind existing stage invitation-enrollment-user-write-internal and fill the order with 25
- Bind existing stage invitation-enrollment-user-login and fill the order with 30
- DONE!!
The order number is like that because I want the possibility to insert new stages between. You can use 0,1,2,3 and it will works fine.

Testing Time!
Now you should be able to go to https://authentik.company/if/flow/invite/ or whatever slug you are using.
An invalid code will result in this

An expired code will result in this

And a working code will forward user to account creation page
