Skip to main content

Overview

The Cap API supports multiple authentication methods depending on your use case:
  • Session cookies - For web application
  • Bearer tokens - For desktop app and API integrations
  • Authorization headers - For custom domains and commercial licenses

Authentication Methods

Session Cookies (NextAuth)

The web application uses NextAuth.js for session management.

Login Flow

  1. User navigates to login page
  2. Enters email address
  3. Receives magic link via email
  4. Clicks link to authenticate
  5. Session cookie is set automatically

Session Configuration

Sessions are configured in packages/database/auth/auth-options.ts. Default session duration: 30 days

Bearer Tokens

For programmatic access, use Bearer tokens in the Authorization header.

Request Format

curl https://cap.so/api/video/analytics?videoId=123 \
  -H "Authorization: Bearer <your_token>"

Desktop App Authentication

The desktop app stores authentication tokens securely:
  • macOS: Keychain
  • Windows: Credential Manager
  • Linux: Secret Service API

Authorization Headers

Some endpoints use custom authorization headers:

Custom Domain Verification

headers: {
  authorization: z.string()
}

License Activation

headers: {
  licensekey: z.string(),
  instanceid: z.string()
}

Protected Endpoints

Desktop Routes

All desktop routes require authentication:
const protectedContract = c.router(
  {
    submitFeedback: { /* ... */ },
    getUserPlan: { /* ... */ },
    getS3Config: { /* ... */ },
  },
  {
    baseHeaders: z.object({ authorization: z.string() }),
    commonResponses: { 
      401: z.object({ error: z.string().or(z.boolean()) }) 
    },
  }
);

Video Endpoints

Video management endpoints require authentication:
  • DELETE /video/delete
  • GET /video/analytics
  • GET /video/transcribe/status

Notification Endpoints

Notification endpoints require authentication:
  • GET /notifications

Error Responses

401 Unauthorized

Returned when authentication is missing or invalid:
{
  "error": "Unauthorized"
}
or
{
  "error": true,
  "auth": false
}

403 Forbidden

Returned when the user lacks permissions:
{
  "message": "Insufficient permissions"
}

Obtaining Authentication Tokens

For Desktop App

The desktop app handles authentication automatically:
  1. User clicks “Sign In”
  2. Opens browser to login page
  3. Completes authentication
  4. Token is sent back to desktop app
  5. Token stored securely in system keychain

For API Integrations

Currently, Cap does not provide public API tokens for third-party integrations. This feature is planned for future releases.

Session Management

Check Session Status

For web sessions, NextAuth provides:
import { getServerSession } from "next-auth/next";
import { authOptions } from "@cap/database/auth/auth-options";

const session = await getServerSession(authOptions);

if (!session) {
  // Not authenticated
}

Client-Side Session

import { useSession } from "next-auth/react";

const { data: session, status } = useSession();

if (status === "authenticated") {
  // User is logged in
}

Security Best Practices

Never commit authentication tokens to version controlStore tokens in:
  • Environment variables
  • System keychains
  • Secure credential stores

Token Storage

Use platform-specific secure storage:
  • macOS: Keychain Services
  • Windows: Credential Manager
  • Linux: libsecret/gnome-keyring
Use secure cookies:
  • HttpOnly flag
  • Secure flag (HTTPS only)
  • SameSite=Lax or Strict
Store in environment variables:
  • Never hardcode tokens
  • Use .env files (excluded from git)
  • Rotate tokens regularly

Commercial License Authentication

Activate License

POST /api/commercial/activate
Headers:
{
  "licensekey": "your-license-key",
  "instanceid": "unique-instance-id"
}
Body:
{
  "reset": false
}
Response:
{
  "message": "License activated",
  "expiryDate": 1735689600,
  "refresh": 86400
}
Headers:
{
  "licensekey": "your-license-key",
  "instanceid": "unique-instance-id"
}
Body:
{
  "reset": false
}
Response:
{
  "message": "License activated",
  "expiryDate": 1735689600,
  "refresh": 86400
}
See packages/web-api-contract/src/index.ts:122-136 for full schema.

Testing Authentication

Test Authenticated Endpoint

curl -X GET https://cap.so/api/desktop/plan \
  -H "Authorization: Bearer test-token" \
  -H "Content-Type: application/json"
Expected response (authenticated):
{
  "upgraded": true,
  "stripeSubscriptionStatus": "active"
}
Expected response (unauthenticated):
{
  "error": "Unauthorized"
}

Authentication Flow Diagram

Next Steps

Videos API

Learn about video endpoints

Notifications API

Learn about notification endpoints

Build docs developers (and LLMs) love