Authentication
NextEVI supports multiple authentication methods for different use cases. Choose the method that best fits your application architecture and security requirements.
Authentication Methods
API Key Recommended for server-side applications Simple and secure for backend services and development
JWT Token Recommended for client applications Secure user sessions with fine-grained permissions
API Key Authentication
Getting Your API Key
Sign up at NextEVI Dashboard
Create a new project
Generate an API key from the project settings
Copy your API key (starts with oak_)
Using API Keys
API keys are passed as query parameters in the WebSocket URL:
const ws = new WebSocket (
`wss://api.nextevi.com/ws/voice/ ${ connectionId } ?api_key=oak_your_api_key&config_id=your_config_id`
);
React SDK
WebSocket Direct
Python
import { useVoice } from '@nextevi/voice-react' ;
function VoiceChat () {
const { connect } = useVoice ();
const handleConnect = async () => {
await connect ({
auth: {
apiKey: "oak_your_api_key" ,
configId: "your_config_id" ,
projectId: "your_project_id" // Optional
}
});
};
return < button onClick = { handleConnect } > Connect </ button > ;
}
API Key Security
Never expose API keys in client-side code API keys provide full access to your account and should only be used in secure server environments.
Best Practices:
Store API keys in environment variables
Use different keys for development and production
Rotate keys regularly
Monitor usage in the NextEVI dashboard
# Environment variables
NEXTEVI_API_KEY = oak_your_api_key
NEXTEVI_CONFIG_ID = your_config_id
NEXTEVI_PROJECT_ID = your_project_id
JWT Token Authentication
When to Use JWT
JWT tokens are ideal for:
Client-side applications (React, mobile apps)
User-specific sessions
Multi-tenant applications
Fine-grained permission control
Getting JWT Tokens
JWT tokens are obtained from your backend authentication system. Contact NextEVI support to set up JWT authentication for your account.
Using JWT Tokens
JWT tokens can be passed via Authorization header or query parameter:
JWT Token Structure
NextEVI JWT tokens contain the following claims:
{
"iss" : "nextevi.com" ,
"sub" : "user_id_123" ,
"aud" : "nextevi-api" ,
"exp" : 1645123456 ,
"iat" : 1645120000 ,
"permissions" : [ "voice:connect" , "voice:stream" ],
"project_id" : "project_123" ,
"config_id" : "config_abc"
}
Show JWT Claims Reference
Token issuer (always “nextevi.com”)
Subject - unique user identifier
Audience (always “nextevi-api”)
Expiration time (Unix timestamp)
Issued at time (Unix timestamp)
List of granted permissions
Associated project identifier
Voice configuration identifier
Environment Setup
Development Environment
Create a .env file for local development:
# .env
NEXTEVI_API_KEY = oak_dev_your_api_key
NEXTEVI_CONFIG_ID = dev_config_id
NEXTEVI_PROJECT_ID = dev_project_id
NEXTEVI_BASE_URL = wss://api.nextevi.com/ws/voice
Production Environment
Set environment variables securely in your production environment:
Docker
Kubernetes
Vercel
AWS Lambda
# docker-compose.yml
version: '3'
services:
app:
environment:
- NEXTEVI_API_KEY=oak_prod_your_api_key
- NEXTEVI_CONFIG_ID=prod_config_id
- NEXTEVI_PROJECT_ID=prod_project_id
Configuration Management
Project and Config IDs
Project ID : Identifies your NextEVI project and billing account
Config ID : Specifies voice model, language, and feature settings
Both are obtained from the NextEVI Dashboard :
Navigate to your project
Go to “Voice Configurations”
Copy the Config ID for your desired setup
Project ID is shown in the project settings
Dynamic Configuration
For multi-tenant applications, you can use different configs per user:
class NextEVIManager {
constructor () {
this . connections = new Map ();
}
async connectUser ( userId , userConfig ) {
const connectionId = `conn- ${ userId } - ${ Date . now () } ` ;
const ws = new WebSocket (
`wss://api.nextevi.com/ws/voice/ ${ connectionId } ?api_key= ${ process . env . NEXTEVI_API_KEY } &config_id= ${ userConfig . configId } &project_id= ${ userConfig . projectId } `
);
this . connections . set ( userId , { ws , connectionId , config: userConfig });
return ws ;
}
getUserConnection ( userId ) {
return this . connections . get ( userId );
}
}
Error Handling
Authentication Errors
Common authentication error codes:
Cause : No authentication providedSolution : Include either api_key query parameter or Authorization header// Missing authentication
const ws = new WebSocket ( `wss://api.nextevi.com/ws/voice/ ${ connectionId } ` );
// Fixed - with API key
const ws = new WebSocket ( `wss://api.nextevi.com/ws/voice/ ${ connectionId } ?api_key=oak_your_key&config_id=your_config` );
Cause : Invalid API key or expired JWT tokenSolution : Verify your credentials and check token expiration// Check API key format
if ( ! apiKey . startsWith ( 'oak_' )) {
throw new Error ( 'Invalid API key format' );
}
// Check JWT expiration
const payload = JSON . parse ( atob ( jwtToken . split ( '.' )[ 1 ]));
if ( payload . exp < Date . now () / 1000 ) {
throw new Error ( 'JWT token expired' );
}
Cause : Invalid config_id providedSolution : Verify your config_id in the NextEVI dashboard// Validate config exists before connecting
const validConfigs = await fetchValidConfigs ();
if ( ! validConfigs . includes ( configId )) {
throw new Error ( `Invalid config_id: ${ configId } ` );
}
PROJECT_ACCESS_DENIED (4003)
Cause : API key or JWT doesn’t have access to specified projectSolution : Check project permissions in dashboard or regenerate credentials
Connection Retry Logic
Implement robust error handling with exponential backoff:
class AuthenticatedConnection {
constructor ( auth ) {
this . auth = auth ;
this . retryCount = 0 ;
this . maxRetries = 5 ;
}
async connect () {
try {
const ws = new WebSocket ( this . buildUrl ());
ws . onopen = () => {
console . log ( 'Connected successfully' );
this . retryCount = 0 ; // Reset on successful connection
};
ws . onerror = ( error ) => {
console . error ( 'Connection error:' , error );
};
ws . onclose = ( event ) => {
if ( event . code >= 4000 && event . code < 5000 ) {
// Authentication or client error - don't retry
console . error ( 'Authentication failed:' , event . reason );
return ;
}
// Network error - retry with backoff
this . scheduleRetry ();
};
return ws ;
} catch ( error ) {
console . error ( 'Failed to create connection:' , error );
this . scheduleRetry ();
}
}
scheduleRetry () {
if ( this . retryCount >= this . maxRetries ) {
console . error ( 'Max retries exceeded' );
return ;
}
const delay = Math . pow ( 2 , this . retryCount ) * 1000 ; // Exponential backoff
this . retryCount ++ ;
console . log ( `Retrying connection in ${ delay } ms (attempt ${ this . retryCount } )` );
setTimeout (() => {
this . connect ();
}, delay );
}
buildUrl () {
const connectionId = `conn- ${ Math . random (). toString ( 36 ). substr ( 2 , 9 ) } ` ;
const baseUrl = `wss://api.nextevi.com/ws/voice/ ${ connectionId } ` ;
if ( this . auth . apiKey ) {
return ` ${ baseUrl } ?api_key= ${ this . auth . apiKey } &config_id= ${ this . auth . configId } ` ;
} else if ( this . auth . jwtToken ) {
return ` ${ baseUrl } ?authorization=Bearer%20 ${ this . auth . jwtToken } &config_id= ${ this . auth . configId } ` ;
}
throw new Error ( 'No authentication method provided' );
}
}
// Usage
const connection = new AuthenticatedConnection ({
apiKey: 'oak_your_api_key' ,
configId: 'your_config_id'
});
await connection . connect ();
Security Best Practices
API Key Security
✅ Store in environment variables, never in code
✅ Use different keys for dev/staging/production
✅ Rotate keys regularly (quarterly recommended)
✅ Monitor usage and set up alerts
❌ Never commit keys to version control
❌ Never expose keys in client-side JavaScript
JWT Token Security
✅ Use short expiration times (15-60 minutes)
✅ Implement proper token refresh flow
✅ Validate tokens server-side before use
✅ Use secure HTTP-only cookies when possible
❌ Never store tokens in localStorage
❌ Don’t include sensitive data in tokens
Connection Security
✅ Always use WSS (secure WebSocket)
✅ Implement connection timeout limits
✅ Validate all configuration parameters
✅ Log authentication events for monitoring
❌ Don’t retry forever on auth failures
❌ Never log credentials in error messages
Next Steps