Skip to main content

Behavioral Signals API Python SDK

Behavioral Signal Technologies

Discord Twitter readme.io CI Coverage Ruff Checked with mypy uv PyPI Status Downloads Python License Contributor Covenant

Official Python SDK for the Behavioral Signals API.

Analyze human behavior and detect deepfake speech using batch and real-time audio APIs. Experimental video deepfake detection is also available in batch mode.

Python SDK Documentation · Examples · PyPI · Contributing

Features

  • Behavioral Analysis — analyze human behavior from speech in batch and real-time streaming modes
  • Deepfake Detection — detect synthetic or manipulated speech in batch and real-time streaming modes
  • Video Deepfake Detection (Experimental, Batch Only) — analyze both the video frames and audio track of supported video files
  • Core Speech Attributes (Batch Only) — automatic speech recognition (ASR), speaker diarization, and language identification
  • Embeddings — retrieve speaker and behavioral embeddings from the Behavioral API, or speaker and deepfake embeddings from the Deepfakes API
  • S3 Input — submit audio and video using S3 presigned URLs
  • MCP Server — use Behavioral Signals from MCP-compatible AI assistants

Quickstart

Install

pip install behavioralsignals

Requires Python 3.10 or later.

Configure credentials

Create an account and API key in the Behavioral Signals portal.

Set your client ID (CID) and API key as environment variables:

export BEHAVIORALSIGNALS_CID="your_cid"
export BEHAVIORALSIGNALS_API_KEY="your_api_key"

The SDK will pick them up automatically:

from behavioralsignals import Client

client = Client()

You can also pass the credentials directly:

client = Client("your_cid", "your_api_key")

Analyze audio

from behavioralsignals import Client
from behavioralsignals.utils import print_results

client = Client()

process = client.behavioral.upload_audio(file_path="audio.wav")
result = client.behavioral.wait_for_result(
    pid=process.pid,
    timeout=600,
)

print_results(result.results)

upload_audio() returns a process with a unique process ID (pid). wait_for_result() polls until processing completes and returns the analysis result.

print_results() prints one line per result: the start and end time in seconds, the task, and the top label with its probability. Continuous tasks such as intensity have no label, only a score, and asr and diarization have a label without a probability. For a 10-second clip of one speaker, the output starts like this:

0.487 3.001 asr The birch canoe slid on the smooth plank.
0.487 3.001 diarization SPEAKER_00
0.487 3.001 language en (98.9%)
0.487 3.001 gender female (99.7%)
0.487 3.001 age 18 - 22 (46.8%)
0.487 3.001 emotion sad (70.6%)
...
0.487 3.001 intensity 0.0873

Each row also has prediction, the list of all labels with their probabilities. Use result.model_dump() to get the results as a dictionary.

To include speaker and behavioral embeddings:

process = client.behavioral.upload_audio(
    file_path="audio.wav",
    embeddings=True,
)

Deepfake Detection

Audio

Batch deepfake detection follows the same workflow as Behavioral Analysis:

from behavioralsignals import Client
from behavioralsignals.utils import print_results

client = Client()

process = client.deepfakes.upload_audio(file_path="audio.wav")
result = client.deepfakes.wait_for_result(
    pid=process.pid,
    timeout=600,
)

print_results(result.results)

To include speaker and deepfake embeddings:

process = client.deepfakes.upload_audio(
    file_path="audio.wav",
    embeddings=True,
)

Experimental Generator Detection

Generator detection is an experimental batch feature that attempts to identify the model used to generate deepfake audio.

process = client.deepfakes.upload_audio(
    file_path="audio.wav",
    enable_generator_detection=True,
)

See the generator detection documentation for details and supported generators.

Experimental Video Deepfake Detection

Video deepfake detection is available in batch mode only and is currently experimental.

process = client.deepfakes.upload_video(file_path="video.mp4")
result = client.deepfakes.wait_for_video_result(
    pid=process.pid,
    timeout=600,
)

Unlike an audio result, a video result contains two separate lists:

  • audio_results — deepfake detection results for the video's audio track
  • video_results — deepfake detection results for the video frames

For example:

print_results(result.video_results)

You can also submit a video using an S3 presigned URL with upload_s3_presigned_video_url() and inspect video processes using list_video_processes() and get_video_process().

