Skip to main content

Overview

Conversimple uses API key authentication to secure your agent’s connection to the platform. Each agent instance requires both an API key and a customer ID to establish a connection.

Credentials

API Key

Your API key is a secret token that identifies your account and authorizes access to the platform. Format: cs_live_xxxxxxxxxxxxxxxxxxxxx (production) or cs_test_xxxxxxxxxxxxxxxxxxxxx (development) Security: Treat your API key like a password:
  • Never commit API keys to version control
  • Rotate keys periodically
  • Use environment variables to store keys
  • Use different keys for development and production

Customer ID

Your customer ID uniquely identifies your organization on the platform. Format: cust_xxxxxxxxxxxxxxxxxxxxx Purpose:
  • Identifies your organization for billing and usage tracking
  • Enables multi-tenant isolation
  • Associates conversations with your account

Configuration Methods

The most secure way to provide credentials:
# Set environment variables
export CONVERSIMPLE_API_KEY="cs_live_your_key_here"
export CONVERSIMPLE_CUSTOMER_ID="cust_your_id_here"
export CONVERSIMPLE_PLATFORM_URL="wss://app.conversimple.com/sdk/websocket"
import os
from conversimple import ConversimpleAgent

# Automatically reads from environment variables
agent = ConversimpleAgent()

Programmatic Configuration

Pass credentials directly when needed:
from conversimple import ConversimpleAgent

agent = ConversimpleAgent(
    api_key="cs_live_your_key_here",
    customer_id="cust_your_id_here",
    platform_url="wss://app.conversimple.com/sdk/websocket"
)
Only use programmatic configuration when environment variables aren’t available. Always use secrets management for production deployments.

Configuration File

For development environments:
# config.py
CONVERSIMPLE_CONFIG = {
    "api_key": os.getenv("CONVERSIMPLE_API_KEY"),
    "customer_id": os.getenv("CONVERSIMPLE_CUSTOMER_ID"),
    "platform_url": os.getenv(
        "CONVERSIMPLE_PLATFORM_URL",
        "ws://localhost:4000/sdk/websocket"
    )
}

# agent.py
from config import CONVERSIMPLE_CONFIG
from conversimple import ConversimpleAgent

agent = ConversimpleAgent(**CONVERSIMPLE_CONFIG)

Connection Process

WebSocket Connection

When you call agent.start(), the SDK:
  1. Validates credentials locally (format checks)
  2. Establishes WebSocket connection to the platform
  3. Sends authentication message with API key and customer ID
  4. Receives confirmation or error
  5. Registers tools with the platform
  6. Enters ready state to handle conversations
import asyncio
from conversimple import ConversimpleAgent

async def main():
    agent = ConversimpleAgent(
        api_key="cs_live_your_key_here",
        customer_id="cust_your_id_here"
    )

    try:
        # Establishes connection and authenticates
        await agent.start()
        print("✅ Connected and authenticated")

        # Agent is now ready for conversations
        while True:
            await asyncio.sleep(1)

    except Exception as e:
        print(f"❌ Authentication failed: {e}")

asyncio.run(main())

Authentication Errors

Common authentication errors:
ErrorCauseSolution
Invalid API keyWrong or malformed keyCheck your API key format and value
API key revokedKey has been disabledGenerate a new API key
Customer ID mismatchWrong customer IDVerify your customer ID
Rate limit exceededToo many connection attemptsImplement exponential backoff
WebSocket connection failedNetwork or platform issueCheck network and platform status

Security Best Practices

1. Use Environment Variables

Never hardcode credentials in source code: Bad:
agent = ConversimpleAgent(
    api_key="cs_live_abc123xyz",  # DON'T DO THIS!
    customer_id="cust_abc123"
)
Good:
agent = ConversimpleAgent(
    api_key=os.getenv("CONVERSIMPLE_API_KEY"),
    customer_id=os.getenv("CONVERSIMPLE_CUSTOMER_ID")
)

2. Use .env Files

For local development:
# .env file
CONVERSIMPLE_API_KEY=cs_test_your_key_here
CONVERSIMPLE_CUSTOMER_ID=cust_your_id_here
# Load environment variables from .env
from dotenv import load_dotenv
load_dotenv()

