API Authentication

Learn how to authenticate your requests and securely access the AIPersona API.

Session Authentication

Automatic authentication for dashboard users via session cookies.

Dashboard

API Key Authentication

Header-based authentication for external integrations and server-side calls.

External API

Authentication Methods

AIPersona supports two authentication methods depending on your use case.

Session-Based (Dashboard)

When using the AIPersona dashboard or embedding the tRPC client in your own Next.js app with shared authentication, requests are automatically authenticated via session cookies.

  • No additional configuration required
  • Session is maintained after login
  • Works seamlessly with the tRPC client in the frontend

API Key (External Access)

For server-to-server communication, external integrations, or building your own clients, use API key authentication.

Required Headers:
TEXT
X-API-Key: your-api-key-here
X-Organization-ID: your-organization-id

API Key Management

API keys are scoped to your organization and can be created, updated, and revoked from the dashboard.

Creating an API Key

  1. Navigate to Settings → API Keys in your dashboard
  2. Click Create New Key
  3. Enter a descriptive name for your key (e.g., "Production Server", "Development")
  4. Optionally configure rate limits and expiration
  5. Copy the generated key and store it securely
Warning
API keys are only shown once during creation. Copy and store them immediately in a secure location.

API Key Features

Organization Scoping

Each API key is tied to a specific organization and can only access resources within that organization.

Rate Limiting

Configure per-key rate limits with customizable request counts and time windows.

Enable/Disable

Temporarily disable a key without deleting it, useful for debugging or emergencies.

Expiration

Optionally set an expiration date for short-lived or temporary access.

Managing Keys via API

List all API keys for your organization (dashboard only):

TypeScript
// Using tRPC client in dashboard
const apiKeys = await trpc.apiKeys.list.query();

// Returns keys without the actual key value for security
[{
  id: "key_abc123",
  name: "Production Server",
  start: "aip_",
  enabled: true,
  rateLimitEnabled: true,
  rateLimitMax: 1000,
  createdAt: "2025-01-15T10:00:00.000Z"
}]

Using API Keys

Header Authentication

Include both headers with every API request:

TEXT
X-API-Key: your-api-key-here
X-Organization-ID: your-organization-id
Content-Type: application/json

Example Requests

Bash
# List personas
curl -X GET "https://aipersona.dsethiopia.org/api/trpc/persona.list?input=%7B%7D" \
  -H "X-API-Key: your-api-key" \
  -H "X-Organization-ID: your-org-id"

# Create a chat session
curl -X POST "https://aipersona.dsethiopia.org/api/trpc/chat.createSession" \
  -H "Content-Type: application/json" \
  -H "X-API-Key: your-api-key" \
  -H "X-Organization-ID: your-org-id" \
  -d '{"json": {"personaId": "clx123...", "title": "New Chat"}}'

Rate Limiting

Each API key has configurable rate limits to ensure fair usage and protect the service.

Default Rate Limits

SettingDefault Value
Max Requests1,000 per window
Time Window1 hour (3,600,000 ms)

These defaults can be customized when creating or updating an API key.

Handling Rate Limits

When you exceed rate limits, you'll receive a 429 status code:

JSON
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded for this API key",
    "data": {
      "remaining": 0,
      "resetAt": "2025-01-15T12:00:00.000Z"
    }
  }
}
Tip
Implement exponential backoff in your client code to gracefully handle rate limit errors.

Security Best Practices

Do's

  • • Store API keys in environment variables
  • • Use different keys for dev/staging/production
  • • Rotate API keys periodically
  • • Use descriptive key names for tracking
  • • Set expiration dates for temporary access
  • • Monitor key usage in the dashboard
  • • Disable unused keys immediately

Don'ts

  • • Never commit API keys to version control
  • • Don't expose keys in client-side code
  • • Don't share keys between projects
  • • Don't hardcode keys in applications
  • • Don't log API keys in plain text
  • • Don't use the same key for different environments

Environment Variables Example

Bash
# .env file (never commit this!)
AIPERSONA_API_KEY=your-api-key-here
AIPERSONA_ORG_ID=your-organization-id
AIPERSONA_BASE_URL=https://aipersona.dsethiopia.org/api/trpc

Error Handling

Handle authentication errors gracefully in your applications.

Common Authentication Errors

401 Unauthorized
JSON
{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid or missing API key"
  }
}

Cause: Missing X-API-Key header or invalid key value.

403 Forbidden
JSON
{
  "error": {
    "code": "FORBIDDEN",
    "message": "Organization access denied"
  }
}

Cause: Missing/incorrect X-Organization-ID or key not associated with the organization.

429 Too Many Requests
JSON
{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded"
  }
}

Cause: API key has exceeded its rate limit. Wait and retry.

Error Handling Example

JavaScript
async function callAPIWithErrorHandling(procedure, data) {
  try {
    const response = await fetch(`${BASE_URL}/${procedure}`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'X-API-Key': API_KEY,
        'X-Organization-ID': ORG_ID,
      },
      body: JSON.stringify({ json: data })
    });
    
    if (!response.ok) {
      const error = await response.json();
      
      switch (response.status) {
        case 401:
          throw new Error('Invalid API key - check your credentials');
        case 403:
          throw new Error('Access denied - check organization ID');
        case 429:
          // Implement retry with backoff
          const retryAfter = 60;
          console.log(`Rate limited. Retry after ${retryAfter}s`);
          throw new Error('Rate limit exceeded');
        default:
          throw new Error(error.error?.message || 'Unknown error');
      }
    }
    
    return (await response.json()).result.data;
  } catch (error) {
    console.error('API call failed:', error.message);
    throw error;
  }
}
Tip
For debugging authentication issues, check the dashboard's API Key settings to verify the key is enabled and hasn't expired.