See the video deepfake documentation for supported formats, limits, and the current experimental status.

Streaming

Both the Behavioral and Deepfakes APIs support real-time audio streaming over gRPC.

To stream an audio file:

from behavioralsignals import Client, StreamingOptions
from behavioralsignals.utils import make_audio_stream, print_results

client = Client()

audio_stream, sample_rate = make_audio_stream(
    "audio.wav",
    chunk_size=0.25,
)

options = StreamingOptions(
    sample_rate=sample_rate,
    encoding="LINEAR_PCM",
)

for result in client.behavioral.stream_audio(
    audio_stream=audio_stream,
    options=options,
):
    print_results(result.results)

chunk_size is specified in seconds, so 0.25 corresponds to 250 ms.

stream_audio() can also accept your own Iterator[bytes], for example from a microphone or live call.

For real-time deepfake detection, use the same interface:

for result in client.deepfakes.stream_audio(
    audio_stream=audio_stream,
    options=options,
):
    print_results(result.results)

See the streaming examples and streaming documentation for more.

Available Methods

client.behavioral and client.deepfakes expose the same methods for audio. Video methods are available only on client.deepfakes.

Method What it does
upload_audio(file_path, ...) Uploads an audio file and returns the process, including its pid
upload_s3_presigned_url(url, ...) Submits audio using an S3 presigned URL
wait_for_result(pid, timeout=None) Waits for a process to finish and returns its results
get_result(pid) Returns the results of a finished process
get_process(pid) Returns a process and its current status
list_processes(...) Lists audio processes
stream_audio(audio_stream, options) Streams audio and yields results as they arrive
upload_video(file_path, ...) Deepfakes only: uploads a video file
upload_s3_presigned_video_url(url, ...) Deepfakes only: submits video using an S3 presigned URL
wait_for_video_result(pid, timeout=None) Deepfakes only: waits for a video process to finish and returns its results
get_video_result(pid) Deepfakes only: returns the results of a finished video process
get_video_process(pid) Deepfakes only: returns a video process and its status
list_video_processes(...) Deepfakes only: lists video processes

behavioralsignals.utils also has two helpers: make_audio_stream(file_path, chunk_size=0.25) turns an audio file into chunks for stream_audio(), and print_results(items) prints result rows as shown in Analyze audio.

For detailed parameters and result schemas, see the full API documentation.

Timeouts and Error Handling

Batch API

Batch HTTP API errors raise BehavioralSignalsError. Its status_code contains the HTTP status code.

from behavioralsignals import BehavioralSignalsError, Client

client = Client()

try:
    result = client.behavioral.get_result(pid=12345)
except BehavioralSignalsError as error:
    print(error.status_code, error)

wait_for_result() and wait_for_video_result() also raise:

  • TimeoutError if processing has not finished within the supplied timeout
  • RuntimeError if the process finishes unsuccessfully, for example because of insufficient credits

Network problems raise the usual requests exceptions, such as requests.ConnectionError.

Each HTTP request also has its own timeout. By default, the SDK allows 10 seconds to connect and up to 60 seconds waiting for the server, or 300 seconds for uploads.

You can customize these limits when creating the client:

client = Client(
    timeout=(10, 120),
    upload_timeout=(10, 900),
)

These request timeouts are separate from the overall timeout passed to wait_for_result().

If an upload request times out, the server may still have received the file and started processing it. Check list_processes() — or list_video_processes() for videos — before uploading the same file again.

Streaming API

Streaming uses gRPC rather than the batch HTTP API. Streaming failures can therefore raise grpc.RpcError instead of BehavioralSignalsError.

import grpc

try:
    for result in client.behavioral.stream_audio(
        audio_stream=audio_stream,
        options=options,
    ):
        ...  # handle results
except grpc.RpcError as error:
    print(error.code(), error.details())

Use with AI Assistants (MCP)

The SDK includes an MCP server (available since version 0.7.0), so AI assistants such as Claude Code, Codex, Claude Desktop, and Cursor can analyze audio and video files for you.

The setups below start the server with uvx, so install uv first.

The server reads credentials from BEHAVIORALSIGNALS_CID and BEHAVIORALSIGNALS_API_KEY. Your assistant starts the server, so provide them in the assistant's MCP configuration as shown below.

Claude Code

With the two variables set in your shell, run:

