> ## Documentation Index
> Fetch the complete documentation index at: https://docs.finscreener.in/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> Learn how to authenticate with the Finscreener API

## Overview

The Finscreener API uses a two-step authentication process:

1. **API Key Exchange**: Exchange your API key for JWT tokens
2. **Bearer Token**: Use the JWT access token for all subsequent API calls

<Note>
  API keys start with `fsk_` and can be obtained from your [User Profile → Security](https://finscreener.in/user-profile?tab=Security) settings.
</Note>

## Authentication Flow

```mermaid theme={null}
sequenceDiagram
    participant Client
    participant Finscreener API

    Client->>Finscreener API: POST /api/auth/login (API Key)
    Finscreener API-->>Client: access_token + refresh_token
    Client->>Finscreener API: API Request (Bearer access_token)
    Finscreener API-->>Client: Response
    Note over Client: When access_token expires...
    Client->>Finscreener API: POST /api/auth/refresh-token
    Finscreener API-->>Client: New access_token
```

## Step 1: Login with API Key

Exchange your API key for JWT tokens:

```bash theme={null}
curl -X POST https://api.finscreener.in/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"api_key": "fsk_your_api_key_here"}'
```

**Response:**

```json theme={null}
{
  "success": true,
  "message": "Login successful",
  "user": {
    "name": "John Doe",
    "userId": "usr_1e6f3517748c4923b90e1f3422967661c"
  },
  "token": {
    "access_token": "eyJhbGciOiJIUzI1NiIs...",
    "refresh_token": "eyJhbGciOiJIUzI1NiIs...",
    "token_type": "bearer"
  }
}
```

<Warning>
  The `access_token` expires after approximately 1 hour. Store the `refresh_token` securely to obtain new access tokens.
</Warning>

## Step 2: Use Bearer Token

Include the access token in all API requests:

```bash theme={null}
curl https://api.finscreener.in/api/users/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIs..."
```

## Step 3: Refresh Access Token

When your access token expires, use the refresh token to get a new one:

```bash theme={null}
curl -X POST https://api.finscreener.in/api/auth/refresh-token \
  -H "Content-Type: application/json" \
  -d '{"refresh_token": "eyJhbGciOiJIUzI1NiIs..."}'
```

## Error Handling

| Status Code | Error             | Description                                  |
| ----------- | ----------------- | -------------------------------------------- |
| 400         | Bad Request       | Invalid request body or missing API key      |
| 401         | Unauthorized      | Invalid or expired token                     |
| 403         | Forbidden         | Token not authorized for developer API       |
| 403         | Account Suspended | Account has been suspended — contact support |
| 429         | Rate Limited      | Too many login attempts — wait and retry     |

## Best Practices

<AccordionGroup>
  <Accordion title="Secure Storage">
    * Store API keys in environment variables, not in code
    * Never commit API keys to version control
    * Use secret management services in production
  </Accordion>

  <Accordion title="Token Management">
    * Cache the access token and reuse until expiration
    * Implement automatic token refresh before expiration
    * Store refresh tokens securely (encrypted at rest)
  </Accordion>

  <Accordion title="Error Handling">
    * Handle 401 errors by refreshing the token
    * Implement exponential backoff for rate limit errors (429)
    * Log authentication failures for debugging
  </Accordion>
</AccordionGroup>
