Back to site
ProsodyAI Docs
API Reference

Analyze Endpoint

Analyze audio for emotion recognition

Analyze Endpoint

Analyze a single audio segment for emotion recognition.

Endpoint

POST /v1/analyze

Request

Headers

HeaderRequiredDescription
AuthorizationYesBearer psk_your_api_key
Content-TypeYesapplication/json or multipart/form-data

Body (JSON)

{
  "audio_url": "https://storage.example.com/audio.wav",
  "vertical": "contact_center",
  "features": ["emotion", "prosody", "vad", "vertical"],
  "transcript": "I've been waiting for 30 minutes!",
  "speaker_id": "customer",
  "session_id": "call-12345",
  "metadata": {
    "call_id": "abc123",
    "queue": "support"
  }
}

Body (Multipart)

curl -X POST https://api.prosody.ai/v1/analyze \
  -H "Authorization: Bearer psk_your_api_key" \
  -F "audio=@recording.wav" \
  -F "vertical=contact_center" \
  -F "features=emotion,prosody,vad"

Parameters

ParameterTypeRequiredDescription
audiofile*Audio file (multipart)
audio_urlstring*URL to audio file
audio_base64string*Base64-encoded audio
verticalstringNoTarget vertical
featuresarrayNoFeatures to include
transcriptstringNoAudio transcript
speaker_idstringNoSpeaker identifier
session_idstringNoSession identifier
metadataobjectNoCustom metadata

* One of audio, audio_url, or audio_base64 is required.

Supported Audio Formats

FormatMIME TypeNotes
WAVaudio/wavRecommended
MP3audio/mpeg
OGGaudio/ogg
WebMaudio/webm
FLACaudio/flac
M4Aaudio/mp4

For best results, use 16kHz sample rate, 16-bit depth, mono audio.

Features

FeatureDescription
emotionBase emotion classification
prosodyProsodic features (pitch, energy, rhythm)
vadValence-Arousal-Dominance scores
verticalVertical-specific state and metrics
predictionForward predictions (requires session)

Response

Success (200 OK)

{
  "emotion": "frustrated",
  "confidence": 0.87,
  "emotion_probabilities": {
    "neutral": 0.05,
    "happy": 0.02,
    "sad": 0.08,
    "angry": 0.15,
    "fearful": 0.03,
    "disgusted": 0.02,
    "surprised": 0.01,
    "contempt": 0.12,
    "anxious": 0.10,
    "confused": 0.08,
    "excited": 0.01,
    "amused": 0.01,
    "content": 0.02,
    "frustrated": 0.87
  },
  "valence": -0.6,
  "arousal": 0.7,
  "dominance": 0.4,
  "prosody": {
    "pitch": {
      "mean": 180.5,
      "std": 45.2,
      "min": 95.0,
      "max": 320.0,
      "range": 225.0
    },
    "energy": {
      "mean": 0.65,
      "std": 0.18
    },
    "rhythm": {
      "speech_rate": 4.2,
      "pause_rate": 0.8,
      "average_pause_duration": 0.35
    },
    "voice_quality": {
      "jitter": 0.023,
      "shimmer": 0.045,
      "hnr": 12.5
    }
  },
  "state": "frustrated",
  "metrics": {
    "csat_predicted": 2.3,
    "sentiment_trajectory": "declining",
    "escalation_risk": "high",
    "first_call_resolution_likely": false,
    "churn_risk": 0.65
  },
  "duration": 4.5,
  "processed_at": "2025-02-22T14:30:00Z",
  "request_id": "req_abc123xyz"
}

Error Responses

400 Bad Request

{
  "error": {
    "code": "validation_error",
    "message": "Invalid request parameters",
    "details": {
      "audio_url": ["Invalid URL format"],
      "vertical": ["Unknown vertical: 'invalid'"]
    }
  }
}

413 Payload Too Large

{
  "error": {
    "code": "payload_too_large",
    "message": "Audio file exceeds maximum size of 25MB"
  }
}

415 Unsupported Media Type

{
  "error": {
    "code": "unsupported_audio_format",
    "message": "Unsupported audio format: video/mp4",
    "details": {
      "supported_formats": ["audio/wav", "audio/mpeg", "audio/ogg", "audio/webm", "audio/flac"]
    }
  }
}

Examples

# With URL
curl -X POST https://api.prosody.ai/v1/analyze \
  -H "Authorization: Bearer psk_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "audio_url": "https://storage.example.com/call.wav",
    "vertical": "contact_center",
    "features": ["emotion", "vertical"]
  }'

# With file upload
curl -X POST https://api.prosody.ai/v1/analyze \
  -H "Authorization: Bearer psk_your_api_key" \
  -F "audio=@recording.wav" \
  -F "vertical=healthcare"
// With URL
const response = await fetch('https://api.prosody.ai/v1/analyze', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    audio_url: 'https://storage.example.com/call.wav',
    vertical: 'contact_center',
    features: ['emotion', 'vertical'],
  }),
});

// With file upload
const formData = new FormData();
formData.append('audio', audioFile);
formData.append('vertical', 'contact_center');

const response = await fetch('https://api.prosody.ai/v1/analyze', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${apiKey}`,
  },
  body: formData,
});
import requests

# With URL
response = requests.post(
    'https://api.prosody.ai/v1/analyze',
    headers={'Authorization': f'Bearer {api_key}'},
    json={
        'audio_url': 'https://storage.example.com/call.wav',
        'vertical': 'contact_center',
        'features': ['emotion', 'vertical'],
    },
)

# With file upload
with open('recording.wav', 'rb') as f:
    response = requests.post(
        'https://api.prosody.ai/v1/analyze',
        headers={'Authorization': f'Bearer {api_key}'},
        files={'audio': f},
        data={'vertical': 'healthcare'},
    )

Batch Analysis

Analyze multiple audio files in a single request:

POST /v1/analyze/batch
{
  "items": [
    {
      "id": "item-1",
      "audio_url": "https://storage.example.com/call1.wav"
    },
    {
      "id": "item-2", 
      "audio_url": "https://storage.example.com/call2.wav"
    }
  ],
  "vertical": "contact_center",
  "features": ["emotion", "vertical"]
}

Response:

{
  "results": [
    {
      "id": "item-1",
      "emotion": "satisfied",
      "confidence": 0.91,
      ...
    },
    {
      "id": "item-2",
      "emotion": "frustrated",
      "confidence": 0.85,
      ...
    }
  ],
  "request_id": "batch_xyz789"
}