claude mcp add --env BEHAVIORALSIGNALS_CID="$BEHAVIORALSIGNALS_CID" \
  --env BEHAVIORALSIGNALS_API_KEY="$BEHAVIORALSIGNALS_API_KEY" --transport stdio \
  behavioralsignals -- uvx --python ">=3.10" --from "behavioralsignals[mcp]" behavioralsignals-mcp

This adds the server to the current project only. Your key stays out of your shell history and out of the repository.

Codex

With the two variables set in your shell, run:

codex mcp add behavioralsignals --env BEHAVIORALSIGNALS_CID="$BEHAVIORALSIGNALS_CID" \
  --env BEHAVIORALSIGNALS_API_KEY="$BEHAVIORALSIGNALS_API_KEY" \
  -- uvx --python ">=3.10" --from "behavioralsignals[mcp]" behavioralsignals-mcp

This adds the server for all your projects in ~/.codex/config.toml.

Claude Desktop and Cursor

Add this to claude_desktop_config.json (Claude Desktop: Settings > Developer > Edit Config) or ~/.cursor/mcp.json:

{
  "mcpServers": {
    "behavioralsignals": {
      "command": "uvx",
      "args": [
        "--python",
        ">=3.10",
        "--from",
        "behavioralsignals[mcp]",
        "behavioralsignals-mcp"
      ],
      "env": {
        "BEHAVIORALSIGNALS_CID": "your_cid",
        "BEHAVIORALSIGNALS_API_KEY": "your_api_key"
      }
    }
  }
}

If the app cannot find uvx, use its full path (which uvx).

MCP Tools

The server exposes four tools:

Tool What it does
analyze_behavior Uploads an audio file or S3 presigned URL for behavioral analysis and returns the results
detect_deepfake Uploads an audio or video file, or an S3 presigned URL, for deepfake detection and returns the results
get_result Returns the results of a process, in pages, optionally filtered to specific tasks
list_processes Lists processes, newest first, including the failure reason when available

Notes:

  • Each upload uses API credits, and files named in MCP tool calls are sent to the Behavioral Signals API.
  • Upload tools wait up to wait_seconds (45 seconds by default, 50 seconds at most). If processing takes longer, they return the process ID so the assistant can check it later with get_result.
  • Do not commit configuration files containing your API key.

Running the MCP Server Manually

With uv installed, run the server without installing the package:

uvx --python ">=3.10" --from "behavioralsignals[mcp]" behavioralsignals-mcp

Or install the MCP extra with pip:

pip install "behavioralsignals[mcp]"
behavioralsignals-mcp

Requirements

  • Python 3.10+
  • A Behavioral Signals account and API key

ffmpeg is needed by make_audio_stream() for formats other than WAV, such as mp3.

Documentation and Examples

Contributing

Contributions are welcome. See CONTRIBUTING.md for development setup, testing, formatting, and pull request guidelines.

Please report security issues according to SECURITY.md.

License

Licensed under the Apache License 2.0. See LICENSE.

Metadata

Release files for behavioralsignals 0.7.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for behavioralsignals 0.7.1
File Size Uploaded
behavioralsignals-0.7.1.tar.gz 47.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for behavioralsignals 0.7.1
File Interpreter ABI Platform
behavioralsignals-0.7.1-py3-none-any.whl Python 3 none any Details

Total release size: 84.2 kB

Release files / behavioralsignals-0.7.1.tar.gz

Download URL behavioralsignals-0.7.1.tar.gz
Size 47.3 kB
Tags Source
SHA-256 checksum
How to use checksums
8c366a64f19c9757844a5175d9f96895105098657369040132fd0d082f6b3b8d
BLAKE2b-256 checksum
How to use checksums
7fdc23ad416e1ff178afc2364b26a656db14ae1015ef9272807fe86f0b5e30be
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / behavioralsignals-0.7.1-py3-none-any.whl

Download URL behavioralsignals-0.7.1-py3-none-any.whl
Size 37.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3a00e34f6cb8a59c4832e9d8ed2b4121be033d968abfc7170bc1f37a1abeaf64
BLAKE2b-256 checksum
How to use checksums
aa23a8fc07c43cafde767e2107c10e860287f8cfb66ccb4a0dced8bdbad6a78d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.7.1 This release

2 release files

0.7.0

2 release files

0.6.0

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page