Skip to content

API Authentication

Overview

Solatis API uses JWT-based authentication with support for API keys, OAuth 2.0, and service roles for different use cases.

Authentication Methods

API Keys

Generate API Key:

  1. Settings → Developer → API Keys
  2. Click "Generate New Key"
  3. Enter description
  4. Select scopes
  5. Copy key (shown once!)

Usage:

bash
curl https://api.solatis.com/v1/documents \
  -H "Authorization: Bearer sk_live_abc123..."

Key Types:

User API Keys:

  • Tied to user account
  • Inherits user permissions
  • Personal projects
  • Development and testing

Service Keys:

  • Organization-level
  • Independent permissions
  • Production systems
  • Server-to-server

Scopes:

read:documents    - View documents
write:documents   - Create/update documents
delete:documents  - Remove documents
read:meetings     - Access meetings
write:meetings    - Create meetings
admin:*           - Full access (careful!)

JWT Tokens

Obtain Token:

typescript
import { createClient } from '@supabase/supabase-js';

const supabase = createClient(
  'https://your-project.supabase.co',
  'your-anon-key'
);

// Sign in
const { data, error } = await supabase.auth.signInWithPassword({
  email: 'user@example.com',
  password: 'password'
});

// Access token
const token = data.session.access_token;

Use Token:

typescript
const response = await fetch('https://api.solatis.com/v1/documents', {
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
});

Token Lifecycle:

Access Token: 1 hour TTL
Refresh Token: 30 days TTL

Before expiry:
  - Auto-refresh using refresh token
  - New access token issued
  - Seamless user experience

OAuth 2.0

Authorization Flow:

1. Redirect to authorization endpoint
GET https://api.solatis.com/oauth/authorize
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=YOUR_CALLBACK
  &response_type=code
  &scope=read:documents write:documents

2. User authorizes

3. Callback with code
GET https://your-app.com/callback?code=AUTH_CODE

4. Exchange code for tokens
POST https://api.solatis.com/oauth/token
{
  "grant_type": "authorization_code",
  "code": "AUTH_CODE",
  "client_id": "YOUR_CLIENT_ID",
  "client_secret": "YOUR_SECRET",
  "redirect_uri": "YOUR_CALLBACK"
}

5. Receive tokens
{
  "access_token": "...",
  "refresh_token": "...",
  "expires_in": 3600,
  "token_type": "Bearer"
}

API Reference

Endpoints

Documents:

bash
# List documents
GET /v1/documents?workspace_id=uuid

# Get document
GET /v1/documents/:id

# Create document
POST /v1/documents
{
  "workspace_id": "uuid",
  "title": "My Document",
  "content": "..."
}

# Update document
PATCH /v1/documents/:id
{
  "title": "Updated Title"
}

# Delete document
DELETE /v1/documents/:id

Search:

bash
# Semantic search
POST /v1/search
{
  "query": "how to configure auth",
  "workspace_id": "uuid",
  "limit": 20
}

Meetings:

bash
# List meetings
GET /v1/meetings?workspace_id=uuid

# Get transcript
GET /v1/meetings/:id/transcript

# Get summary
GET /v1/meetings/:id/summary

Security

Best Practices

API Key Storage:

bash
# ✅ Environment variables
export SOLATIS_API_KEY="sk_live_..."

# ✅ Secret manager
aws secretsmanager get-secret-value --secret-id solatis-api-key

# ❌ Never in code
const API_KEY = "sk_live_123...";  // BAD!

# ❌ Never in version control
git add .env  // BAD!

Rate Limiting:

Standard: 100 requests/minute
Pro: 1000 requests/minute
Enterprise: Custom limits

HTTP 429 when exceeded:
{
  "error": "rate_limit_exceeded",
  "retry_after": 60
}

IP Allowlisting (Enterprise):

Settings → Security → IP Allowlist
Add: 203.0.113.0/24

Error Handling

Common Errors:

typescript
// 401 Unauthorized
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or expired token"
  }
}

// 403 Forbidden
{
  "error": {
    "code": "forbidden",
    "message": "Insufficient permissions"
  }
}

// 429 Rate Limited
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests",
    "retry_after": 60
  }
}

Retry Logic:

typescript
async function apiRequestWithRetry(
  url: string,
  options: RequestInit,
  maxRetries = 3
) {
  for (let i = 0; i < maxRetries; i++) {
    try {
      const response = await fetch(url, options);
      
      if (response.status === 429) {
        const retryAfter = response.headers.get('Retry-After');
        await sleep(parseInt(retryAfter || '60') * 1000);
        continue;
      }
      
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}`);
      }
      
      return await response.json();
    } catch (error) {
      if (i === maxRetries - 1) throw error;
      await sleep(1000 * Math.pow(2, i)); // Exponential backoff
    }
  }
}

SDKs

TypeScript/JavaScript:

typescript
import { SolatisClient } from '@solatis/sdk';

const client = new SolatisClient({
  apiKey: process.env.SOLATIS_API_KEY
});

const documents = await client.documents.list({
  workspaceId: 'workspace-uuid'
});

Python:

python
from solatis import Solatis

client = Solatis(api_key=os.environ["SOLATIS_API_KEY"])

documents = client.documents.list(
    workspace_id="workspace-uuid"
)

Next Steps


Last Updated: October 11, 2025

Released under the MIT License.