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

# Authentication

> Get your API key and start tracking events

## Get Your API Key

Authentication with Surfa is simple - you just need an API key.

<Steps>
  <Step title="Sign up">
    Create a free account at [surfa.dev](https://surfa.dev)
  </Step>

  <Step title="Access your dashboard">
    Go to your [dashboard](https://surfa-web.vercel.app/dashboard)
  </Step>

  <Step title="Create an API key">
    Navigate to **Settings → API Keys** and click **"Create New Key"**
  </Step>

  <Step title="Copy your key">
    Your key will start with `sk_live_` - copy it and store it securely
  </Step>
</Steps>

<Check>
  **Success!** You now have your API key. Keep it secure and never commit it to Git.
</Check>

## Using Your API Key

<Note>
  **Building your own integration?** See the [API Reference](/api-reference) for endpoint details, payload schemas, and request/response examples.
</Note>

### For SDK (Tracking Events)

Use your API key when initializing the Surfa SDK:

```python theme={null}
from surfa_ingest import SurfaClient
import os

analytics = SurfaClient(
    ingest_key=os.getenv("SURFA_INGEST_KEY"),
    api_url=os.getenv("SURFA_API_URL", "https://surfa-web.vercel.app")
)
```

**Set as environment variable:**

```bash theme={null}
export SURFA_INGEST_KEY=sk_live_your_key_here
export SURFA_API_URL=https://surfa-web.vercel.app
```

Or add to your `.env` file:

```bash theme={null}
SURFA_INGEST_KEY=sk_live_your_key_here
SURFA_API_URL=https://surfa-web.vercel.app
```

### For MCP Server (Querying Analytics)

Add your API key to Claude Desktop config:

**macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`

```json theme={null}
{
  "mcpServers": {
    "surfa": {
      "command": "/path/to/uv",
      "args": ["--directory", "/path/to/surfa-mcp", "run", "surfa-mcp"],
      "env": {
        "SURFA_API_KEY": "sk_live_your_key_here",
        "SURFA_API_URL": "https://surfa-web.vercel.app"
      }
    }
  }
}
```

## API Key Types

Surfa uses different key prefixes for different environments:

| Prefix     | Environment | Use Case                          |
| ---------- | ----------- | --------------------------------- |
| `sk_live_` | Production  | Live data, production MCP servers |
| `sk_test_` | Testing     | Development and testing           |

<Note>
  Test keys are isolated from production data. Use them for development and CI/CD.
</Note>

## Security Best Practices

<AccordionGroup>
  <Accordion title="Never commit keys to Git" icon="github">
    **Bad:**

    ```python theme={null}
    # ❌ Don't do this!
    analytics = SurfaClient(ingest_key="sk_live_abc123...")
    ```

    **Good:**

    ```python theme={null}
    # ✅ Use environment variables
    analytics = SurfaClient(ingest_key=os.getenv("SURFA_INGEST_KEY"))
    ```

    Add `.env` to your `.gitignore`:

    ```
    .env
    .env.local
    ```
  </Accordion>

  <Accordion title="Use environment variables" icon="terminal">
    Store keys in environment variables, not in code:

    **Development:**

    ```bash theme={null}
    # .env file
    SURFA_INGEST_KEY=sk_live_your_key
    ```

    **Production:**
    Set environment variables in your deployment platform:

    * Vercel: Settings → Environment Variables
    * Railway: Variables tab
    * Fly.io: `fly secrets set SURFA_INGEST_KEY=...`
  </Accordion>

  <Accordion title="Rotate keys regularly" icon="rotate">
    Rotate your API keys periodically for security:

    1. Create a new key in dashboard
    2. Update environment variables
    3. Deploy changes
    4. Delete old key

    <Tip>
      Keep the old key active for 24 hours during rotation to avoid downtime.
    </Tip>
  </Accordion>

  <Accordion title="Use separate keys per environment" icon="layer-group">
    Use different keys for different environments:

    * **Production:** `sk_live_prod_abc123`
    * **Staging:** `sk_live_staging_xyz789`
    * **Development:** `sk_test_dev_123456`

    This isolates data and makes it easier to track issues.
  </Accordion>
</AccordionGroup>

## Workspace Isolation

Each API key is tied to a specific workspace. This means:

* ✅ **Data isolation** - You only see your workspace's data
* ✅ **Multi-tenant safe** - No cross-workspace leakage
* ✅ **Team collaboration** - Share workspace access with team members

<Info>
  Want to track multiple projects? Create separate workspaces in your dashboard.
</Info>

## Troubleshooting

<AccordionGroup>
  <Accordion title="'Invalid API key' error" icon="circle-exclamation">
    **Possible causes:**

    1. Key is incorrect or has typos
    2. Key was deleted from dashboard
    3. Using test key in production (or vice versa)

    **Solution:**

    * Verify key in dashboard
    * Check environment variables are set correctly
    * Ensure no extra spaces or quotes
  </Accordion>

  <Accordion title="'Unauthorized' error" icon="circle-exclamation">
    **Possible causes:**

    1. API key not included in request
    2. Environment variable not set
    3. Key expired or revoked

    **Solution:**

    ```python theme={null}
    # Verify key is loaded
    import os
    print(os.getenv("SURFA_INGEST_KEY"))  # Should print your key
    ```
  </Accordion>

  <Accordion title="Events not appearing in dashboard" icon="circle-exclamation">
    **Check:**

    1. API key is correct
    2. API URL is correct (`https://surfa-web.vercel.app`)
    3. No firewall blocking outbound requests
    4. Events are being tracked (check logs)

    **Debug:**

    ```python theme={null}
    import logging
    logging.basicConfig(level=logging.DEBUG)

    # You'll see API requests in logs
    analytics.track({...})
    ```
  </Accordion>
</AccordionGroup>

## Rate Limits

The Ingest API is rate limited to prevent abuse:

* **1,000 events per minute** per API key
* **60 second sliding window**

<Warning>
  If you exceed the rate limit, requests will return `429 Too Many Requests`. The SDK automatically retries with exponential backoff.
</Warning>

<Info>
  The MCP Query API (for Claude Desktop) currently has no rate limits.
</Info>

## Next Steps

<CardGroup cols={2}>
  <Card title="Quickstart Guide" icon="rocket" href="/quickstart">
    Start tracking events in 5 minutes
  </Card>

  <Card title="API Reference" icon="book" href="/api-reference">
    Complete API documentation with examples
  </Card>

  <Card title="Privacy & PII" icon="shield" href="/privacy-and-pii">
    Learn what data Surfa tracks
  </Card>

  <Card title="MCP Server Setup" icon="sparkles" href="/claude-desktop-setup">
    Query analytics with Claude Desktop
  </Card>
</CardGroup>
