Ason supports a few different ways to authenticate, depending on who's calling: a human exploring the API, your backend calling on behalf of your platform, or your own IAM federated directly against Ason.
A User is a person with access to a Tenant - invited by email, with a role that determines what they can see and do. Users are separate from the System User your backend uses for machine-to-machine calls.
How provisioning actually works in practice: create tenants using your System User, not a personal account - that's the supported pattern. To give a person access, invite them (POST .../user_memberships/invite with their email and a role) rather than trying to create a User directly - POST /users exists in the API, but isn't available to a System User token in practice (it returns 403). Accepting the invitation is what actually creates the Ason User and membership; the invitee does that themselves, not you. There's also no way to link one person to several tenants at once - send a separate invitation per tenant, and the invitee accepts each one individually.
Interactive login (human)
The Quickstart and every Playground button on this site log you in interactively - a browser redirect to Ason's identity provider, a human clicking "Login". This is also how a User logs into the Ason frontend (CaseMan) day to day. That's the right flow for exploring the API yourself or for HR staff using CaseMan, but it's the wrong flow for your production backend, which needs to call Ason without a human in the loop - for that, use a System User below.
System User: machine-to-machine via Zitadel
Ason's identity provider is Zitadel. Interactive Users log in through Zitadel's normal OIDC flow, with sessions that refresh automatically like any browser login. Machine-to-machine access works differently: it's not a self-service OAuth2 flow you run yourself.
The flow:
- Ason provisions a system user for your tenant in its Zitadel instance and generates a machine-to-machine access token for it (via the OAuth2
client_credentialsgrant, on the Zitadel side). - Ason sends you that token directly. Your backend never calls Zitadel's token endpoint itself, and you never see a client ID or secret - you just get the resulting token.
- Your backend calls the Ason API with that token as
Authorization: Bearer <token>- the exact same header every interactive-login request uses. From the Ason API's point of view, there's no difference between a system user and a logged-in human; both are just a valid Zitadel access token.
Getting a system user
System users are provisioned by Ason, not self-service through the API - talk to us to get a token issued for your tenant.
Token lifetime
The system user token Ason gives you is permanent - it doesn't expire, so there's no refresh flow to build for it. Store it once (e.g. in your backend's configuration or secrets store) and use it for every request. This is different from interactive User sessions in the Ason frontend, which go through Zitadel's normal OIDC login and refresh automatically.
Should you also create Ason users?
A system user authenticates your backend, not your end users - it doesn't by itself decide what an individual employee or HR admin is allowed to see. Whether you're embedding Ason or running it standalone/white-label, the recommended pattern is the same: your platform's own IAM keeps deciding who can do what, your backend enforces that with its own logic, and it's the backend (authenticated as the system user) that talks to Ason on the user's behalf. You generally don't need to create one Ason user per end user just to make API calls.
Direct IAM Integration
Instead of your backend holding a system user token, your own Identity & Access Management can be connected directly to Ason - Ason's API validates tokens issued by your IAM, not Zitadel's. There's no system-user hop at all: your IAM's token is what the Ason API checks on every request.
Code
Requirements: a dedicated Ason PROD instance in Ason's Azure environment, configured to trust your IAM. This is a deeper integration than the system-user flow above - talk to us to set it up.
Result: a fully integrated authentication setup with centralized user management - Ason users and their permissions are set up directly in your dedicated instance, alongside your own IAM.
Which one should I use?
- Exploring the API, or using CaseMan as a human - interactive login, nothing to set up.
- Your backend calling Ason on behalf of your platform (Embedded Payroll, whether embedded or standalone/white-label) - System User. This is the recommended default for most integrations.
- Your own IAM should be the single source of truth Ason trusts directly (Embedded Payroll) - Direct IAM Integration, on a dedicated instance.
Where this shows up
- Embedded Payroll - the system user and direct IAM integration, for both the embedded and standalone/white-label architectures
- API Reference - every endpoint accepts a system user token exactly like an interactive one
User FAQ
Do I need one Ason user per employee?
No - end users of an embedded integration typically don't need individual Ason users; see "Should you also create Ason users?" above for the recommended pattern.
How do I invite someone to a tenant?
POST .../user_memberships/invite with { email, role } - see API Endpoints below.
Can my System User create a new user directly via POST /users?
Not in practice - it returns 403 for a System User token, even though the endpoint exists in the API. Use the invite flow instead: invite by email, and the person creates their own User by accepting the invitation - you never call POST /users yourself.
Is there a way to attach an existing user to a tenant without sending an invitation?
No - always go through the invite flow (POST .../user_memberships/invite), even for a person who already has an Ason User elsewhere, and it has to be sent per tenant individually.
Can an Owner-level token invite someone as Admin?
No documented role-hierarchy restriction was found on the invite endpoint - Owner and Admin are treated as equivalent for permissions elsewhere in the API, so a System User provisioned at Owner level should be able to invite someone as Admin.
How does someone actually accept an invitation?
Either through the link they're given (in the sandbox: https://sandbox.asonpayroll.com/invitation/{invitationId}), or programmatically via POST /user_membership_invitations/{invitationId} - called with the invitee's own token, not the inviter's.
Can I give one person access to several tenants at once?
No - invite them separately to each tenant, and they have to accept each invitation individually. There's no bulk or shared invite across tenants.
Should tenants be created with a personal user or the System User?
The System User - that's the recommended, supported pattern for anything programmatic.
What's the difference between a User and a System User?
A User is a person with interactive access; a System User is a machine-to-machine credential for your backend.
How does a user actually register/log in?
Through your connected Identity & Access Management provider (IAM/OIDC) - accepting an invitation (POST /user_membership_invitations/{invitationId}) links that IAM account to a tenant. Ason itself doesn't run its own signup/login screen.
Does a user need two-factor authentication?
That's governed entirely by your IAM/OIDC provider (e.g. Zitadel), not by Ason - configure it there if you need it.
Can I change an existing user's name, email or password?
Not through Ason - those belong to your IAM provider. The only thing a user can change in Ason itself is their language/culture setting (PUT /users/{userId}).
How do I remove a user?
DELETE /tenants/{orgId}/user_memberships/{userMembershipId} - this removes their access to the tenant, not their underlying IAM account.
What types of users exist?
Regular Users (interactive, invited by email) and System Users (machine-to-machine, for your backend) - see above.
How does a normal "frontend" user work?
They're invited by email, log in via your IAM/OIDC connection, and see CaseMan scoped to whatever role they were given.
What roles exist for a normal frontend user, and what does each see?
- Administrator - full access to the whole tenant
- Manager - access limited to the specific payrolls they're assigned to
- Self Service - access limited to their own employee record only (linked to a specific Employee), landing directly on their own ESS documents
Can I change a user's role after inviting them?
Yes - PUT /tenants/{orgId}/user_memberships/{userMembershipId} updates the role (and which employee it's linked to, for Self Service).
API Endpoints
| What | Call |
|---|---|
| Get the current user | GET /users |
| Update a user | PUT /users/{userId} |
| Create a user (not usable by a System User token in practice) | POST /users |
| List user memberships (who has access) | GET /tenants/{orgId}/user_memberships |
| List pending invitations | GET /tenants/{orgId}/user_memberships/invitations |
| Update a member's role | PUT /tenants/{orgId}/user_memberships/{userMembershipId} |
| Remove a member | DELETE /tenants/{orgId}/user_memberships/{userMembershipId} |
| Invite a user | POST /tenants/{orgId}/user_memberships/invite |
| Withdraw an invitation | DELETE /tenants/{orgId}/user_memberships/invitations/{invitationId} |
| Get invitation details | GET /user_membership_invitations/{invitationId} |
| Accept an invitation | POST /user_membership_invitations/{invitationId} |
