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:
- Settings → Developer → API Keys
- Click "Generate New Key"
- Enter description
- Select scopes
- 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 experienceOAuth 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/:idSearch:
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/summarySecurity
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/24Error 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
- Supabase Architecture - Database design
- Data Flow - System architecture
- Security - Security practices
Last Updated: October 11, 2025