--- title: "API Keys" description: "Create and manage API keys for users and teams" icon: "key" --- The API Keys app enables your users to generate and manage API keys for programmatic access to your backend services. API keys provide a secure way to authenticate requests, allowing developers to associate API calls with specific users or teams. Stack Auth provides prebuilt UI components for users and teams to manage their own API keys. ## Overview API keys allow your users to access your backend services programmatically without interactive authentication. The flow works as follows: a user or client sends an API request with an API key to your application server. Your server validates the API key with Stack Auth, which returns an authenticated User object. Your server then processes the request and returns the response. Stack Auth provides two types of API keys: ### User API keys User API keys are associated with individual users and allow them to authenticate with your API. ```typescript title="app/components/create-api-key.tsx" "use client"; import { useUser } from "@stackframe/stack"; export default function CreateApiKey() { const user = useUser({ or: 'redirect' }); const handleCreateKey = async () => { const apiKey = await user.createApiKey({ description: "My client application", expiresAt: new Date(Date.now() + (90 * 24 * 60 * 60 * 1000)), // 90 days }); console.log("API Key created:", apiKey.value); }; return ; } ``` ```typescript title="app/components/create-api-key.tsx" import { stackServerApp } from "@/stack/server"; export default async function CreateApiKey() { const user = await stackServerApp.getUser({ or: 'redirect' }); const apiKey = await user.createApiKey({ description: "Admin-provisioned API key", expiresAt: new Date(Date.now() + (30 * 24 * 60 * 60 * 1000)), // 30 days }); return
API Key: {apiKey.value}
; } ```
```typescript title="components/CreateApiKey.tsx" "use client"; import { useUser } from "@stackframe/react"; export default function CreateApiKey() { const user = useUser({ or: 'redirect' }); const handleCreateKey = async () => { const apiKey = await user.createApiKey({ description: "My client application", expiresAt: new Date(Date.now() + (90 * 24 * 60 * 60 * 1000)), // 90 days }); console.log("API Key created:", apiKey.value); }; return ; } ``` ```python title="views.py" import requests from django.http import JsonResponse def create_user_api_key(request): # Get the current user's access token from session/cookie access_token = request.COOKIES.get('stack-access-token') # Create API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/user-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'user_id': 'me', 'description': 'My client application', 'expires_at_millis': int((time.time() + 90 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise Exception(f"Failed to create API key: {response.text}") return JsonResponse(response.json()) ``` ```python title="main.py" import requests import time from fastapi import Cookie, HTTPException @app.post("/api/create-user-api-key") async def create_user_api_key(stack_access_token: str = Cookie(None, alias="stack-access-token")): if not stack_access_token: raise HTTPException(status_code=401, detail="Not authenticated") # Create API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/user-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': stack_access_token, }, json={ 'user_id': 'me', 'description': 'My client application', 'expires_at_millis': int((time.time() + 90 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise HTTPException(status_code=response.status_code, detail=response.text) return response.json() ``` ```python title="app.py" import requests import time from flask import request, jsonify @app.route('/api/create-user-api-key', methods=['POST']) def create_user_api_key(): access_token = request.cookies.get('stack-access-token') if not access_token: return jsonify({'error': 'Not authenticated'}), 401 # Create API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/user-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'user_id': 'me', 'description': 'My client application', 'expires_at_millis': int((time.time() + 90 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: return jsonify({'error': response.text}), response.status_code return jsonify(response.json()) ```
### Team API keys Team API keys are associated with teams and can be used to provide access to team resources over your API. ```typescript title="app/components/create-team-api-key.tsx" "use client"; import { useUser } from "@stackframe/stack"; export default function CreateTeamApiKey({ teamId }: { teamId: string }) { const user = useUser({ or: 'redirect' }); const team = user.useTeam(teamId); const handleCreateKey = async () => { if (!team) return; const teamApiKey = await team.createApiKey({ description: "Team integration service", expiresAt: new Date(Date.now() + (60 * 24 * 60 * 60 * 1000)), // 60 days }); console.log("Team API Key created:", teamApiKey.value); }; return ; } ``` ```typescript title="app/components/create-team-api-key.tsx" import { stackServerApp } from "@/stack/server"; export default async function CreateTeamApiKey({ teamId }: { teamId: string }) { const team = await stackServerApp.getTeam(teamId); if (!team) { return
Team not found
; } const teamApiKey = await team.createApiKey({ description: "Admin-provisioned team API key", expiresAt: new Date(Date.now() + (30 * 24 * 60 * 60 * 1000)), // 30 days }); return
Team API Key: {teamApiKey.value}
; } ```
```typescript title="components/CreateTeamApiKey.tsx" "use client"; import { useUser } from "@stackframe/react"; export default function CreateTeamApiKey({ teamId }: { teamId: string }) { const user = useUser({ or: 'redirect' }); const team = user.useTeam(teamId); const handleCreateKey = async () => { if (!team) return; const teamApiKey = await team.createApiKey({ description: "Team integration service", expiresAt: new Date(Date.now() + (60 * 24 * 60 * 60 * 1000)), // 60 days }); console.log("Team API Key created:", teamApiKey.value); }; return ; } ``` ```python title="views.py" import requests import time from django.http import JsonResponse def create_team_api_key(request, team_id): # Get the current user's access token from session/cookie access_token = request.COOKIES.get('stack-access-token') # Create team API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/team-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'team_id': team_id, 'description': 'Team integration service', 'expires_at_millis': int((time.time() + 60 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise Exception(f"Failed to create team API key: {response.text}") return JsonResponse(response.json()) ``` ```python title="main.py" import requests import time from fastapi import Cookie, HTTPException @app.post("/api/teams/{team_id}/api-keys") async def create_team_api_key(team_id: str, stack_access_token: str = Cookie(None, alias="stack-access-token")): if not stack_access_token: raise HTTPException(status_code=401, detail="Not authenticated") # Create team API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/team-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': stack_access_token, }, json={ 'team_id': team_id, 'description': 'Team integration service', 'expires_at_millis': int((time.time() + 60 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise HTTPException(status_code=response.status_code, detail=response.text) return response.json() ``` ```python title="app.py" import requests import time from flask import request, jsonify @app.route('/api/teams//api-keys', methods=['POST']) def create_team_api_key(team_id): access_token = request.cookies.get('stack-access-token') if not access_token: return jsonify({'error': 'Not authenticated'}), 401 # Create team API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/team-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'team_id': team_id, 'description': 'Team integration service', 'expires_at_millis': int((time.time() + 60 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: return jsonify({'error': response.text}), response.status_code return jsonify(response.json()) ```
## Enabling the API Keys App To use API keys in your application, you need to enable the API Keys app in your Stack Auth dashboard: 1. Navigate to your Stack Auth dashboard 2. Go to the **Apps** section 3. Find and click on **API Keys** in the app store 4. Click the **Enable** button Once enabled, you can configure User API Keys and Team API Keys in the app settings. The app will provide your users with a prebuilt UI to manage their own API keys. ## Prebuilt UI Components Stack Auth provides prebuilt UI components that allow your users to manage their own API keys without any additional code: ### User API Keys UI For frameworks that support React components, the `` component includes an API Keys tab where users can: - View all their active API keys - Create new API keys with custom descriptions and expiration dates - Revoke existing API keys - See when each key was created and when it expires. ```typescript title="app/src/account-page.tsx" import { AccountSettings } from '@stackframe/stack'; export default function MyAccountPage() { return ( ); } ``` ```typescript title="app/src/account-page.tsx" import { AccountSettings } from '@stackframe/react'; export default function MyAccountPage() { return ( ); } ``` ### Team API Keys UI For team API keys, the team settings page automatically includes an API Keys section when: - The API Keys app is enabled - `allowTeamApiKeys` is configured in your project settings - The user has the `$manage_api_keys` permission for the team Users with appropriate permissions can manage team API keys directly from the team settings interface. ## Working with API Keys ### Creating User API Keys ```typescript title="app/components/create-api-key.tsx" "use client"; import { useUser } from "@stackframe/stack"; export default function CreateApiKey() { const user = useUser({ or: 'redirect' }); const handleCreateKey = async () => { const apiKey = await user.createApiKey({ description: "My client application", expiresAt: new Date(Date.now() + (90 * 24 * 60 * 60 * 1000)), // 90 days }); console.log("API Key created:", apiKey.value); }; return ; } ``` ```typescript title="app/components/create-api-key.tsx" import { stackServerApp } from "@/stack/server"; export default async function CreateApiKey() { const user = await stackServerApp.getUser({ or: 'redirect' }); const apiKey = await user.createApiKey({ description: "Admin-provisioned API key", expiresAt: new Date(Date.now() + (30 * 24 * 60 * 60 * 1000)), // 30 days }); return
API Key: {apiKey.value}
; } ```
```typescript title="components/CreateApiKey.tsx" "use client"; import { useUser } from "@stackframe/react"; export default function CreateApiKey() { const user = useUser({ or: 'redirect' }); const handleCreateKey = async () => { const apiKey = await user.createApiKey({ description: "My client application", expiresAt: new Date(Date.now() + (90 * 24 * 60 * 60 * 1000)), // 90 days }); console.log("API Key created:", apiKey.value); }; return ; } ``` ```python title="views.py" import requests from django.http import JsonResponse def create_user_api_key(request): # Get the current user's access token from session/cookie access_token = request.COOKIES.get('stack-access-token') # Create API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/user-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'user_id': 'me', 'description': 'My client application', 'expires_at_millis': int((time.time() + 90 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise Exception(f"Failed to create API key: {response.text}") return JsonResponse(response.json()) ``` ```python title="main.py" import requests import time from fastapi import Cookie, HTTPException @app.post("/api/create-user-api-key") async def create_user_api_key(stack_access_token: str = Cookie(None, alias="stack-access-token")): if not stack_access_token: raise HTTPException(status_code=401, detail="Not authenticated") # Create API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/user-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': stack_access_token, }, json={ 'user_id': 'me', 'description': 'My client application', 'expires_at_millis': int((time.time() + 90 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise HTTPException(status_code=response.status_code, detail=response.text) return response.json() ``` ```python title="app.py" import requests import time from flask import request, jsonify @app.route('/api/create-user-api-key', methods=['POST']) def create_user_api_key(): access_token = request.cookies.get('stack-access-token') if not access_token: return jsonify({'error': 'Not authenticated'}), 401 # Create API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/user-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'user_id': 'me', 'description': 'My client application', 'expires_at_millis': int((time.time() + 90 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: return jsonify({'error': response.text}), response.status_code return jsonify(response.json()) ```
### Creating Team API Keys ```typescript title="app/components/create-team-api-key.tsx" "use client"; import { useUser } from "@stackframe/stack"; export default function CreateTeamApiKey({ teamId }: { teamId: string }) { const user = useUser({ or: 'redirect' }); const team = user.useTeam(teamId); const handleCreateKey = async () => { if (!team) return; const teamApiKey = await team.createApiKey({ description: "Team integration service", expiresAt: new Date(Date.now() + (60 * 24 * 60 * 60 * 1000)), // 60 days }); console.log("Team API Key created:", teamApiKey.value); }; return ; } ``` ```typescript title="app/components/create-team-api-key.tsx" import { stackServerApp } from "@/stack/server"; export default async function CreateTeamApiKey({ teamId }: { teamId: string }) { const team = await stackServerApp.getTeam(teamId); if (!team) { return
Team not found
; } const teamApiKey = await team.createApiKey({ description: "Admin-provisioned team API key", expiresAt: new Date(Date.now() + (30 * 24 * 60 * 60 * 1000)), // 30 days }); return
Team API Key: {teamApiKey.value}
; } ```
```typescript title="components/CreateTeamApiKey.tsx" "use client"; import { useUser } from "@stackframe/react"; export default function CreateTeamApiKey({ teamId }: { teamId: string }) { const user = useUser({ or: 'redirect' }); const team = user.useTeam(teamId); const handleCreateKey = async () => { if (!team) return; const teamApiKey = await team.createApiKey({ description: "Team integration service", expiresAt: new Date(Date.now() + (60 * 24 * 60 * 60 * 1000)), // 60 days }); console.log("Team API Key created:", teamApiKey.value); }; return ; } ``` ```python title="views.py" import requests import time from django.http import JsonResponse def create_team_api_key(request, team_id): # Get the current user's access token from session/cookie access_token = request.COOKIES.get('stack-access-token') # Create team API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/team-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'team_id': team_id, 'description': 'Team integration service', 'expires_at_millis': int((time.time() + 60 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise Exception(f"Failed to create team API key: {response.text}") return JsonResponse(response.json()) ``` ```python title="main.py" import requests import time from fastapi import Cookie, HTTPException @app.post("/api/teams/{team_id}/api-keys") async def create_team_api_key(team_id: str, stack_access_token: str = Cookie(None, alias="stack-access-token")): if not stack_access_token: raise HTTPException(status_code=401, detail="Not authenticated") # Create team API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/team-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': stack_access_token, }, json={ 'team_id': team_id, 'description': 'Team integration service', 'expires_at_millis': int((time.time() + 60 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: raise HTTPException(status_code=response.status_code, detail=response.text) return response.json() ``` ```python title="app.py" import requests import time from flask import request, jsonify @app.route('/api/teams//api-keys', methods=['POST']) def create_team_api_key(team_id): access_token = request.cookies.get('stack-access-token') if not access_token: return jsonify({'error': 'Not authenticated'}), 401 # Create team API key via client API response = requests.post( 'https://api.stack-auth.com/api/v1/team-api-keys', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'team_id': team_id, 'description': 'Team integration service', 'expires_at_millis': int((time.time() + 60 * 24 * 60 * 60) * 1000), } ) if response.status_code != 200: return jsonify({'error': response.text}), response.status_code return jsonify(response.json()) ```
### Listing API Keys ```typescript title="app/components/api-keys-list.tsx" "use client"; import { useUser } from "@stackframe/stack"; export default function ApiKeysList() { const user = useUser({ or: 'redirect' }); const apiKeys = user.useApiKeys(); return (

Your API Keys

{apiKeys.map(key => (

{key.description}

Last 4 digits: {key.value.lastFour}

Created: {key.createdAt.toLocaleDateString()}

))}
); } ```
```typescript title="app/components/api-keys-list.tsx" import { stackServerApp } from "@/stack/server"; export default async function ApiKeysList() { const user = await stackServerApp.getUser({ or: 'redirect' }); const apiKeys = await user.listApiKeys(); return (

Your API Keys

{apiKeys.map(key => (

{key.description}

Last 4 digits: {key.value.lastFour}

Created: {key.createdAt.toLocaleDateString()}

))}
); } ```
```typescript title="components/ApiKeysList.tsx" "use client"; import { useUser } from "@stackframe/react"; export default function ApiKeysList() { const user = useUser({ or: 'redirect' }); const apiKeys = user.useApiKeys(); return (

Your API Keys

{apiKeys.map(key => (

{key.description}

Last 4 digits: {key.value.lastFour}

Created: {key.createdAt.toLocaleDateString()}

))}
); } ```
```python title="views.py" import requests from django.http import JsonResponse def list_user_api_keys(request): # Get the current user's access token from session/cookie access_token = request.COOKIES.get('stack-access-token') # List user's API keys via client API response = requests.get( 'https://api.stack-auth.com/api/v1/user-api-keys?user_id=me', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, } ) if response.status_code != 200: raise Exception(f"Failed to list API keys: {response.text}") return JsonResponse(response.json(), safe=False) ``` ```python title="main.py" import requests from fastapi import Cookie, HTTPException @app.get("/api/user-api-keys") async def list_user_api_keys(stack_access_token: str = Cookie(None, alias="stack-access-token")): if not stack_access_token: raise HTTPException(status_code=401, detail="Not authenticated") # List user's API keys via client API response = requests.get( 'https://api.stack-auth.com/api/v1/user-api-keys?user_id=me', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': stack_access_token, } ) if response.status_code != 200: raise HTTPException(status_code=response.status_code, detail=response.text) return response.json() ``` ```python title="app.py" import requests from flask import request, jsonify @app.route('/api/user-api-keys', methods=['GET']) def list_user_api_keys(): access_token = request.cookies.get('stack-access-token') if not access_token: return jsonify({'error': 'Not authenticated'}), 401 # List user's API keys via client API response = requests.get( 'https://api.stack-auth.com/api/v1/user-api-keys?user_id=me', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, } ) if response.status_code != 200: return jsonify({'error': response.text}), response.status_code return jsonify(response.json()) ```
### Revoking API Keys API keys can be revoked when they are no longer needed or if they have been compromised. ```typescript title="app/components/revoke-api-key.tsx" "use client"; import { useUser } from "@stackframe/stack"; export default function RevokeApiKey({ apiKeyId }: { apiKeyId: string }) { const user = useUser({ or: 'redirect' }); const apiKeys = user.useApiKeys(); const handleRevoke = async () => { const apiKeyToRevoke = apiKeys.find(key => key.id === apiKeyId); if (apiKeyToRevoke) { await apiKeyToRevoke.revoke(); console.log("API Key revoked"); } }; return ; } ``` ```typescript title="lib/api-keys.ts" import { stackServerApp } from "@/stack/server"; export async function revokeApiKey(userId: string, apiKeyId: string) { const user = await stackServerApp.getUser(userId); if (!user) return; const apiKeys = await user.listApiKeys(); const apiKeyToRevoke = apiKeys.find(key => key.id === apiKeyId); if (apiKeyToRevoke) { await apiKeyToRevoke.revoke(); } } ``` ```typescript title="components/RevokeApiKey.tsx" "use client"; import { useUser } from "@stackframe/react"; export default function RevokeApiKey({ apiKeyId }: { apiKeyId: string }) { const user = useUser({ or: 'redirect' }); const apiKeys = user.useApiKeys(); const handleRevoke = async () => { const apiKeyToRevoke = apiKeys.find(key => key.id === apiKeyId); if (apiKeyToRevoke) { await apiKeyToRevoke.revoke(); console.log("API Key revoked"); } }; return ; } ``` ```python title="views.py" import requests from django.http import JsonResponse def revoke_api_key(request, api_key_id): # Get the current user's access token from session/cookie access_token = request.COOKIES.get('stack-access-token') # Revoke API key via client API (update with revoked: true) response = requests.patch( f'https://api.stack-auth.com/api/v1/user-api-keys/{api_key_id}', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'revoked': True, } ) if response.status_code != 200: raise Exception(f"Failed to revoke API key: {response.text}") return JsonResponse({'message': 'API key revoked successfully'}) ``` ```python title="main.py" import requests from fastapi import Cookie, HTTPException @app.delete("/api/user-api-keys/{api_key_id}") async def revoke_api_key(api_key_id: str, stack_access_token: str = Cookie(None, alias="stack-access-token")): if not stack_access_token: raise HTTPException(status_code=401, detail="Not authenticated") # Revoke API key via client API (update with revoked: true) response = requests.patch( f'https://api.stack-auth.com/api/v1/user-api-keys/{api_key_id}', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': stack_access_token, }, json={ 'revoked': True, } ) if response.status_code != 200: raise HTTPException(status_code=response.status_code, detail=response.text) return {"message": "API key revoked successfully"} ``` ```python title="app.py" import requests from flask import request, jsonify @app.route('/api/user-api-keys/', methods=['DELETE']) def revoke_api_key(api_key_id): access_token = request.cookies.get('stack-access-token') if not access_token: return jsonify({'error': 'Not authenticated'}), 401 # Revoke API key via client API (update with revoked: true) response = requests.patch( f'https://api.stack-auth.com/api/v1/user-api-keys/{api_key_id}', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, }, json={ 'revoked': True, } ) if response.status_code != 200: return jsonify({'error': response.text}), response.status_code return jsonify({'message': 'API key revoked successfully'}) ``` ### Checking API Key Validity You can check if an API key is still valid: ```typescript title="app/components/check-api-key.tsx" "use client"; import { useUser } from "@stackframe/stack"; export default function CheckApiKeyValidity({ apiKeyId }: { apiKeyId: string }) { const user = useUser({ or: 'redirect' }); const apiKeys = user.useApiKeys(); const apiKey = apiKeys.find(key => key.id === apiKeyId); if (!apiKey) { return
API key not found
; } if (apiKey.isValid()) { return
API key is valid
; } const reason = apiKey.whyInvalid(); return
API key is invalid: {reason}
; } ```
```typescript title="app/components/check-api-key.tsx" import { stackServerApp } from "@/stack/server"; export default async function CheckApiKeyValidity({ userId, apiKeyId }: { userId: string, apiKeyId: string }) { const user = await stackServerApp.getUser(userId); if (!user) return
User not found
; const apiKeys = await user.listApiKeys(); const apiKey = apiKeys.find(key => key.id === apiKeyId); if (!apiKey) { return
API key not found
; } if (apiKey.isValid()) { return
API key is valid
; } const reason = apiKey.whyInvalid(); return
API key is invalid: {reason}
; } ```
```typescript title="components/CheckApiKey.tsx" "use client"; import { useUser } from "@stackframe/react"; export default function CheckApiKeyValidity({ apiKeyId }: { apiKeyId: string }) { const user = useUser({ or: 'redirect' }); const apiKeys = user.useApiKeys(); const apiKey = apiKeys.find(key => key.id === apiKeyId); if (!apiKey) { return
API key not found
; } if (apiKey.isValid()) { return
API key is valid
; } const reason = apiKey.whyInvalid(); return
API key is invalid: {reason}
; } ```
```python title="views.py" import requests import time from django.http import JsonResponse def check_api_key_validity(request, api_key_id): # Get the current user's access token from session/cookie access_token = request.COOKIES.get('stack-access-token') # Get API key details via client API response = requests.get( f'https://api.stack-auth.com/api/v1/user-api-keys/{api_key_id}', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, } ) if response.status_code != 200: return JsonResponse({'error': 'API key not found'}, status=404) api_key = response.json() # Check if manually revoked if api_key.get('manually_revoked_at_millis'): return JsonResponse({ 'valid': False, 'reason': 'manually-revoked' }) # Check if expired if api_key.get('expires_at_millis'): if api_key['expires_at_millis'] < time.time() * 1000: return JsonResponse({ 'valid': False, 'reason': 'expired' }) return JsonResponse({'valid': True}) ``` ```python title="main.py" import requests import time from fastapi import Cookie, HTTPException @app.get("/api/check-api-key/{api_key_id}") async def check_api_key_validity(api_key_id: str, stack_access_token: str = Cookie(None, alias="stack-access-token")): if not stack_access_token: raise HTTPException(status_code=401, detail="Not authenticated") # Get API key details via client API response = requests.get( f'https://api.stack-auth.com/api/v1/user-api-keys/{api_key_id}', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': stack_access_token, } ) if response.status_code != 200: raise HTTPException(status_code=404, detail="API key not found") api_key = response.json() # Check if manually revoked if api_key.get('manually_revoked_at_millis'): return { 'valid': False, 'reason': 'manually-revoked' } # Check if expired if api_key.get('expires_at_millis'): if api_key['expires_at_millis'] < time.time() * 1000: return { 'valid': False, 'reason': 'expired' } return {'valid': True} ``` ```python title="app.py" import requests import time from flask import request, jsonify @app.route('/api/check-api-key/', methods=['GET']) def check_api_key_validity(api_key_id): access_token = request.cookies.get('stack-access-token') if not access_token: return jsonify({'error': 'Not authenticated'}), 401 # Get API key details via client API response = requests.get( f'https://api.stack-auth.com/api/v1/user-api-keys/{api_key_id}', headers={ 'x-stack-access-type': 'client', 'x-stack-project-id': stack_project_id, 'x-stack-publishable-client-key': stack_publishable_client_key, 'x-stack-access-token': access_token, } ) if response.status_code != 200: return jsonify({'error': 'API key not found'}), 404 api_key = response.json() # Check if manually revoked if api_key.get('manually_revoked_at_millis'): return jsonify({ 'valid': False, 'reason': 'manually-revoked' }) # Check if expired if api_key.get('expires_at_millis'): if api_key['expires_at_millis'] < time.time() * 1000: return jsonify({ 'valid': False, 'reason': 'expired' }) return jsonify({'valid': True}) ```