Focus
Flag the moments you care about
Focus flags the moments you care about. You list the labels you want to watch, e.g. angry or low_confidence, and the API adds a focus result to every utterance or segment where that label is likely but is not the finalLabel, so check finalLabel too. high_stress, low_confidence and negative_tone are combined labels: they are flagged whenever their score is high enough.
Focus is available for the Behavioral API, in batch and streaming.
Labels
| Label | What it flags |
|---|---|
angry, happy | Moments with likely anger or happiness (emotion) |
negative, positive | Moments with likely negative or positive sentiment (positivity) |
slow, fast | Moments with likely slow or fast speech (speaking_rate) |
high_stress | Moments with signs of stress, combined from several behavioral signals |
low_confidence | Moments with signs of low confidence, combined from several behavioral signals |
negative_tone | Moments with a negative tone, combined from several behavioral signals (negative uses only positivity) |
Sensitivity
sensitivity sets how easily a moment is flagged:
low: flags fewer moments, only the clearer onesdefault: the default, if you leave it emptyhigh: flags more moments, including the subtler ones
🌐 cURL Example (batch)
Submit your audio as usual. When processing is complete, add the focus and, optionally, the sensitivity query params to the results request:
curl --request GET \
--url 'https://api.behavioralsignals.com/v5/clients/your-client-id/processes/pid/results?focus=angry,low_confidence&sensitivity=high' \
--header 'X-Auth-Token: your-api-token' \
--header 'accept: application/json'Focus is computed when you read the results, so you can read the same process again with other labels or another sensitivity, without uploading the audio again.
🐍 Python SDK Example
Batch:
from behavioralsignals import Client
client = Client()
process = client.behavioral.upload_audio(file_path="audio.wav")
result = client.behavioral.wait_for_result(
pid=process.pid,
focus=["angry", "low_confidence"],
sensitivity="high",
)
for r in result.results:
if r.task == "focus":
print(r.st, r.et, r.finalLabel)Streaming:
from behavioralsignals import Client, StreamingOptions
from behavioralsignals.utils import make_audio_stream
client = Client()
audio_stream, sample_rate = make_audio_stream("audio.wav", chunk_size=0.25)
options = StreamingOptions(
sample_rate=sample_rate,
encoding="LINEAR_PCM",
focus=["angry", "low_confidence"],
sensitivity="high",
)
for response in client.behavioral.stream_audio(audio_stream=audio_stream, options=options):
for r in response.results:
if r.task == "focus":
print(r.st, r.et, r.finalLabel)Streaming with gRPC
Add a focus field to the AudioConfig of the first message (see the proto file):
config = pb.AudioConfig(
encoding=pb.AudioEncoding.LINEAR_PCM,
sample_rate_hertz=16000,
focus=pb.FocusConfig(labels=["angry", "low_confidence"], sensitivity="high"),
)Response
Each flagged moment is one extra result with task set to focus and finalLabel set to suspected_<label>. It has the same id, startTime, endTime and level as the utterance or segment it flags:
{
"id": "3",
"startTime": "12.48",
"endTime": "16.02",
"task": "focus",
"prediction": [
{
"label": "low_confidence",
"posterior": "0.6124"
}
],
"finalLabel": "suspected_low_confidence",
"level": "utterance"
}The posterior is the likelihood of the label. For high_stress, low_confidence and negative_tone it is a combined score. In batch results, each focus result comes right after the other results of its utterance.
Notes
- A process that never used focus returns the same results as before.
- An unknown or empty label list, an unknown sensitivity, or
sensitivitywithoutfocusis rejected: with400in batch andINVALID_ARGUMENTin streaming.- In streaming, send focus in the first message: once it is set, later values are ignored. Focus is not available for deepfake detection streams.
- In batch, focus results are not stored: they are added to the response each time you ask for them. A stream's focus results are stored with its results, and asking for
focusagain replaces them.
Updated 7 days ago

