Skip to content

API Key Management

The API Key Management system allows users to securely store and manage their external service API keys. Keys are encrypted at rest and can be used by the AI agents for enhanced functionality.

Base URL

All API key management endpoints are prefixed with:

/api/v1/api-keys/

Authentication

All API key endpoints require authentication. Include the Bearer token in the Authorization header:

Authorization: Bearer <your_jwt_token>

Supported API Key Types

Type Description Used For
google_api Google AI Studio API Key Gemini AI models and agent functionality
news_api NewsAPI Key Financial news aggregation and analysis

Note: Yahoo Finance requires no API key. Finnhub and FMP keys can be stored as general purpose keys.

Data Models

API Key Response

{
  "id": 1,
  "key_type": "news_api",
  "key_name": "My News API Key",
  "is_active": true,
  "masked_key": "****abcd",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T10:30:00Z",
  "last_used_at": "2025-01-15T12:00:00Z"
}

API Key Creation

{
  "key_type": "news_api",
  "api_key": "your-actual-api-key-here",
  "key_name": "My News API Key"
}

API Key Update

{
  "key_name": "Updated Key Name",
  "is_active": false
}

Endpoints

Create API Key

Create a new API key for external service integration.

POST /api/v1/api-keys/

Request Body

{
  "key_type": "news_api",
  "api_key": "your-actual-api-key-here",
  "key_name": "My News API Key"
}

Response

Status Code: 201 Created

{
  "id": 1,
  "key_type": "news_api",
  "key_name": "My News API Key",
  "is_active": true,
  "masked_key": "****abcd",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": null,
  "last_used_at": null
}

Error Responses

400 Bad Request - Invalid data or duplicate key type

{
  "detail": "API key for this service type already exists"
}


Get All API Keys

Retrieve all API keys for the current user.

GET /api/v1/api-keys/?include_inactive=false

Query Parameters

Parameter Type Required Description
include_inactive boolean No Include inactive keys (default: false)

Response

Status Code: 200 OK

[
  {
    "id": 1,
    "key_type": "news_api",
    "key_name": "My News API Key",
    "is_active": true,
    "masked_key": "****abcd",
    "created_at": "2025-01-15T10:30:00Z",
    "updated_at": null,
    "last_used_at": "2025-01-15T12:00:00Z"
  },
  {
    "id": 2,
    "key_type": "google_api",
    "key_name": "Google AI Key",
    "is_active": true,
    "masked_key": "****xyz9",
    "created_at": "2025-01-15T11:00:00Z",
    "updated_at": null,
    "last_used_at": null
  }
]

Get Specific API Key

Retrieve a specific API key by ID.

GET /api/v1/api-keys/{key_id}

Path Parameters

Parameter Type Description
key_id integer ID of the API key to retrieve

Response

Status Code: 200 OK

{
  "id": 1,
  "key_type": "news_api",
  "key_name": "My News API Key",
  "is_active": true,
  "masked_key": "****abcd",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": null,
  "last_used_at": "2025-01-15T12:00:00Z"
}

Error Responses

404 Not Found

{
  "detail": "API key not found"
}


Update API Key

Update an existing API key (name or active status only - not the key value).

PUT /api/v1/api-keys/{key_id}

Path Parameters

Parameter Type Description
key_id integer ID of the API key to update

Request Body

{
  "key_name": "Updated Key Name",
  "is_active": false
}

Response

Status Code: 200 OK

{
  "id": 1,
  "key_type": "news_api",
  "key_name": "Updated Key Name",
  "is_active": false,
  "masked_key": "****abcd",
  "created_at": "2025-01-15T10:30:00Z",
  "updated_at": "2025-01-15T14:30:00Z",
  "last_used_at": "2025-01-15T12:00:00Z"
}

Delete API Key

Delete an API key (soft delete - marks as inactive).

DELETE /api/v1/api-keys/{key_id}

Path Parameters

Parameter Type Description
key_id integer ID of the API key to delete

Response

Status Code: 204 No Content


Test API Key by ID

