# API Documentation Only read this file when modifying API routes, authentication, keys, or integrations. --- # API Location API routes: src/routes/api/v1/ --- # Authentication Most API endpoints require: Authorization: Bearer API keys are: - generated randomly - hashed with SHA-256 before storage - displayed using stored prefix only Never store plaintext API keys. --- # API Key Lifecycle Normal rotation: - New key generated. - Old key remains valid for 48 hours. - Old key expires using expiresAt. Emergency rotation: - Old key immediately invalidated. - revokedAt is set. --- # API Routes ## Categories GET: /api/v1/categories Requires API key. --- ## Frequencies GET: /api/v1/frequencies Requires API key. --- ## Proclamations GET: /api/v1/proclamations Supports: - optional key filtering - optional email filtering Requires API key. --- ## License Validation POST: /api/v1/license Payload: { "license_key": "...", "email_address": "..." } Requires API key. --- # Schedule (v2) Endpoint: GET /api/v2/schedule?email=&licenseKey= Authenticates with the paired `email` + `licenseKey` query parameters and validates only that the key belongs to the account (not that the license is active/entitled). Returns the user's Blocks with start/end times and the IDs of the selected Proclamations (content is fetched separately via `/api/v2/proclamations`). Each block also carries `dynamicAudio`; when true, the kiosk enables dynamic audio for the block's duration, overriding any audio selections made on the device while the block is active. Overnight blocks (end clock time before start) are supported and flagged with `overnight: true` plus a wrapping `durationMinutes`. Rate limited to 10 requests per minute per IP. Failure messages follow the existing v2 shape: `not-authorized` or `this key doesn't appear to belong to you`. --- # GHL Account Creation Webhook Endpoint: POST /api/v1/automations/create/account This endpoint does NOT require an API key. It is used by GoHighLevel automation. --- # Account Creation Flow When a request arrives: 1. Check whether the email already exists. If user does not exist: 2. Create user through Better Auth. 3. Generate temporary password. 4. Retrieve verification token. 5. Build verification URL. 6. Send registration email. Then: 7. Create LicenseKey. 8. Send license key delivery email. If user already exists: 1. Skip signup. 2. Create license key. 3. Send delivery email. --- # Email Templates Controlled by: src/lib/server/resend.ts Templates: automated-user-registration Variables: - firstName - tempPassword - verifyUrl - loginUrl license-key-delivery Variables: - firstName - license_key email-verification-email Variables: - target_email_address - verification_link --- # Better Auth Server: src/lib/auth.ts Client: src/lib/auth-client.ts Email callbacks: - sendVerificationEmail - sendResetPassword Failures should: - log errors - not crash requests Use: void promise.catch() pattern. --- # Security Rules Never: - expose plaintext API keys - bypass authorization checks - trust client role information - skip validation Always: - validate input - check permissions - preserve existing security patterns --- # API Change Workflow Before modifying an endpoint: 1. Read the route. 2. Read related auth middleware. 3. Read database models involved. 4. Check existing tests. After modifying: Run: npm run check npm run test Fix failures before completing.