Skip to main content
Telzino enforces guardrails on every outbound call; your CRM decides who is called, when, and on what legal basis. This guide sets out how to configure an outbound agent so both halves work together, and a baseline to start every campaign from.
This is operational guidance, not legal advice. AI-voice calls are generally treated as artificial-voice calls under the TCPA, so the consent and opt-out rules for those calls apply. Have your own counsel review your consent and calling practices before you launch.

Who is responsible for what

Every call is checked before it is dialled. A call that fails any check is refused with an error and never placed: The order shown is for illustration; any failed check stops the call.

Before you launch

  • Use production. The suppression list, retry policies, queued-retry cancellation and the compliance export are available on production only.
  • Check your API key’s scope. Retry policies belong to the account. A key scoped to a reseller or organization can read them but gets 403 insufficient_scope on create, edit or delete. Ask your Telzino contact to create policies for you, or use an account-level key.
  • Call from a server. The API sends no CORS headers, and the client secret must never reach a browser. Proxy every call through your backend, as the Agent Runbook describes.
  • Confirm outbound is unlocked. A trigger on an organization where outbound is locked returns 403 feature_locked.
  • Use a test organization first. Keep pilot and QA traffic out of live customer organizations.
  • Caller ID is set by your PBX. All outbound calls are placed through your PBX, so the number shown, and its STIR/SHAKEN attestation, follow your PBX and carrier configuration. Set the outbound caller ID there before launch. If your PBX passes the shared default number through instead and then rejects transfers on outbound calls (Zoom Phone does), turn on Use this agent’s DID or SIP user as caller ID on outbound calls in the agent’s Transfers settings (config.outbound_caller_id_use_did) so calls show the DID from the agent’s SIP registration (or its SIP username or extension when there is no DID).
Turn on contactPolicy.require_consent_basis for every outbound agent, so a call without a stated consent basis is refused with 400 consent_required and never dialled. See Outbound Compliance for the full reference.
  • Telzino checks that a basis is present. It does not verify it; your CRM is the source of truth.
  • Always send consent_reference (up to 200 characters): the CRM record or form submission that proves consent. It is stored for the audit export.
  • If you allow other, require a consent_reference with it in your own process.

Calling hours

Set calling hours on every outbound agent: with no calling_windows, Telzino applies no hours restriction at all. We recommend 09:00 to 20:00 on the callee’s local clock, stricter than the federal 8am to 9pm and inside tighter state rules such as Florida’s.
  • start_local is inclusive and end_local exclusive, so "20:00" means before 8pm. Windows can’t wrap midnight.
  • Use timezone_source: "callee_npanxx", which infers the callee’s zone from the area code. Area codes spanning two zones resolve to the dominant one, and ported or moved numbers can be wrong.
  • Send callee_timezone whenever your CRM knows it. It overrides the area-code lookup for that call and matters most for mobile numbers.
  • Turn on Reschedule out-of-window calls in your retry policy, so a call triggered outside the window is queued for the next opening (202, status scheduled) instead of refused with 409 out_of_window.

AI disclosure and greetings

Disclose the AI in the first words the callee hears: put the disclosure in the agent’s static outbound greeting, and also enable aiDisclosure so delivery is recorded on each call. An outbound call opens in this order:
  1. outboundStaticGreeting: spoken word for word, cannot be altered by the AI.
  2. The outbound greeting (outboundGreetingMessage, or a per-call greeting).
  3. The aiDisclosure text. Only position: "after_greeting" is supported.
Because the disclosure plays after the greeting, the static greeting is where it belongs if it must come first. A good opening identifies the business and the AI in one line, for example: “Hi, this is an AI assistant calling on behalf of Acme Dental.”
  • Set aiDisclosure.enabled: true explicitly; it is never defaulted.
  • Each call records disclosure_delivered (true, false, or null when none was due) and disclosure_timestamp, and both appear in the result webhook. Treat any false as an incident to review.
  • Disclosure is configured per agent. It can’t yet be made mandatory at the reseller or partner level, so lock it into your agent template.
  • required_states is stored but not yet evaluated. Treat disclosure as always on, not state-dependent.

Do-not-call and opt-outs

