Authentication
Sign in with ZiloOne for apps, personal tokens for your scripts, keys for servers.
Every request carries a token in the Authorization header, and every token acts as one person.
GET /v1/me HTTP/1.1
Host: api.zilomail.in
Authorization: Bearer <token>Three kinds of token#
| Token | For | Acts as | Made in |
|---|---|---|---|
| Sign in with ZiloOne access token, 1 hour + refresh token | Apps other people use: phone, desktop, web | The person who signs in | Your apps |
Personal tokenzo_pat_…, 7 days to a year | Your own scripts and tools | You | Personal tokens |
Organisation keyzm_live_… | Servers with nobody signed in | The person an admin chose for it | ZiloOne Control › API keys |
No admin approves your app. People allow it themselves on a consent screen, and it can only do what they can do. An organisation can still turn the API off, or allow only its own apps, in Control › API access.
Sign in with ZiloOne#
Standard OAuth 2.0 with OpenID Connect: the authorization code flow with PKCE. Any OAuth library works (AppAuth on Android and iOS, MSAL-style libraries, oidc-client, Authlib, oauth2 crates…). Its settings are all at the discovery address:
https://accounts.zilomail.in/oidc/.well-known/openid-configurationhttps://accounts.zilomail.in/oidchttps://accounts.zilomail.in/oidc/authhttps://accounts.zilomail.in/oidc/tokenhttps://accounts.zilomail.in/oidc/token/revocationhttps://accounts.zilomail.in/oidc/me (or GET /v1/me with an API token)https://api.zilomail.in1. Register your app#
In Your apps › New app: its name, its kind, where people come back after signing in, and the API permissions it needs. You get a client_id (and a secret for web apps with a server).
| Kind | Examples | Secret | Callback address |
|---|---|---|---|
| Mobile or desktop | Kotlin, Swift, React Native, Flutter, C# WPF | No (PKCE) | Your own scheme (com.acme.mail:/callback) or http://127.0.0.1:PORT/callback |
| Single-page | React, Vue, Angular in the browser | No (PKCE) | https://app.example.com/callback |
| Web with a server | Node, Django, Laravel, ASP.NET, Spring | Yes | https://app.example.com/auth/callback |
2. Send the person to sign in#
Ask for openid and the API permissions you need. Always send a PKCE challenge and a random state. Apps with API permissions get a refresh token with every sign-in (asking for offline_access is fine, not needed).
https://accounts.zilomail.in/oidc/auth
?client_id=zo_app_…
&response_type=code
&redirect_uri=com.acme.mail:/callback
&scope=openid email profile mail.read mail.write mail.send
&state=af0ifjsldkj
&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
&code_challenge_method=S256They sign in (two-step if they use it), see what your app asks for, and allow it. The browser comes back to your callback with code and state.
3. Swap the code for tokens#
curl -X POST https://accounts.zilomail.in/oidc/token \
-d grant_type=authorization_code \
-d code=$CODE \
-d redirect_uri=com.acme.mail:/callback \
-d client_id=zo_app_… \
-d code_verifier=$VERIFIER{
"access_token": "Wq7f…",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "Ux9b…",
"scope": "openid email profile mail.read mail.write mail.send",
"id_token": "eyJhbGciOiJFUzI1NiIs…"
}4. Call the API#
curl https://api.zilomail.in/v1/mail/folders -H "Authorization: Bearer $ACCESS_TOKEN"5. Refresh when it expires#
Access tokens last an hour; a 401 with token_expired says it's time. Swap the refresh token for new ones. Every refresh gives a new refresh token: keep the new one. Using an old refresh token again ends the whole connection (that's how a stolen copy is caught), and the person has to sign in again.
curl -X POST https://accounts.zilomail.in/oidc/token \
-d grant_type=refresh_token \
-d refresh_token=$REFRESH_TOKEN \
-d client_id=zo_app_…A refresh token unused for 60 days expires. The connection outlives the person's browser session (signing out of ZiloOne doesn't end it); it ends when they remove the app, their organisation switches the API off, or they leave. Store tokens in the platform's secure storage (Android Keystore, iOS Keychain, Windows DPAPI), never in plain files.
Signing out#
Revoke the refresh token at https://accounts.zilomail.in/oidc/token/revocation (token=…&client_id=…). The person can also remove your app any time in their account (Security › Connected apps): its tokens stop at once.
Personal tokens and organisation keys#
Both go in the same header and act as one person. Personal tokens are yours, made at Personal tokens with the permissions you pick and an expiry. Organisation keys are made by an admin in Control for servers; each acts as the person the admin chose and can be limited to some IP addresses. Both stop working if that person is turned off.
Never put a personal token or organisation key in an app you give to other people. Apps for others use Sign in with ZiloOne.