# Pre-user-registration Action
## 1. Create it
Actions > Library > Build Custom > pre-user-registration trigger:
```
exports.onExecutePreUserRegistration = async (event, api) => {
const blocked = ["tempmail.example", "mailinator.example"];
const domain = event.user.email.split("@")[1].toLowerCase();
if (blocked.includes(domain)) {
api.validation.error("email", "Please sign up with a work email.");
}
api.user.setUserMetadata("signup_source", "web");
api.user.setAppMetadata("tier", "trial");
};
```
## What you can do here
- `api.validation.error(field, message)`: reject the signup with a field-level error shown on Universal Login.
- `api.user.setUserMetadata` / `setAppMetadata`: stamp data on the user before creation. user_metadata is user-editable; app_metadata is admin-only. Put entitlements in app_metadata.
- Read `event.user.email`, `event.connection`, `event.request` for context.
## What you cannot do
- No access tokens exist yet; do not try to set token claims here (that is post-login).
- Heavy network calls slow every signup; keep it fast or move enrichment to post-registration async.
## 2. Deploy and attach
Deploy the Action, then attach it in Actions > Flows > Pre User Registration. Test with the flow runner using a blocked and an allowed email.
## 3. Pair with post-login
Signup policy (this trigger) and login-time enforcement (post-login) are different moments. A domain denylist here plus an app_metadata tier check at login covers both new and existing users.
## Checklist
- Deny messages are human-readable; they render on the signup page.
- Metadata names are consistent with what post-login Actions and your API expect.