Appearance
API Keys
API keys authenticate programmatic access to the Flowstate REST API. Each key carries its own set of permissions so you can grant exactly the access each integration needs, and nothing more.
Overview
Flowstate uses a structured key format that supports efficient lookup and secure validation without exposing the full secret in logs, the UI, or database records.
Key Format
private_{identifier}_{secret}| Segment | Description |
|---|---|
private_ | Fixed prefix indicating this is a secret API key |
{identifier} | 32-character hexadecimal ID used for O(1) key lookup (no full-table scan needed) |
{secret} | Cryptographically random 64-character hexadecimal string, SHA-256 hashed before storage |
Example (secret abbreviated):
private_a1b2c3d4e5f60718293a4b5c6d7e8f90_7c9e2f48...d1a0b3c5The full key is shown only once at creation time. Flowstate stores a key prefix (e.g., private_a1b2c3d4e5f6...) for display purposes in the UI, alongside the hashed secret. The raw secret is never persisted.
DANGER
Copy your API key immediately after creation. Flowstate cannot retrieve or display the full key again. If you lose the key, you must revoke it and create a new one.
Creating API Keys
- Navigate to Settings → Users & Access → API Keys
- Click Create API Key
- Enter a descriptive name (e.g., "Workday Sync", "BI Dashboard", "CI Pipeline")
- Choose an expiry and select the permissions the key needs
- Click Create
- Copy the key immediately -- it is shown only once
Creating API keys requires the SETTINGS_API_KEYS_CREATE permission.
Permissions
API keys use the same permission set as roles. When you create a key, you select the specific permissions it should hold from a checklist grouped by category (Team Plan, Roadmap, Financial Detail, Settings, and so on). Every request made with the key is authorised against those granted permissions.
For example, a key that only reads employee data needs TEAM_EMPLOYEES_VIEW. A sync integration that also updates employees needs TEAM_EMPLOYEES_UPDATE as well.
TIP
Follow the principle of least privilege. Grant only the permissions your integration actually uses. A reporting dashboard needs view permissions only. A sync integration needs create/update permissions for the entities it pushes, but probably nothing else.
Key Lifecycle
API keys have a defined lifecycle from creation through expiration or revocation.
Expiration
You choose an expiry when you create the key (7, 30, 60, or 90 days). The maximum lifetime is 90 days from creation. The expiry is set at creation time and cannot be extended. When a key expires, all requests using that key return 401 Unauthorized.
Activity Tracking
Flowstate records the lastUsedAt timestamp each time a key is used to authenticate a request. Monitor this field to identify unused keys that should be revoked.
Revocation
Keys can be revoked at any time from Settings → Users & Access → API Keys. When a key is revoked:
- The
revokedAttimestamp is recorded - Revocation is immediate -- all subsequent requests with that key return
401 Unauthorized - Revocation cannot be undone; you must create a new key if access is still needed
Revoking keys requires the SETTINGS_API_KEYS_DELETE permission.
Lifecycle States
| State | expiresAt | revokedAt | Accepts Requests |
|---|---|---|---|
| Active | Future date | null | Yes |
| Expired | Past date | null | No |
| Revoked | Any | Set | No |
Key Rotation
Rotate keys on a regular schedule to limit the blast radius of a compromised key. The recommended process ensures zero downtime:
- Create a new key with the same permissions as the existing key
- Update your integration to use the new key
- Verify the integration works by confirming successful API calls
- Revoke the old key once you have confirmed the new key is in use
WARNING
Always create the new key and update your integration before revoking the old key. If you revoke first, your integration will break until you configure the replacement.
Authentication
API keys are passed in the Authorization header using the Bearer scheme:
bash
curl -X GET "https://{tenant}.flowstate.inc/api/v1/org/{orgId}/employees" \
-H "Authorization: Bearer private_a1b2c3d4e5f60718293a4b5c6d7e8f90_7c9e2f48...d1a0b3c5"The authentication middleware validates the key by:
- Extracting the
{identifier}segment for O(1) key lookup - Hashing the key with SHA-256 and comparing against the stored hash
- Checking that the key is not expired (
expiresAt) or revoked (revokedAt) - Verifying the requested endpoint against the key's granted permissions
See the API Authentication guide for detailed usage examples and error response formats.
Managing Keys
Required Permissions
| Action | Permission |
|---|---|
| View keys | SETTINGS_API_KEYS_VIEW |
| Create keys | SETTINGS_API_KEYS_CREATE |
| Revoke keys | SETTINGS_API_KEYS_DELETE |
Viewing Keys
Navigate to Settings → Users & Access → API Keys to see all keys for your organization. The list shows:
- Key name and description
- Key prefix (e.g.,
private_a1b2c3d4e5f6...) for identification - Granted permissions
- Creation date and expiration date
- Last used timestamp
- Status (active, expired, or revoked)
Error Responses
| HTTP Status | Code | Meaning |
|---|---|---|
401 | UNAUTHORIZED | Missing, invalid, expired, or revoked API key |
403 | FORBIDDEN | Valid key but insufficient permissions |
json
{
"error": {
"code": "UNAUTHORIZED",
"message": "Invalid or expired API key.",
"errorId": "err_abc123"
}
}json
{
"error": {
"code": "FORBIDDEN",
"message": "API key does not have the required permission: team_employees_update",
"errorId": "err_def456"
}
}Security Best Practices
- Store keys in a secrets manager -- Use environment variables or a dedicated secrets manager (AWS Secrets Manager, HashiCorp Vault, Google Secret Manager, Azure Key Vault). Never hardcode keys in source code.
- Use separate keys per integration -- If three systems connect to Flowstate, create three separate keys. This way you can revoke one without disrupting the others, and you get per-integration usage tracking.
- Grant minimal permissions -- Only assign the permissions your integration actually needs. A read-only reporting tool should not have create, update, or delete permissions.
- Rotate every 30-60 days -- Do not wait for the maximum 90-day expiration. Proactive rotation limits the window of exposure if a key is compromised.
- Monitor usage via
lastUsedAt-- Periodically review your keys in Settings → Users & Access → API Keys. If a key has not been used recently, consider whether it is still needed. - Never commit keys to source control -- Use
.envfiles (excluded from version control) or CI/CD secrets. If a key is accidentally committed, revoke it immediately and rotate. - Restrict network access -- If your integration runs from known IP addresses, layer network-level controls (VPN, IP allowlisting) on top of API key authentication for defense in depth.
Related Pages
- API Authentication -- API key format, request examples, and error handling
- Roles & Permissions -- The permission model API keys draw from
- Activity Log -- Review changes made through the API
- SIEM Integration -- Stream API key events to your security monitoring platform