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

# Authentication

> Learn how to authenticate API requests with Meter

# Authentication

Meter uses API keys to authenticate requests. All API requests must include your API key to identify your account and track usage.

## Getting your API key

1. Sign up or log in at [meter.sh](https://meter.sh/login)
2. Navigate to your [dashboard](https://meter.sh/dashboard)
3. Click **Generate API Key**
4. Copy your API key immediately—it will only be shown once

<Warning>
  **Save your API key immediately**. For security, Meter only shows the full API key once during creation. After that, only the prefix (e.g., `sk_live_abc...`) is visible. If you lose your key, you'll need to generate a new one and delete the old one.
</Warning>

## Managing API keys

### Creating a new key

1. Go to your [dashboard](https://meter.sh/dashboard)
2. Click **Generate API Key**
3. Copy the full key (starts with `sk_live_`)
4. Store it securely

### Deleting a key

To revoke an API key:

1. Go to your dashboard
2. Find the key by its prefix (e.g., `sk_live_abc...`)
3. Click **Delete**
4. Confirm deletion

<Note>
  Deleting a key immediately revokes access. Any requests using that key will return `401 Unauthorized`.
</Note>

### Key rotation

Manual rotation is supported:

1. Generate a new API key
2. Update your applications with the new key
3. Verify the new key works
4. Delete the old key from the dashboard

This enables zero-downtime key rotation for production systems.

## API key format

API keys follow this format:

* **Live keys**: `sk_live_` + random characters
* Used for production and development

## Using API keys

### Python SDK

Store your API key in an environment variable:

```bash theme={null}
export METER_API_KEY="sk_live_your_key_here"
```

Initialize the client:

```python theme={null}
from meter_sdk import MeterClient
import os

# Recommended: Load from environment
client = MeterClient(api_key=os.getenv("METER_API_KEY"))

# Alternative: Direct initialization (not recommended for production)
client = MeterClient(api_key="sk_live_your_key_here")
```

### REST API

Include your API key in the `Authorization` header using the Bearer scheme:

```bash theme={null}
curl https://api.meter.sh/api/strategies \
  -H "Authorization: Bearer sk_live_your_key_here" \
  -H "Content-Type: application/json"
```

## Best practices

<CardGroup cols={2}>
  <Card title="Use Environment Variables" icon="shield-halved">
    Store API keys in environment variables, never in code
  </Card>

  <Card title="Rotate Keys Regularly" icon="arrows-rotate">
    Generate new keys periodically and delete old ones
  </Card>

  <Card title="Use Secrets Management" icon="vault">
    Use tools like AWS Secrets Manager or HashiCorp Vault in production
  </Card>

  <Card title="Monitor Usage" icon="chart-line">
    Check your dashboard for unusual API activity
  </Card>
</CardGroup>

## Storing API keys securely

### Development

Use environment variables or a `.env` file (add to `.gitignore`):

```bash .env theme={null}
METER_API_KEY=sk_live_your_key_here
```

Load with python-dotenv:

```python theme={null}
from dotenv import load_dotenv
import os

load_dotenv()
api_key = os.getenv("METER_API_KEY")
```

### Production

<Tabs>
  <Tab title="AWS">
    Use AWS Secrets Manager or Systems Manager Parameter Store:

    ```python theme={null}
    import boto3

    def get_api_key():
        client = boto3.client('secretsmanager', region_name='us-east-1')
        response = client.get_secret_value(SecretId='meter-api-key')
        return response['SecretString']
    ```
  </Tab>

  <Tab title="Docker">
    Pass as an environment variable:

    ```bash theme={null}
    docker run -e METER_API_KEY=sk_live_xxx your-image
    ```

    Or use Docker secrets (Swarm mode):

    ```yaml docker-compose.yml theme={null}
    services:
      app:
        image: your-image
        secrets:
          - meter_api_key

    secrets:
      meter_api_key:
        external: true
    ```
  </Tab>

  <Tab title="Kubernetes">
    Create a secret:

    ```bash theme={null}
    kubectl create secret generic meter-api-key \
      --from-literal=key=sk_live_xxx
    ```

    Mount in your pod:

    ```yaml theme={null}
    env:
      - name: METER_API_KEY
        valueFrom:
          secretKeyRef:
            name: meter-api-key
            key: key
    ```
  </Tab>

  <Tab title="Vercel/Netlify">
    Add to environment variables in your project settings:

    * Vercel: Project Settings → Environment Variables
    * Netlify: Site Settings → Environment Variables
  </Tab>
</Tabs>

## Error responses

### 401 Unauthorized

Your API key is missing or invalid:

```json theme={null}
{
  "detail": "Invalid or missing API key"
}
```

**Solutions:**

* Verify your API key is correct
* Check that you're including the `Authorization` header
* Ensure the key hasn't been deleted from the dashboard

### 403 Forbidden

Your API key doesn't have permission for the requested resource:

```json theme={null}
{
  "detail": "You do not have permission to access this resource"
}
```

**Solutions:**

* Verify you're accessing your own resources
* Check that the resource exists

## Rate limits

Rate limits are based on:

* Requests per minute
* Strategies generated per day
* Jobs executed per hour

Rate limit information is included in response headers.

## Security model

Meter follows security best practices for API key handling:

* **One-time display**: Full keys are shown only once during creation
* **Prefix storage**: Only the key prefix is stored and displayed after creation
* **Hashed storage**: Full keys are hashed using bcrypt before storage
* **Immediate revocation**: Deleted keys are invalidated instantly
* **Per-user isolation**: API keys can only access resources belonging to the authenticated user

## Need help?

Email me at [mckinnon@meter.sh](mailto:mckinnon@meter.sh)
