Voice Govern your voice agent Voice governance

Voice governance

Rules for what your voice agents may say, in which voice, and with whose permission. They apply to every call, whatever framework the agent uses. To connect an agent, see Govern your voice agent.

Voice governance is available on Pro and Enterprise. Changing the policy or registry needs the admin role; viewers can read them.

Disclosure, marking and consent are recorded in the audit log as evidence of what happened. Whether a setting satisfies a particular law, such as the EU AI Act's transparency duties, is for your counsel to decide.

Disclosure

A Disclosure tells the listener, at the start of a Voice Conversation, that they're talking to an AI. The policy sets what happens when the first Speech Synthesis of a conversation doesn't contain it.

ModeWhat happens
log (default)The call goes through. The audit entry records whether the Disclosure was present or missing. With no phrases and no inject text configured, nothing is checked and the entry records off.
enforceA first Speech Synthesis without the Disclosure is refused with 422 and code disclosure_missing. Nothing is synthesized or charged. With no phrases configured, every first Speech Synthesis is refused, so list at least one.
injectForgebench prepends the workspace's inject_text for the conversation's language to the first Speech Synthesis. The audit entry records injected. If no inject text is set for the language or the default language, the call is refused as under enforce.

Phrase matching. The Disclosure is present when the first Speech Synthesis contains one of the workspace's phrases for the conversation's language, such as "I'm an AI assistant". You set phrases and inject text per language. default_language applies when a request doesn't specify one.

Which call is first. The session key (metadata.session or the X-Forgebench-Session header) identifies the conversation. Send one on every voice call.

  • Later Speech Synthesis calls in the conversation are audited as not_first and aren't checked.
  • A call with no session key is always treated as first.
  • The first-call marker lasts 24 hours.
  • Conversations are tracked per agent, or per API key when there's no agent.
  • A call that fails before it's served doesn't use up the first slot. That includes enforce refusals, budget, plan and rate-limit refusals, guardrail blocks and provider errors.
  • Session keys are at most 128 characters. Longer keys get 422 invalid_session, or a protocol error and close 1008 on streaming sockets.

Per-agent override. An agent's voice settings can set its own mode (config.voice.disclosure_mode: log, enforce or inject), overriding the workspace policy.

from forgebench import Forgebench, PermissionDeniedError, ValidationError

client = Forgebench(api_key="sk_...", base_url="https://api.forgebench.ai")

try:
  client.voice.policy.update(
      disclosure_mode="inject",
      disclosure_phrases={"en": ["i'm an ai assistant", "i am an ai"]},
      inject_text={"en": "Hi, I'm an AI assistant."},
      default_language="en",
  )
  print(client.voice.policy.get()["disclosure_mode"])
except PermissionDeniedError as e:
  print("admin role required:", e.code)
except ValidationError as e:
  print("rejected:", e.code)

Recording text on traces

voice_trace_content (default false) controls whether text is recorded on traces. It covers both Forgebench's transcripts and Speech Synthesis input, and the text in telemetry your LiveKit or Pipecat pipeline sends. While it's off, no transcript or speech text is recorded. Turn it on in Settings → Voice (Record text on traces) or with voice.policy.update(voice_trace_content=True). Secrets are always removed from recorded text. See Observe your voice agent.

Marking

Some Speech Synthesis providers embed a mark in their output identifying it as machine generated. A workspace can require models that do this. Forgebench doesn't watermark audio itself.

Each speech model has a marking level:

LevelMeaning
confirmedThe provider documents that its output carries an identifiable mark.
claimedThe provider says its output is marked, without documentation detailed enough to confirm it.
noneNo marking is documented.

The setting is off by default. Turn on marking_required and set marking_min_level to claimed (accepts confirmed and claimed) or confirmed (accepts confirmed only). A Speech Synthesis on a model below the level is refused with 403 and code marking_required.

Levels as of the last review, 2026-10-09:

Provider and modelLevel
Gemini TTSconfirmed
OpenAI speech modelsclaimed
ElevenLabsclaimed
Deepgram Auranone
Google Chirp 3 HDnone

