Delegated access to Zev products
Test environments
Try delegated access end to end in your test environment, with your own team's accounts, before ZevID approves your live app.
You can build and test delegated access without ZevID’s approval, in your
test environment (env_test_…, your pk_test_… and sk_test_… keys). It
runs against the real Zev products, so the only thing that is “test” is who
can use it: your own team, and no one else.
Set it up
- Switch the console to your test environment and open Delegated access.
- Under Set up a test app, pick the product and register your first callback. That creates your test app at ZevID straight away, with every permission the product offers to partners.
- Use your
pk_test_…key on authorize and yoursk_test_…key on token and revoke. Everything else is identical.
Test callbacks may use any https host or http://localhost: preview
deployments and local development both work. Your live callbacks must still
be on your verified domain.
Who can use it
Only the people in your ZevAuth workspace, connecting with their own ZevID accounts. We send ZevID your workspace’s members whenever your team changes, and every day, up to 25 people (owners and admins first). Add teammates under Team in the console.
Anyone else who reaches your test environment is stopped on ZevID’s screen (“This is a test version of your app. Only your app’s team can connect it.”) and your callback receives:
?error=access_denied&error_reason=not_a_test_member&state=...
Sign in with ZevID on a test environment works for anyone today. ZevID
can extend the same team-only rule to it; once that is on, someone outside the
team gets error=zevid_not_a_test_member on your sign-in callback. Keeping
your team in ZevAuth up to date means nothing changes for your team when it
happens. Delegated access is team-only from the start.
Removing someone from your workspace ends their test connections at once (and their test sign-ins, once team-only sign-in is on). Their live connections are untouched.
Limits
| Test | Live | |
|---|---|---|
| Who can connect | Your team (up to 25 people) | Anyone with a product account |
| Approval and domain verification | Not needed | Needed, per product |
| Permissions | Every permission the product offers to partners, except any it keeps live-only | What ZevID approved for you |
| High-risk permissions | Work, with the same “Confirm it’s you” | With ZevID’s approval |
| Callbacks | Any https host, or localhost | https on your verified domain |
| Connections | At most 25 at once | No cap |
| How long a connection lasts | Ends on its own after a set number of days, shown in the console and as grant_expires_at | Until it is disconnected |
| Emails to the user | None | Connect, new permissions, removal |
When a test connection ends, refresh fails with invalid_grant, reason
test_grant_expired, and you receive delegated_access.connection.revoked
with the same reason. Reconnect to keep testing. The token response tells you
when in advance, as grant_expires_at.
A product may refuse test apps entirely (test_apps_not_allowed) or keep
some permissions live-only (scope_not_for_test_apps).
Test and live never mix
They are separate apps at ZevID. A teammate’s test connection never counts as
a live one, and never pre-fills live consent. Codes, refresh tokens and
connection ids from one never work with the other (client_mismatch).
Every token response and webhook says which one you are looking at:
| Where | Field |
|---|---|
| Token response | tenant_mode: "test" or "live", and grant_expires_at (test only, otherwise null) |
| Webhooks | data.tenantMode and data.expiresAt |
The ZevID consent screen and the user’s Apps and websites page label your app “Test version”, so nobody mistakes it for the live one.
Going live
Testing is the rehearsal. To take real users, request approval for your live environment: see Getting approved. Then register your live callbacks and switch your keys. No test connection carries over.
Updated at, Wednesday, October 21, 2026