A number on any suppression list that covers your organization (its own, its reseller’s or its partner’s) is never dialled: the trigger returns 409 suppressed. Opt-outs heard on a call are added automatically; make sure opt-outs from any other channel land on a list the same day.
  • Opt-outs during a call are suppressed automatically. When a callee asks not to be called again, the call is marked opt_out_detected, every queued retry to that number is cancelled, and the number is added to the suppression list with created_by: "system". Which list depends on the opt-in settings; by default it is the calling organization’s. The result webhook reports opt_out_detected and suppression_added. See stopping retries.
  • Phone menus and voicemail. An opt-out found only in the transcript of a call answered by a phone menu or voicemail cancels retries but doesn’t add the number, because menu prompts such as “to opt out, press 9” are transcribed as the callee. A result with opt_out_detected: true and suppression_added: null means the number was not listed, either for this reason or because the add failed: review the call and add the number yourself if a person asked.
  • Add a number from another channel with POST /v1/organizations/{organization_id}/suppression-list, sending phone_number (E.164) and reason: "opt_out". Adding a number already on the list succeeds, so it is safe to retry.
  • Stop pending retries for opt-outs received outside a call with DELETE /v1/outbound-calls/queued?to_number=+15105550123. It cancels every scheduled retry to that number across your account; a retry already dialling is not stopped.
  • Use E.164 everywhere. Numbers are matched exactly; (510) 555-0123 does not match +15105550123.
  • Consider wide suppression. By default an opt-out heard on a call is added only to the organization that placed it, so a sibling organization can still dial the number. If you run several organizations, consider turning on Apply opt-outs partner-wide or Apply opt-outs reseller-wide. Check with counsel first: a partner-wide opt-out can block calls from unrelated businesses under the same partner, which is why it is off by default. Opt-outs from other channels can be added straight to the reseller or partner list.
  • Keypress opt-out (“press 9 to stop these calls”) has to be written into the agent’s instructions. The Keypad (DTMF) transfer toggle only maps keys to transfer destinations.

Retries and attempt caps

Let Telzino handle redials with a retry policy, and cap attempts per number so no one is called more than twice a day. Set it as the agent’s defaultRetryPolicyId, or per call with retry_policy_id. Recommended rules (outcomes not listed are never retried): Recommended contact_policy caps, enforced per number across your whole account:
  • Set on_exhausted: "webhook" with an HTTPS on_exhausted_target, so your CRM learns when a contact’s attempts are used up.
  • A call blocked by the caps returns 409 policy_violation.
  • Editing a policy doesn’t change retry chains already in progress; each call keeps the rules it started with.

Answering machine detection and voicemail

Turn on answering machine detection (AMD) and leave a short voicemail that names your business and a callback number. AMD is off by default, and the abandon-rate metric only counts calls AMD classified as answered by a person, so without it your abandon rate reports null.
  • Voicemail message. Keep it to two sentences: who is calling, why, and the number to call back. Set it on the agent (voicemailMessage) or per call (voicemail_message).
  • IVR navigation. Leave IVR navigation off unless you call businesses with phone menus. It requires AMD; enabling it with AMD off returns 400 and places no call.
  • Test AMD on your own phones. A live person misread as a machine hears a voicemail or nothing at all.

Concurrency, pacing and abandon rate

Start a new campaign at 2 to 3 concurrent calls per agent, paced by your CRM, and raise it only after reviewing the first day’s results.
  • The concurrency limit is configured per agent; ask your Telzino contact for your agents’ limit.
  • A trigger past the limit returns 429 agent_at_capacity; the call is not queued. Back off and retry with an increasing delay (for example 30 s, 60 s, 120 s).
  • A call counts as abandoned when a person answers and hangs up before the agent engages. Each agent is flagged in GET /v1/metrics when its abandon rate passes abandon_rate_alert_threshold, which defaults to 3%, the FCC limit. Review flagged agents before the next campaign day.

CRM integration

Your CRM triggers each call with POST /v1/agents/{agentId}/outbound-calls and receives the result on a callback_url. Send these fields on every trigger: Handle the responses:
  • Results. The callback payload includes your metadata, the outcome, opt_out_detected, suppression_added, and disclosure_delivered / disclosure_timestamp. Update the contact, and mark it do-not-call on any opt-out. Telzino has already added the number to the suppression list unless suppression_added is null.
  • Verifying results. The per-call callback_url is not signed. Use an unguessable callback URL and match each result to a call id you created. Event webhooks are signed with HMAC if you need verifiable delivery.
  • Compliance export. GET /v1/outbound-calls/export returns every dialled number, including unanswered attempts, with the consent basis each was placed under. Run it at the end of each campaign and archive it. Exports too large return 413 rather than a partial file; narrow the date range.
  • Usage. Outbound minutes appear in the standard minutes and billing reports alongside inbound.
Start every outbound agent from this baseline, then adjust per use case with your counsel’s sign-off. The agent-level controls in one update (PUT /v1/agents/{agentId}):

Pre-launch checklist

Run every check in a test organization before the first live campaign.
  • A call with no consent_basis is refused with 400 consent_required
  • A call outside calling hours is refused (409 out_of_window) or scheduled for the next opening
  • A number on the suppression list is refused with 409 suppressed
  • A non-E.164 version of a suppressed number is normalized by your CRM, never dialled
  • A spoken opt-out mid-call ends the call, cancels retries, and adds the number to the suppression list (suppression_added: true)
  • A keypress opt-out works, if you offer one
  • The disclosure plays on every answered call, and disclosure_delivered is true
  • Attempt caps block a third call to the same number in one day
  • AMD leaves the voicemail on a machine and does not misread a live person
  • Retries follow the policy, and on_exhausted reaches your CRM
  • Cancelling queued retries stops scheduled attempts
  • Your CRM backs off correctly on 429 agent_at_capacity
  • The result webhook updates the right CRM record
  • The compliance export lists every attempt, including unanswered ones

Known limitations