Skip to main content

Authentication

Manage API keys and verify identity.

All auth endpoints support session authentication (browser cookie) with API key fallback. This means you can call these endpoints from the browser (using your Meteor login session) or from scripts and external clients (using a valid API key in the X-API-Key header).


POST /api/v1/auth/api-keys

Create a new API key

Returns the raw key value once — store it securely.

Authentication: Session (browser cookie) or API key

Request Body:

{
"name": "My CI/CD Key",
"scopes": ["apps:read", "apps:deploy", "workflows:execute"],
"expiresInDays": 90
}
FieldTypeRequiredDescription
namestringYesHuman-readable key name (non-empty)
scopesstring[]YesPermission scopes (non-empty array; see Scopes)
expiresInDaysintegerNoDays until expiration. Omit for no expiration

Response: 201 Created

{
"data": {
"id": "67a1b2c3d4e5f6a7b8c9d0e1",
"key": "sk-prod-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
"name": "My CI/CD Key",
"keyPrefix": "sk-prod-a1b2",
"scopes": ["apps:read", "apps:deploy", "workflows:execute"],
"expiresAt": "2025-05-07T00:00:00.000Z",
"createdAt": "2025-02-07T00:00:00.000Z"
},
"meta": { "requestId": "req_abc123" }
}
FieldTypeDescription
idstringMongoDB document ID
keystringThe raw API key (only returned once)
namestringKey name
keyPrefixstringFirst 12 characters of the key
scopesstring[]Assigned permission scopes
expiresAtstring | nullISO-8601 expiration date, or null if no expiration
createdAtstringISO-8601 creation date
warning

The key field is only returned once at creation time. Store it securely — it cannot be retrieved later.


GET /api/v1/auth/api-keys

List API keys for the current user

Authentication: Session (browser cookie) or API key

Parameters:

NameInTypeRequiredDescription
statusquerystringNoFilter by status: active, revoked, expired
limitqueryintegerNoMax results (default: 50, max: 200)
offsetqueryintegerNoPagination offset
sortquerystringNoSort field (default: -createdAt)

Response: 200 OK (paginated)

{
"data": [
{
"_id": "67a1b2c3d4e5f6a7b8c9d0e1",
"keyPrefix": "sk-prod-a1b2",
"name": "My CI/CD Key",
"userId": "user123",
"organizationId": "org-abc",
"scopes": ["apps:read", "apps:deploy"],
"status": "active",
"expiresAt": "2025-05-07T00:00:00.000Z",
"lastUsedAt": "2025-02-06T10:30:00.000Z",
"lastUsedIp": "192.168.1.1",
"createdAt": "2025-02-07T00:00:00.000Z",
"revokedAt": null,
"revokedBy": null,
"metadata": null
}
],
"meta": { "total": 3, "limit": 50, "offset": 0, "hasMore": false, "requestId": "req_abc123" }
}
FieldTypeDescription
_idstringMongoDB document ID
keyPrefixstringFirst 12 characters of the key
namestringKey name
userIdstringOwning user ID
organizationIdstring | nullBound organization
scopesstring[]Permission scopes
statusstringactive, revoked, or expired
expiresAtstring | nullExpiration date
lastUsedAtstring | nullLast request timestamp
lastUsedIpstring | nullLast request IP address
createdAtstringCreation timestamp
revokedAtstring | nullRevocation timestamp (if revoked)
revokedBystring | nullUser who revoked (if revoked)
isDefaultPlatformKeybooleantrue if this is the auto-generated platform key
metadataobject | nullOptional metadata (userAgent, description)

GET /api/v1/auth/api-keys/:id

Get a single API key

Authentication: Session (browser cookie) or API key

Parameters:

NameInTypeRequiredDescription
idpathstringYesAPI key ID (_id from list response)

Response: 200 OK

{
"data": {
"_id": "67a1b2c3d4e5f6a7b8c9d0e1",
"keyPrefix": "sk-prod-a1b2",
"name": "My CI/CD Key",
"userId": "user123",
"organizationId": "org-abc",
"scopes": ["apps:read", "apps:deploy"],
"status": "active",
"expiresAt": "2025-05-07T00:00:00.000Z",
"lastUsedAt": "2025-02-06T10:30:00.000Z",
"lastUsedIp": "192.168.1.1",
"createdAt": "2025-02-07T00:00:00.000Z",
"revokedAt": null,
"revokedBy": null,
"metadata": null
},
"meta": { "requestId": "req_abc123" }
}

