The NimbusOS REST API supports two authentication schemes: short-lived JWT tokens for user-facing applications and long-lived API keys for server-to-server integrations. Both authenticate to a specific workspace and respect the same tenant isolation rules as the web app. This article covers token acquisition, the refresh flow, API key management, scope rules, and the common mistakes developers hit when integrating.
The Two Schemes
JWT tokens. Short-lived (60 minutes by default), refresh-token backed. Used when a human user is logged in and the app is acting on their behalf. Web UI and mobile apps use this.
API keys. Long-lived. Used for server-to-server integrations, automation scripts, and programmatic pipelines. Revocable per key.
Both return the same API surface. The difference is the lifecycle and the identity the request represents.
JWT Tokens
A JWT authenticates a user session. The token contains:
user_idworkspace_idemailissued_atexpires_atscopes(optional, defaults to user's full workspace permissions)
Obtaining a JWT
POST /api/v1/auth/login/
Content-Type: application/json
{
"email": "user@example.com",
"password": "..."
}
The response includes access_token, refresh_token, and expiration metadata.
Using a JWT
Include in the Authorization header:
Authorization: Bearer <access_token>
Every request is authenticated and authorized. Authentication decodes the JWT and loads the user. Authorization checks that the user has access to the requested resource within their workspace.
Refreshing a JWT
Access tokens expire. When they expire, use the refresh token:
POST /api/v1/auth/refresh/
Content-Type: application/json
{
"refresh_token": "..."
}
The response contains a new access token and, in some configurations, a new refresh token (token rotation).
Refresh tokens expire after 30 days of inactivity. Users re-authenticate after that.
Revoking a JWT
POST /api/v1/auth/logout/
Authorization: Bearer <access_token>
Revokes the specific token. The user's other active sessions continue.
Revoke all sessions:
POST /api/v1/auth/logout-all/
Authorization: Bearer <access_token>
Useful when a user suspects credential compromise.
API Keys
API keys authenticate a specific workspace for programmatic access.
Creating an API key
Go to Account Settings -> API Keys. Click Create Key. Configure:
- Name. Descriptive (e.g., "Zapier integration", "Custom data pipeline").
- Scopes. Which operations the key can perform.
- Expiration. Optional. Default: never expires. Best practice: rotate annually.
On save, the full key is shown once. Copy it immediately; it is never shown again. Only the first 8 characters are stored for identification purposes.
Using an API key
Same header as JWT:
Authorization: Bearer <api_key>
API keys are prefixed nmbapi_ so they are easy to recognize in logs and configuration files. Never commit API keys to source control. Use a secrets manager.
Revoking an API key
From API Keys settings, click Revoke next to the key. Revocation is immediate; existing sessions using the key fail with 401.
Rotating an API key
Create a new key. Update your integration to use it. Revoke the old key.
For rolling rotation without downtime, keep both keys active briefly, deploy the new key, then revoke the old. The platform supports multiple keys per workspace precisely for this pattern.
Scopes
API keys support scope restrictions. Scopes limit what the key can do.
Common scopes:
contacts:readandcontacts:writecampaigns:readandcampaigns:writesequences:readandsequences:writesends:readwebhooks:readandwebhooks:writeadmin:*(everything, admin-only)
A key without explicit scopes has the full permissions of an admin user in the workspace. Best practice is to create scope-limited keys for each integration.
Scopes are enforced per endpoint. A key with only contacts:read receives 403 on POST /api/v1/contacts/.
Workspace Resolution
Every authenticated request resolves to a workspace. Three ways the workspace is determined:
From the JWT or API key. The token is issued for a specific workspace; the request implicitly scopes to that workspace.
From the header X-Workspace-Id. If the user or API key has access to multiple workspaces, this header picks one.
From the resource URL. Some endpoints include the workspace in the URL path (/api/v1/workspaces/:id/contacts). The URL wins over the header or token.
The WorkspaceSecurityMiddleware enforces that the resolved workspace matches the user's access. Mismatches return 403.
Rate Limiting
Authenticated requests are subject to rate limits. Defaults:
- User JWT: 120 requests per minute per user
- API key: 600 requests per minute per key
- Enterprise tier: configurable
Rate limits are returned in response headers:
X-RateLimit-LimitX-RateLimit-RemainingX-RateLimit-Reset
Exceeding the limit returns 429. The Retry-After header indicates when to retry.
CORS
The API allows CORS from the configured frontend domain. External JavaScript apps that need direct access require CORS configuration on your workspace, which is enterprise-tier.
For non-browser server applications (Python, Node, Go), CORS does not apply.
Two-Factor Authentication
Enable 2FA in Account Settings. Supported methods:
- TOTP (authenticator apps)
- WebAuthn (security keys)
- Backup codes
2FA applies to user authentication, not to API keys. API keys are not 2FA-protected because they are server-to-server credentials managed as secrets.
Single Sign-On
SSO is available on enterprise. Supported providers:
- Okta (SAML 2.0)
- Azure AD (SAML 2.0 or OIDC)
- Google Workspace
- Generic SAML 2.0
With SSO, users log in through the identity provider. JWT issuance happens after SSO authentication. API key creation is still self-service within the workspace.
Webhooks Authentication
Webhooks use HMAC signatures, not JWT or API keys. See the Webhooks article for the signing and verification flow.
Common Integration Patterns
Pattern 1: Zapier or similar no-code integration
Create an API key scoped to the specific operations Zapier needs. Paste into Zapier's NimbusOS connector. Rotate annually.
Pattern 2: Custom server-side integration
Create a workspace-level API key. Store in your secrets manager (AWS Secrets Manager, HashiCorp Vault). Reference from code; never commit.
Pattern 3: Multi-workspace agency integration
If you manage multiple NimbusOS workspaces on the same instance, create one API key per workspace. Store each separately. Integration routes to the right key based on the target workspace.
Pattern 4: User-facing app using JWT
Your app obtains a JWT by proxying the user's login through NimbusOS. Store the tokens client-side with appropriate protections (httpOnly cookie for web, secure storage for mobile). Refresh before expiry.
Troubleshooting
"401 Unauthorized on every request"
Token is wrong, expired, or revoked. Regenerate.
"403 Forbidden on specific endpoints"
Scope limitation. Check which scopes the API key has. Create a new key with the needed scopes.
"JWT works in my browser but not in curl"
Missing Authorization header in curl, or copied the token with trailing whitespace. Verify with a simple GET request to /api/v1/auth/me/.
"429 Too Many Requests under normal load"
Either the rate limit is lower than your usage or multiple integrations share the same key. Split into separate keys for each integration.
Frequently Asked Questions
Can I use an API key from the browser?
Technically yes, practically no. Browser-exposed API keys leak to anyone inspecting network traffic. Use JWT for browser authentication. API keys belong on servers.
Does NimbusOS support OAuth for third-party apps?
Partial support. OAuth-style consent flows exist for enterprise integrations but are not open to self-service third-party developers. Contact sales for OAuth app registration.
How do I audit API key usage?
API Keys settings shows last-used timestamp and request count per key. The full audit log is available in enterprise tier.
Can I restrict an API key to a specific IP range?
Yes, in the API key configuration. Enter CIDR blocks. Requests from outside the range are rejected with 403.
What to Read Next
Useful next pages after this one: Contacts API for the contact CRUD endpoints, Rate Limits for detailed rate limit behavior, and Webhooks API for managing webhooks via API.