API Keys
API keys provide a static credential alternative to OAuth client credentials for server-to-server access. They're appropriate when:
- You need to call a ZewstID-integrated API from a build script, a webhook handler in a third-party platform, or any other context that can't easily complete an OAuth token exchange.
- You want a long-lived credential without an access-token refresh loop.
OAuth Client Credentials is still the recommended path for production-grade machine-to-machine; API keys are best treated as a convenience for internal tooling and integrations that can't manage tokens.
Creating an API key
- Open the developer portal → API Keys → Create API Key.
- Choose:
- Application — the OAuth application this key belongs to (used for usage attribution + audit logging).
- Scopes — the permissions granted. Same scope catalog as service accounts (see Scopes).
- Expiration — optional. Keys can be set to never expire, or to expire on a specific date.
- The generated key is shown once. Copy it into your secrets manager immediately — there's no way to retrieve it again.
Key format
zml_a1B2c3D4e5F6g7H8i9J0k1L2m3N4o5P6q7R8s9T0u1V2w3X4y5Z6 └┬┘ └────────────────────────────────────────────────────┘ │ random secret └─ namespace prefix (zml = "ZewstID Mail Lib", others vary by application)
The 12-character prefix is the public key identifier (logged, used for usage stats, safe to print). The remainder is the secret — treat it the same way as a password.
Using an API key
Send it in the
AuthorizationBearercurl https://api.zewst.email/v1/messages \ -H "Authorization: Bearer zml_a1B2c3D4e5F6..."
The receiving service authenticates the key, looks up its scopes, and checks the requested action against them. Every request increments the
request_countlast_used_atRotation
API keys are designed to be rotated periodically. The recommended pattern:
- Create a new key with the same scopes as the old one.
- Deploy the new key to your application — most platforms accept either of two values during rotation, or you can do a brief overlap window.
- Verify the new key is being used (check in the developer portal).
last_used_at - Revoke the old key.
There's no automatic key rotation — schedule it as part of your security review (every 90 days is a reasonable cadence for production keys; longer is fine for low-traffic tooling).
Revocation
Hit Revoke on the key's row in the developer portal. Revocation is immediate — the next request with that key returns
401 UnauthorizedIf you suspect a key was leaked: revoke first, audit second. Revocation is reversible only by issuing a new key, but a leaked active key is a much bigger problem than a brief outage.
Storage
Treat API keys as you would any secret:
- Store in a secrets manager (AWS Secrets Manager, HashiCorp Vault, GitHub Actions / GitLab CI secrets, Doppler, etc.) — never in source control.
- For local development, use files that are gitignored.
.env - Don't log API keys, even prefixes-only. The first 12 characters are public-safe but logging discipline is hard to enforce — easier to never log them.
- Don't pass keys in URL query strings — they end up in server logs and browser history.
API keys vs. OAuth Client Credentials — which to use
| Choose API keys if… | Choose Client Credentials if… |
|---|---|
| You need a single static credential | You can refresh tokens reliably |
| The caller is a non-programmable integration (Zapier, n8n, a webhook handler in a third-party platform) | The caller is your own production service |
| You want minimal moving parts | You want short-lived credentials with automatic rotation |
| You're prototyping | You're shipping to production |
Both go through the same scope and authorization model. The difference is purely operational.
See also
Was this page helpful?
Let us know how we can improve our documentation