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
Environment Variables (Recommended)
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:
Validates credentials locally (format checks)
Establishes WebSocket connection to the platform
Sends authentication message with API key and customer ID
Receives confirmation or error
Registers tools with the platform
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:
Error Cause Solution Invalid API keyWrong or malformed key Check your API key format and value API key revokedKey has been disabled Generate a new API key Customer ID mismatchWrong customer ID Verify your customer ID Rate limit exceededToo many connection attempts Implement exponential backoff WebSocket connection failedNetwork or platform issue Check 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
Conversation Lifecycle Learn about conversation flow
Error Handling Handle authentication errors gracefully