Skip to main content

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

TierHeaderUse CaseExample Endpoints
PublicNoneStrain data, search, catalogGET /strains, GET /strains/search
AdminX-Admin-Key: <key>Administrative operationsPOST /blog/generate-image
InternalAuthorization: Bearer <api_key>Cron jobs, pipelinesGET /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.
# No authentication needed
curl "https://tiwih-api.vercel.app/api/v1/strains/slug/blue-dream/complete"

curl "https://tiwih-api.vercel.app/api/v1/strains/search?q=sour+diesel"

curl "https://tiwih-api.vercel.app/api/v1/strains/popular"

User Authentication

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.

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.
curl -X POST "https://tiwih-api.vercel.app/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.
// 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:
{
  "success": false,
  "error": "Admin authentication required",
  "code": "ADMIN_AUTH_REQUIRED",
  "message": "Missing X-Admin-Key header"
}
If the key is invalid:
{
  "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).
# Manual admin trigger
curl -X POST "https://tiwih-api.vercel.app/api/v1/admin/backfill" \
  -H "Authorization: Bearer your-api-key"

Security Model

EnvironmentBehavior
ProductionFail-closed: denies access if secrets are not configured
DevelopmentFail-open: allows access for easier local testing
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.

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.
# 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
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.

Error Codes Reference

CodeHTTP StatusDescription
UNAUTHORIZED401Authentication required but not provided
ADMIN_AUTH_REQUIRED401Missing X-Admin-Key header
ADMIN_AUTH_INVALID401Invalid admin API key
ADMIN_AUTH_NOT_CONFIGURED500Server misconfiguration (no key set)