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

# Authentication

> Admin API keys, bearer token auth, and public vs protected endpoint access.

## Overview

The High IQ API uses a tiered authentication model. Most strain data endpoints are **publicly accessible** with no authentication required. Protected endpoints use either an **`X-Admin-Key` header** (for administrative operations) or **`Authorization: Bearer` tokens** (for internal cron jobs and pipeline triggers).

## Authentication Tiers

| Tier         | Header                            | Use Case                     | Example Endpoints                     |
| ------------ | --------------------------------- | ---------------------------- | ------------------------------------- |
| **Public**   | None                              | Strain data, search, catalog | `GET /strains`, `GET /strains/search` |
| **Admin**    | `X-Admin-Key: <key>`              | Administrative operations    | `POST /blog/generate-image`           |
| **Internal** | `Authorization: Bearer <api_key>` | Cron jobs, pipelines         | `GET /cron/*`, `POST /admin/trigger`  |

## Public Endpoints

The majority of API endpoints are public and require no authentication. These include all strain data retrieval, search, filtering, and catalog operations.

```bash theme={null}
# No authentication needed
curl "https://api.thisiswhyimhigh.com/api/v1/strains/slug/blue-dream/complete"

curl "https://api.thisiswhyimhigh.com/api/v1/strains/search?q=sour+diesel"

curl "https://api.thisiswhyimhigh.com/api/v1/strains/popular"
```

## User Authentication

<Note>
  User authentication in High IQ is handled through **Clerk + Convex**, not through the Hono API. The mobile app authenticates users via Clerk SSO (Apple or Google sign-in), and Clerk provides identity tokens that are validated by Convex for real-time user data operations. The Hono API does not validate Clerk JWTs — it serves strain data publicly and protects admin/internal endpoints with API keys.
</Note>

## Admin Authentication

Administrative endpoints are protected by the `X-Admin-Key` header. This is used for operations like blog image generation, batch processing, and other privileged actions.

```bash theme={null}
curl -X POST "https://api.thisiswhyimhigh.com/api/v1/blog/generate-image" \
  -H "Content-Type: application/json" \
  -H "X-Admin-Key: your-admin-api-key" \
  -d '{"slug": "best-terpenes-for-sleep"}'
```

### Security Features

The admin authentication middleware uses **constant-time string comparison** to prevent timing attacks. This ensures that an attacker cannot determine partial key matches by measuring response times.

```typescript theme={null}
// Constant-time comparison prevents timing oracle attacks
function secureCompare(a: string, b: string): boolean {
  const maxLength = Math.max(a.length, b.length);
  let result = a.length ^ b.length;
  for (let i = 0; i < maxLength; i++) {
    const charA = i < a.length ? a.charCodeAt(i) : 0;
    const charB = i < b.length ? b.charCodeAt(i) : 0;
    result |= charA ^ charB;
  }
  return result === 0;
}
```

### Missing or Invalid Key

If the `X-Admin-Key` header is missing:

```json theme={null}
{
  "success": false,
  "error": "Admin authentication required",
  "code": "ADMIN_AUTH_REQUIRED",
  "message": "Missing X-Admin-Key header"
}
```

If the key is invalid:

```json theme={null}
{
  "success": false,
  "error": "Invalid admin API key",
  "code": "ADMIN_AUTH_INVALID"
}
```

## Internal Bearer Authentication

Internal endpoints (cron jobs, pipeline triggers) use Bearer token authentication validated against server-side environment variables (`API_KEY`, `CRON_SECRET`).

<Tabs>
  <Tab title="API Key">
    ```bash theme={null}
    # Manual admin trigger
    curl -X POST "https://api.thisiswhyimhigh.com/api/v1/admin/backfill" \
      -H "Authorization: Bearer your-api-key"
    ```
  </Tab>

  <Tab title="Cron Secret">
    ```bash theme={null}
    # Vercel cron job (sent automatically by Vercel)
    curl "https://api.thisiswhyimhigh.com/api/v1/cron/daily-sync" \
      -H "Authorization: Bearer your-cron-secret"
    ```
  </Tab>

  <Tab title="Either Key">
    ```bash theme={null}
    # Endpoints accepting either key (manual or automated)
    curl -X POST "https://api.thisiswhyimhigh.com/api/v1/trigger/pipeline" \
      -H "Authorization: Bearer your-api-key-or-cron-secret"
    ```
  </Tab>
</Tabs>

### Security Model

| Environment     | Behavior                                                 |
| --------------- | -------------------------------------------------------- |
| **Production**  | Fail-closed: denies access if secrets are not configured |
| **Development** | Fail-open: allows access for easier local testing        |

<Warning>
  In production, if the required environment variable (`API_KEY` or `CRON_SECRET`) is not configured, the middleware **denies all access** rather than allowing unauthenticated requests through. This is a deliberate security design.
</Warning>

## Development Bypass

In development mode or when accessing via `localhost`, authentication is automatically bypassed for both admin and bearer auth middleware. This allows for easier local development and testing without configuring secrets.

```bash theme={null}
# localhost requests bypass auth automatically
curl "http://localhost:3001/api/v1/blog/generate-image" \
  -X POST \
  -H "Content-Type: application/json" \
  -d '{"slug": "test-post"}'
```

The bypass applies when any of these conditions are met:

* `NODE_ENV=development`
* Request host contains `localhost`
* Request host contains `127.0.0.1`

<Note>
  A `DEV_BYPASS_KEY` environment variable can also be configured for remote device testing (e.g., testing from a phone on the local network). When set, requests with `X-Admin-Key` matching this value are allowed through.
</Note>

## Error Codes Reference

| Code                        | HTTP Status | Description                              |
| --------------------------- | ----------- | ---------------------------------------- |
| `UNAUTHORIZED`              | 401         | Authentication required but not provided |
| `ADMIN_AUTH_REQUIRED`       | 401         | Missing `X-Admin-Key` header             |
| `ADMIN_AUTH_INVALID`        | 401         | Invalid admin API key                    |
| `ADMIN_AUTH_NOT_CONFIGURED` | 500         | Server misconfiguration (no key set)     |
