Skip to content

Documentation / Guides / Recording and GCS

Coordinate recording with GCS

VAANI coordinates bounded recording start/observe/stop. The deployment owns consent, legality, storage, retention, credentials, and access.

Install and configure

Select the recording-gcs extra in the authenticated, exact-pinned runtime install.

from vaani import Assistant, RecordingRequirement, bootstrap_environment
from vaani.adapters.recording.gcs import (
    GCSRecordingConfig,
    LiveKitGCSRecordingAdapter,
)

environment = bootstrap_environment()
recording = None
if environment.profile.recording_requirement is not RecordingRequirement.DISABLED:
    recording = LiveKitGCSRecordingAdapter(
        GCSRecordingConfig(
            adapter_id="recording-gcs",
            bucket_name="private-call-recordings",
            credential_source=recording_credentials,
            object_prefix="voicebot/",
            delete_object_on_stop=False,
        )
    )


assistant = Assistant(
    name="Recorded support",
    prompt="Help the caller.",
    environment=environment,
    recording=recording,
)
assistant.check()

environment.profile is the exact immutable ResolvedPreset selected for startup. Its typed recording_requirement is safe to read before constructing the Adapter or calling Assistant.check(). The immutable preset selects measurement.recording as exactly DISABLED, BEST_EFFORT, or REQUIRED. An enabled preset must list the recording-gcs extra and receive the approved LiveKitGCSRecordingAdapter; a disabled preset rejects an Adapter binding. Application code cannot override the preset's requirement per call.

object_prefix must be relative and cannot traverse parent directories. Bucket names and credentials should come from protected deployment configuration.

The credential source may resolve a tested backend or the live binding: livekit_url, livekit_api_key, livekit_api_secret, and gcp_credentials_json. The room is never accepted from credentials. The LiveKit transport derives an opaque call-scoped recording authority from the exact accepted handoff, so two concurrent rooms cannot select each other's recording. Never place room, job, credential, or storage values in docs, profile IDs, locks, or results.

The repository's optional smoke reads VAANI_GCS_BUCKET, VAANI_GCS_ROOM_NAME, LIVEKIT_URL, LIVEKIT_API_KEY, LIVEKIT_API_SECRET, and GOOGLE_APPLICATION_CREDENTIALS_JSON; region may be supplied as VAANI_GCS_REGION. These are smoke/deployment conventions, not ambient reads by the adapter.

Choose requirement per call

RecordingPolicy(RecordingRequirement.DISABLED, None)
RecordingPolicy(RecordingRequirement.BEST_EFFORT, "recording-gcs")
RecordingPolicy(RecordingRequirement.REQUIRED, "recording-gcs")
  • BEST_EFFORT: retain failure evidence and continue.
  • REQUIRED: start must be confirmed before greeting; start failure or later loss forces termination. A required stop failure also prevents a false COMPLETED or TRANSFERRED result.

The result contains an opaque RecordingArtifactReference only after stop has reported complete and the Adapter has positively observed the exact object in the configured bucket within the stop deadline. A failed start, incomplete egress, or missing object publishes no artifact. Results never contain raw audio, a durable public URL, signed URL, bucket name, object name, room/job identity, or credential.

The generated production lock includes the requirement, Adapter manifest, installed distribution, and a SHA-256 binding identity. The binding digest also contributes to call provenance. It changes when the bucket, object prefix, deletion choice, or credential scope changes, while the underlying values remain absent from locks and results. Regenerate and review the lock after any recording configuration change.

Cleanup and live proof

Start and stop use the preset's bounded recording_start_seconds and recording_stop_seconds deadlines. Forced cancellation receives a separate bounded cleanup budget within absolute Closure. VAANI retains ownership of pending/active egress and backend tasks until cancellation and close finish; if that budget is exhausted, it fences the operation and records an explicit cleanup quarantine rather than treating it as success. Teardown applies this discipline when a call ends, fails, transfers, or its owner is cancelled.

Before traffic, prove start, observed recording, stop, required-vs-best-effort failure, deadline expiry, and leak-free Adapter cleanup. Confirm bucket access, retention, deletion, audit logging, and redaction with the responsible privacy owner. A real call must verify legally approved consent wording, media capture, object creation, access, and retention in the target GCS project. VAANI coordinates lifecycle only; the deployment remains the data controller and owns consent, credentials, storage, access, retention, deletion, and incident response.

Next: result publishing or production readiness.