Returns the same fields as the list endpoint for a single key.


DELETE /api/v1/auth/api-keys/:id

Revoke an API key

Permanently revokes the key. This cannot be undone. Default Platform Keys cannot be revoked — use rotate instead.

Authentication: Session (browser cookie) or API key

Parameters:

NameInTypeRequiredDescription
idpathstringYesAPI key ID

Response: 204 No Content


POST /api/v1/auth/api-keys/:id/rotate

Rotate an API key

Revokes the old key and creates a new one with the same name, scopes, and expiration. For Default Platform Keys, also updates profile.stronglyApiKey on the user document.

Authentication: Session (browser cookie) or API key

Parameters:

NameInTypeRequiredDescription
idpathstringYesAPI key ID

Response: 201 Created

{
"data": {
"id": "67b2c3d4e5f6a7b8c9d0e1f2",
"key": "sk-prod-q1w2e3r4t5y6u7i8o9p0a1s2d3f4g5h6",
"name": "My CI/CD Key",
"keyPrefix": "sk-prod-q1w2",
"scopes": ["apps:read", "apps:deploy"],
"expiresAt": "2025-05-07T00:00:00.000Z",
"createdAt": "2025-02-08T00:00:00.000Z"
},
"meta": { "requestId": "req_abc123" }
}

Returns the same fields as the create endpoint, including the new raw key.

warning

The new key is only returned once. Store it securely — the old key is immediately revoked and cannot be used.


GET /api/v1/auth/whoami

Get current user and organization info

Authentication: Session (browser cookie) or API key (X-API-Key header)

Response: 200 OK

{
"data": {
"userId": "user_abc123",
"email": "user@example.com",
"name": "John Doe",
"roles": ["admin"],
"organization": {
"id": "org_abc123",
"role": "owner",
"isMultiTenant": true,
"isSolo": false
},
"apiKey": {
"id": "67a1b2c3d4e5f6a7b8c9d0e1",
"name": "My Key",
"keyPrefix": "sk-prod-a1b2",
"scopes": ["apps:read"],
"expiresAt": "2025-05-07T00:00:00.000Z"
}
},
"meta": { "requestId": "req_abc123" }
}

The apiKey field is only present when authenticating with an API key (not session auth). Use this endpoint to verify your API key is working correctly.


Troubleshooting 401 Errors

If you receive a 401 Unauthorized response when using an API key, check the following:

1. Verify the header format

The key must be sent in the X-API-Key header:

curl -H "X-API-Key: sk-prod-your-key-here" \
https://<your-instance>/api/v1/auth/whoami

2. Verify the key prefix

All API keys start with sk-prod-. If your key does not start with this prefix, it is not a valid Strongly API key.

3. Check key status

Your key may have been revoked or expired. List your keys via the UI (Profile > Security > API Keys) or via session auth:

# List keys using session auth (from browser dev tools, copy your meteor_login_token cookie)
curl -b "meteor_login_token=your-session-token" \
https://<your-instance>/api/v1/auth/api-keys?status=active

4. Confirm there are no extra characters

Ensure no whitespace, newlines, or quotes are included in the key value. Copy-paste errors are common.

5. Test with the whoami endpoint

The /api/v1/auth/whoami endpoint is the simplest way to verify your key works:

curl -v -H "X-API-Key: sk-prod-your-key-here" \
https://<your-instance>/api/v1/auth/whoami

A successful response returns your user info and key details. A 401 response means the key is invalid, expired, or revoked.


Default Platform Key

When a new user is created, a Default Platform Key is automatically provisioned with * (wildcard) scopes. This key is:

  • Stored in profile.stronglyApiKey on the user document for workspace injection
  • Visible in the API Keys list with an isDefaultPlatformKey flag
  • Cannot be revoked — use rotate instead to replace it
  • Automatically rotated when you rotate it via the API or UI, keeping profile.stronglyApiKey in sync

Workspaces use this key as their STRONGLY_API_KEY environment variable, so rotating it will require restarting running workspaces to pick up the new key.