Skip to main content

Error Codes

The Kallglot API uses conventional HTTP response codes and returns detailed error information in JSON format.

HTTP Status Codes

CodeDescription
200Success
201Created
202Accepted (async processing)
400Bad Request - Invalid parameters
401Unauthorized - Invalid or missing API key
403Forbidden - Insufficient permissions
404Not Found - Resource doesn’t exist
409Conflict - Resource already exists
422Unprocessable Entity - Validation failed
429Too Many Requests - Rate limit exceeded
500Internal Server Error
502Bad Gateway - Upstream service error
503Service Unavailable - Temporary outage

Error Response Format

All errors follow this structure:
{
  "error": {
    "code": "invalid_api_key",
    "message": "The API key provided is invalid or has been revoked.",
    "type": "authentication_error",
    "param": null,
    "doc_url": "https://developer.kallglot.com/errors#invalid_api_key"
  }
}
FieldDescription
codeMachine-readable error code
messageHuman-readable error description
typeError category
paramThe parameter that caused the error (if applicable)
doc_urlLink to documentation about this error

Error Types

authentication_error

Problems with API authentication.
CodeDescription
invalid_api_keyThe API key is malformed or doesn’t exist
expired_api_keyThe API key has expired
revoked_api_keyThe API key has been revoked
invalid_tokenWebSocket or session token is invalid
expired_tokenToken has expired

authorization_error

The API key is valid but lacks permissions.
CodeDescription
insufficient_permissionsAPI key lacks required permissions
organization_suspendedOrganization account is suspended
feature_not_availableFeature not available on your plan

validation_error

Request validation failed.
CodeDescription
invalid_requestGeneral validation error
missing_required_fieldRequired field is missing
invalid_field_valueField value is invalid
invalid_language_codeLanguage code not recognized
invalid_modeSession mode is invalid
invalid_providerProvider configuration is invalid

not_found_error

Resource doesn’t exist.
CodeDescription
session_not_foundSession ID doesn’t exist
recording_not_foundRecording ID doesn’t exist
analysis_not_foundAnalysis ID doesn’t exist
transcript_not_foundTranscript not available
webhook_endpoint_not_foundWebhook endpoint doesn’t exist

invalid_request_error

Request is invalid for the current state.
CodeDescription
session_already_endedSession has already ended
session_not_activeSession is not in active state
recording_not_readyRecording is still processing
analysis_not_completeAnalysis is still processing
idempotency_key_in_useIdempotency key already used with different parameters

rate_limit_error

Rate limit exceeded.
CodeDescription
rate_limit_exceededToo many requests
concurrent_session_limitToo many concurrent sessions

processing_error

Server-side processing failed.
CodeDescription
transcription_failedTranscription processing failed
translation_failedTranslation processing failed
recording_failedRecording generation failed
analysis_failedAnalysis processing failed

provider_error

Telephony provider error.
CodeDescription
provider_connection_failedFailed to connect to provider
provider_call_failedCall failed
provider_timeoutProvider request timed out

server_error

Internal server error.
CodeDescription
internal_errorUnexpected server error
service_unavailableService temporarily unavailable
upstream_errorUpstream service failure

Handling Errors

JavaScript/Node.js

try {
  const response = await fetch('https://api.kallglot.com/v1/sessions', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer sk_live_xxx',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      mode: 'bidirectional_translation',
      source_language: 'de',
      target_language: 'en'
    })
  });

  if (!response.ok) {
    const errorBody = await response.json();
    throw {
      type: errorBody.error.type,
      param: errorBody.error.param,
      message: errorBody.error.message,
      headers: Object.fromEntries(response.headers.entries())
    };
  }
} catch (error) {
  if (error.type === 'authentication_error') {
    // Handle auth errors
    console.error('Check your API key');
  } else if (error.type === 'validation_error') {
    // Handle validation errors
    console.error(`Invalid parameter: ${error.param}`);
  } else if (error.type === 'rate_limit_error') {
    // Handle rate limiting
    const retryAfter = error.headers['retry-after'];
    await sleep(retryAfter * 1000);
    // Retry the request
  } else {
    // Handle other errors
    console.error(`Error: ${error.message}`);
  }
}

Python

import requests
import time

try:
    response = requests.post(
        'https://api.kallglot.com/v1/sessions',
        headers={
            'Authorization': 'Bearer sk_live_xxx',
            'Content-Type': 'application/json'
        },
        json={
            'mode': 'bidirectional_translation',
            'source_language': 'de',
            'target_language': 'en'
        }
    )
    response.raise_for_status()
except requests.HTTPError as e:
    if e.response.status_code == 429:
        retry_after = int(e.response.headers.get('Retry-After', 1))
        time.sleep(retry_after)
    else:
        error = e.response.json().get('error', {})
        print(f"Error: {error.get('code')} - {error.get('message')}")

Retry Logic

Some errors are transient and can be retried:
Error TypeRetry?Strategy
rate_limit_errorYesUse Retry-After header
server_errorYesExponential backoff
provider_errorMaybeDepends on error code
validation_errorNoFix the request
authentication_errorNoCheck credentials

Exponential Backoff

async function withRetry(fn, maxRetries = 3) {
  let lastError;

  for (let i = 0; i < maxRetries; i++) {
    try {
      return await fn();
    } catch (error) {
      lastError = error;

      if (!isRetryable(error)) {
        throw error;
      }

      const delay = Math.pow(2, i) * 1000;  // 1s, 2s, 4s
      await sleep(delay);
    }
  }

  throw lastError;
}

function isRetryable(error) {
  return error.type === 'server_error' ||
         error.type === 'rate_limit_error' ||
         error.code === 'provider_timeout';
}

WebSocket Error Codes

WebSocket connections use these close codes:
CodeReasonDescription
1000NormalClean close
1008Policy ViolationAuthentication failed
1011Internal ErrorServer error
4000Session EndedSession was ended
4001Token ExpiredSession token expired
4002Rate LimitedToo many messages
4003Invalid MessageMalformed message
ws.on('close', (code, reason) => {
  switch (code) {
    case 1000:
      console.log('Connection closed normally');
      break;
    case 4000:
      console.log('Session ended');
      break;
    case 4001:
      console.log('Token expired - reconnect with new token');
      break;
    case 4002:
      console.log('Rate limited - slow down');
      break;
    default:
      console.log(`Closed: ${code} - ${reason}`);
  }
});

Common Issues

Cause: API key is incorrect, expired, or revoked.Solution:
  1. Check the key starts with sk_live_ or sk_test_
  2. Verify the key in your Developer Portal
  3. Create a new key if needed
Cause: Language code not recognized.Solution:
  1. Use ISO 639-1 codes (e.g., de, en, fr)
  2. Check Supported Languages
  3. For regional variants, use format like de-CH
Cause: Session ID doesn’t exist or has expired.Solution:
  1. Verify the session ID format (sess_xxx)
  2. Check if session has ended
  3. Sessions expire 24 hours after ending
Cause: Too many API requests.Solution:
  1. Check Retry-After header
  2. Implement exponential backoff
  3. Consider upgrading your plan