Provider behaviour changes. The catalog shows each model's current level and review date.

A Voice Asset is a named synthetic voice your agents may use, with its source and permitted uses. A Consent Record is timestamped evidence that a person agreed to a specific use, such as having their voice cloned or being recorded.

Voice Asset kindRule
stockA provider's own voice. Open to all agents by default.
brandA voice your company owns. Must reference a valid (unrevoked, unexpired) Consent Record, or registration is refused with 422 consent_required. Every use re-checks the consent.
clonedA clone of a person's voice. Same rule as brand.

voice_assets_required_for sets which voices must be registered, active and allowed for the calling agent:

  • cloned_brand (default): a registered voice must be active, unexpired, allowed for the agent and, if cloned or brand, still consented. An unregistered voice is treated as stock and is open, so register every cloned or brand voice, or use all. Registered voices are matched on provider and voice id when the provider can be derived from the model.
  • all: every voice must be a registered Voice Asset.
  • none: the registry is not enforced.

A Speech Synthesis with a voice the policy doesn't allow is refused with 403 voice_not_allowed.

  • Limit a Voice Asset to specific agents with allowed_agent_ids, and give it an expiry.
  • licensed_uses is for your records only; calls aren't checked against it.
  • A revoked Voice Asset is no longer active.
  • Revoking a Consent Record stops every cloned voice that depends on it.
  • Registering a provider voice twice returns 409 voice_asset_exists.
from forgebench import ConflictError, ValidationError

try:
  consent = client.voice.consents.create(
      subject_name="Jane Rivera",
      purpose="voice_clone",
      scope="Support agent voice, English, until revoked",
      evidence_uri="https://contracts.example.com/jr-2026-10",
  )
  asset = client.voice.assets.create(
      provider="elevenlabs",
      provider_voice_id="v_123",
      display_name="Jane (support)",
      kind="cloned",
      consent_record_id=consent["id"],
  )
  # Withdraw later:
  client.voice.assets.revoke(asset["id"])
  client.voice.consents.revoke(consent["id"])
except ConflictError:
  print("that provider voice is already registered")
except ValidationError as e:
  print("rejected:", e.code)

Guardrails on voice

Your guardrails apply to voice as they do to chat:

  • Speech input, always. The text sent to Speech Synthesis is scanned before anything is synthesized. A blocked input returns 400 and is audited as blocked, with no call to the provider.
  • Transcripts, opt-in. Scanning the text produced by Transcription is off by default. Turn on transcript_guardrails in the voice policy to scan it.

What is recorded

Each voice call writes one audit entry and one metering event. The audit entry records the model, Usage Unit and quantity, the Disclosure outcome (present, missing, injected, not_first or off), the Voice Asset, and the model's marking level.

Forgebench never stores recordings or synthesized audio. If you need recordings, keep them in your own systems.

Availability

CapabilityFreeProEnterprise
Voice routes (Transcription, Speech Synthesis, streaming)—
Disclosure, marking, Voice Assets, Consent Records—

On other plans a voice call returns 402 plan_required, after auth checks (401, 403). See Billing.

Refusal codes

A refusal body is {"detail": {"code": "...", "message": "..."}}. Speech checks run in order (Voice Asset, marking, Disclosure), and the first failure sets the code. Refused calls are audited as blocked and aren't charged.

StatusCodeCause
422disclosure_missingDisclosure mode is enforce and the first Speech Synthesis lacks it.
403voice_not_allowedThe voice is not an allowed Voice Asset for this agent.
403marking_requiredThe model's marking level is below the policy minimum.
403model_not_allowedThe key's model allowlist excludes the model.
422consent_requiredRegistering a cloned or brand Voice Asset without a valid Consent Record.
409voice_asset_existsThat provider voice is already registered.
413audio too longTranscription audio is longer than the limit (600 seconds by default).
402plan_requiredThe plan does not include voice.
402budget codesA budget or pool limit was reached. See Errors and refusals.

Next

Cookie settings

Our Cookie Policy lists every cookie and what it does.