---
title: "Create JWT Token"
api: "POST /api/v1/tokens"
description: "Authenticate and obtain a JWT access token."
---
Authenticate with Prowler using email and password credentials to receive JWT tokens for API access. This is the primary authentication method for the Prowler API.
## Use Cases
- **Initial Authentication**: Login to obtain tokens for API access
- **Application Integration**: Authenticate service accounts or automation tools
- **Multi-tenant Access**: Obtain tokens with specific tenant context
- **Session Management**: Create new sessions for web applications
## Request Body
The request follows the JSON:API specification:
```json
{
"data": {
"type": "tokens",
"attributes": {
"email": "user@example.com",
"password": "your-password",
"tenant_id": "optional-tenant-uuid"
}
}
}
```
The `tenant_id` field is optional. If omitted, you'll be authenticated with your first tenant membership. Use `/api/v1/tokens/switch` to change tenants after authentication.
### Attributes
- `email` (required, string, write-only) - User email address registered in Prowler
- `password` (required, string, write-only) - User password
- `tenant_id` (optional, string UUID, write-only) - Specific tenant ID to authenticate with
- If not provided, the first tenant membership will be used
- Use this to specify which organization/tenant to access
## Example Request
```bash
curl -X POST "https://api.prowler.com/api/v1/tokens" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
"type": "tokens",
"attributes": {
"email": "security-team@company.com",
"password": "SecurePassword123!"
}
}
}'
```
## Response
### Success Response (200 OK)
Returns JWT access and refresh tokens:
```json
{
"data": {
"type": "tokens",
"attributes": {
"access": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLWlkIiwiZXhwIjoxNzA2MTg0MDAwfQ...",
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiJ1c2VyLWlkIiwiZXhwIjoxNzA4Nzc2MDAwfQ..."
}
}
}
```
### Response Fields
- `access` (string, read-only) - JWT access token for API authentication
- Use this token in the `Authorization: Bearer ` header for API requests
- Typically valid for a limited time (e.g., 1 hour)
- `refresh` (string, read-only) - JWT refresh token to obtain new access tokens
- Use this token with the `/api/v1/tokens/refresh` endpoint when access token expires
- Typically valid for a longer period (e.g., 30 days)
- Only one refresh token is valid at a time; refreshing invalidates the previous one
### Error Responses
**401 Unauthorized** - Invalid credentials
```json
{
"errors": [
{
"status": "401",
"title": "Authentication Failed",
"detail": "Invalid email or password"
}
]
}
```
**422 Unprocessable Entity** - Missing or invalid fields
```json
{
"errors": [
{
"status": "422",
"title": "Validation Error",
"detail": "Email is required",
"source": {
"pointer": "/data/attributes/email"
}
}
]
}
```
**429 Too Many Requests** - Rate limit exceeded
```json
{
"errors": [
{
"status": "429",
"title": "Rate Limit Exceeded",
"detail": "Too many authentication attempts. Please try again in 15 minutes."
}
]
}
```
## Usage Example
After obtaining tokens, use the `access` token in subsequent API requests:
```bash
# Save the tokens from the response
ACCESS_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # from attributes.access
REFRESH_TOKEN="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." # from attributes.refresh
# Use access token in API requests
curl -X GET "https://api.prowler.com/api/v1/providers" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/vnd.api+json"
# When access token expires, refresh it
curl -X POST "https://api.prowler.com/api/v1/tokens/refresh" \
-H "Content-Type: application/vnd.api+json" \
-d "{\"data\":{\"type\":\"tokens-refresh\",\"attributes\":{\"refresh\":\"$REFRESH_TOKEN\"}}}"
```
## Token Lifecycle
1. **Access Token**: Use for all API requests in the `Authorization` header
- Short-lived (typically 1 hour)
- Included in every API request
2. **Refresh Token**: Use to obtain new access tokens
- Long-lived (typically 30 days)
- Only used with `/api/v1/tokens/refresh` endpoint
- Previous refresh token is invalidated when a new one is issued
3. **Token Refresh Flow**:
```bash
# When access token expires, use refresh token
curl -X POST "https://api.prowler.com/api/v1/tokens/refresh" \
-H "Content-Type: application/vnd.api+json" \
-d '{
"data": {
"type": "tokens-refresh",
"attributes": {
"refresh": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
}
}'
```
4. **Revocation**: Tokens are automatically invalidated on:
- Password change
- Explicit logout
- Security events
**Security Best Practices:**
- Store tokens securely (encrypted storage, environment variables, secure vaults)
- Never commit tokens to version control
- Never log tokens or expose them in error messages
- Use HTTPS for all API communications
- Implement token rotation using refresh tokens
- Revoke tokens when no longer needed
**Rate Limiting:** This endpoint is rate-limited to 5 requests per minute per IP address to prevent brute-force attacks.
For automated systems and CI/CD pipelines, consider using API Keys instead of JWT tokens for more stable, long-lived authentication.