from conversimple import ConversimpleAgent
agent = ConversimpleAgent()  # Reads from environment
Important: Add .env to .gitignore:
# .gitignore
.env
.env.local
.env.*.local

3. Use Secrets Management

For production: AWS Secrets Manager:
import boto3
import json

def get_secret(secret_name):
    client = boto3.client('secretsmanager')
    response = client.get_secret_value(SecretId=secret_name)
    return json.loads(response['SecretString'])

credentials = get_secret('conversimple/prod')
agent = ConversimpleAgent(
    api_key=credentials['api_key'],
    customer_id=credentials['customer_id']
)
HashiCorp Vault:
import hvac

client = hvac.Client(url='https://vault.example.com')
client.auth.approle.login(role_id='...', secret_id='...')

secret = client.secrets.kv.v2.read_secret_version(path='conversimple/prod')
credentials = secret['data']['data']

agent = ConversimpleAgent(
    api_key=credentials['api_key'],
    customer_id=credentials['customer_id']
)

4. Rotate Keys Regularly

Implement key rotation:
class AgentManager:
    def __init__(self):
        self.agent = None
        self.credentials = self.load_credentials()

    def load_credentials(self):
        """Load credentials from secure storage"""
        return {
            "api_key": get_from_secrets_manager("api_key"),
            "customer_id": get_from_secrets_manager("customer_id")
        }

    async def rotate_credentials(self):
        """Rotate credentials without downtime"""
        # Get new credentials
        new_creds = self.load_credentials()

        # Stop old agent
        if self.agent:
            await self.agent.stop()

        # Start new agent with new credentials
        self.agent = ConversimpleAgent(**new_creds)
        await self.agent.start()

5. Different Keys Per Environment

Use separate API keys for each environment:
# Development
api_key = "cs_test_dev_key"

# Staging
api_key = "cs_test_staging_key"

# Production
api_key = "cs_live_production_key"
This allows you to:
  • Test without affecting production
  • Track usage per environment
  • Revoke keys independently
  • Set different rate limits

Monitoring Authentication

Connection Health

Monitor your connection status:
class MonitoredAgent(ConversimpleAgent):
    def __init__(self, **kwargs):
        super().__init__(**kwargs)
        self.connection_status = "disconnected"
        self.last_connected = None

    async def start(self):
        """Start with monitoring"""
        try:
            await super().start()
            self.connection_status = "connected"
            self.last_connected = datetime.now()
            print(f"✅ Connected at {self.last_connected}")
        except Exception as e:
            self.connection_status = "failed"
            print(f"❌ Connection failed: {e}")
            raise

    def on_error(self, error_type: str, message: str, details: dict):
        """Handle authentication errors"""
        if error_type == "authentication":
            print(f"🔑 Auth error: {message}")
            self.connection_status = "authentication_failed"

Logging Authentication Events

Track authentication for debugging and auditing:
import logging

logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)

class AuditedAgent(ConversimpleAgent):
    async def start(self):
        logger.info(f"Attempting authentication for customer: {self.customer_id}")
        try:
            await super().start()
            logger.info("✅ Authentication successful")
        except Exception as e:
            logger.error(f"❌ Authentication failed: {e}")
            raise

Troubleshooting

Connection Timeout

If connection takes too long:
agent = ConversimpleAgent(
    api_key=api_key,
    customer_id=customer_id,
    connection_timeout=30  # Increase timeout to 30 seconds
)

Network Issues

Test platform connectivity:
import aiohttp

async def test_platform_connectivity():
    """Test if platform is reachable"""
    try:
        async with aiohttp.ClientSession() as session:
            async with session.get('https://app.conversimple.com/health') as response:
                if response.status == 200:
                    print("✅ Platform is reachable")
                else:
                    print(f"⚠️ Platform returned {response.status}")
    except Exception as e:
        print(f"❌ Cannot reach platform: {e}")

Debugging Authentication

Enable debug logging:
import logging

# Enable SDK debug logs
logging.getLogger('conversimple').setLevel(logging.DEBUG)

# Your agent will now show detailed auth logs
agent = ConversimpleAgent(api_key=api_key, customer_id=customer_id)
await agent.start()

Next Steps