Test the functionality of a stored API key.

POST /api/v1/api-keys/test-by-id/{key_id}

Path Parameters

Parameter Type Description
key_id integer ID of the API key to test

Response

Status Code: 200 OK

{
  "status": "success",
  "service": "news_api",
  "message": "API key is valid and working",
  "response_time_ms": 245,
  "tested_at": "2025-01-15T15:00:00Z"
}

Failed Test Response:

{
  "status": "error",
  "service": "news_api",
  "message": "Invalid API key or service unavailable",
  "error_code": "UNAUTHORIZED",
  "tested_at": "2025-01-15T15:00:00Z"
}


Test API Key by Type

Test the functionality of an API key by service type.

POST /api/v1/api-keys/test-by-type/{key_type}

Path Parameters

Parameter Type Description
key_type string Type of API key to test (google_api, news_api)

Response

Status Code: 200 OK

{
  "status": "success",
  "service": "news_api",
  "message": "API key is valid and working",
  "response_time_ms": 245,
  "tested_at": "2025-01-15T15:00:00Z"
}

Security Features

Encryption

  • All API keys are encrypted at rest using symmetric encryption
  • Keys are never stored in plain text
  • Only the last 4 characters are shown in responses (masked)

Access Control

  • Users can only access their own API keys
  • Full authentication required for all operations
  • Proper authorization checks on all endpoints

Key Testing

  • Built-in functionality to test API key validity
  • Tests make actual calls to external services
  • Results include response time and status information

Usage in AI Agents

When you store API keys, they become available to the AI agents:

  1. News API: Used by News Analyst agent for real-time financial news
  2. Google API: Used by all agents for Gemini AI model access
  3. System Fallbacks: If no user key is provided, system defaults are used (when available)

Examples

Complete API Key Workflow

1. Create a News API Key

curl -X POST "http://localhost:8000/api/v1/api-keys/" \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..." \
  -H "Content-Type: application/json" \
  -d '{
    "key_type": "news_api",
    "api_key": "your-news-api-key-here",
    "key_name": "My Primary News Key"
  }'

2. Test the API Key

curl -X POST "http://localhost:8000/api/v1/api-keys/test-by-type/news_api" \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

3. Get All Your Keys

curl -X GET "http://localhost:8000/api/v1/api-keys/" \
  -H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9..."

JavaScript/TypeScript Examples

// Create API key service
class APIKeyService {
  constructor(baseURL, token) {
    this.baseURL = baseURL;
    this.token = token;
  }

  async createAPIKey(keyType, apiKey, keyName) {
    const response = await fetch(`${this.baseURL}/api/v1/api-keys/`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.token}`,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        key_type: keyType,
        api_key: apiKey,
        key_name: keyName
      })
    });

    return await response.json();
  }

  async testAPIKey(keyType) {
    const response = await fetch(`${this.baseURL}/api/v1/api-keys/test-by-type/${keyType}`, {
      method: 'POST',
      headers: {
        'Authorization': `Bearer ${this.token}`
      }
    });

    return await response.json();
  }

  async getAllAPIKeys(includeInactive = false) {
    const response = await fetch(`${this.baseURL}/api/v1/api-keys/?include_inactive=${includeInactive}`, {
      headers: {
        'Authorization': `Bearer ${this.token}`
      }
    });

    return await response.json();
  }
}

// Usage
const apiKeyService = new APIKeyService('http://localhost:8000', 'your-jwt-token');

// Create a new API key
const newKey = await apiKeyService.createAPIKey('news_api', 'your-api-key', 'My News Key');

// Test the key
const testResult = await apiKeyService.testAPIKey('news_api');

// Get all keys
const allKeys = await apiKeyService.getAllAPIKeys();

Best Practices

  1. Key Naming: Use descriptive names for your API keys
  2. Testing: Regularly test your API keys to ensure they're still valid
  3. Rotation: Update API keys periodically for security
  4. Monitoring: Check the last_used_at field to monitor key usage
  5. Cleanup: Remove or deactivate unused API keys