Skip to content

Outbound calls and compliance

Queue AI calls through the API. Every call is checked against consent, Do Not Call lists, calling hours and daily limits before it can ring.

POST /outbound-calls asks the AI receptionist to call someone, and POST /leads with a callback asks it to call a new lead back straight away (speed-to-lead). Calls from the API go through exactly the same checks as calls started in the portal, and the API cannot switch any of them off. A call is either refused (it will never be placed), delayed (accepted, it rings later) or allowed (it rings now).

These rules are how Vocenya applies the TCPA and state calling rules to AI voice calls. They are not legal advice: you remain responsible for having consent for the calls you ask for.

Before you start

The account needs, all set in the portal:

  • Outbound AI calling switched on, and the outbound calling terms accepted.
  • An active subscription and an AI receptionist to make the call.
  • For a lead callback: an active Pro plan too. Callbacks are not available in HIPAA mode.

The API key needs the outbound:write scope. To try the rules without ringing anyone, use a test key: test calls are checked the same way and then simulated. See Test mode.

Website lead form

For leads from the business's own website you do not need the API: the portal's Outbound calls page has a ready-made lead form under Add the lead form to your website, once speed-to-lead is on. Each lead it takes records the visitor's consent with the business's consent wording and queues the callback.

  • Embed (recommended). One line where the form should appear. It loads the hosted form in an iframe that sizes itself, shows the business's consent text, and is protected by Cloudflare Turnstile without adding the website's domain anywhere:

    <script src="https://vocenya.com/f/embed.js" data-form="YOUR_FORM_KEY" async></script>
    

    Copy it from the portal, which fills in the form key. Where a site builder blocks scripts, use the iframe code shown next to it. The same form has a direct link and a QR code to share on a Google Business Profile, social media or flyers, and an optional thank-you page on the website to send visitors to after they submit.

  • HTML form (advanced). A plain form to style like the website, posting to the business's intake URL. It is protected by a hidden spam trap and rate limits, plus Cloudflare Turnstile when the business adds its own Turnstile keys in the portal (the snippet then includes the site key, and every lead is checked with the business's secret).

  • API. From a server or CRM, create a lead with a callback, as below.

An AI call needs consent to AI calls on record for that number:

  • purpose: "marketing" (the default) needs marketing consent to AI calls.
  • purpose: "informational" is for reminders and follow-ups the person asked for. Any active AI-call consent covers it.
  • HIPAA-mode accounts may only make informational calls.

A lead callback records the consent as it queues the call: send consent_text, the exact wording the person agreed to, plus source_url, ip_address and user_agent from the moment they agreed when you have them.

Shell
curl -X POST https://vocenya.com/api/public/v1/leads \
  -H "Authorization: Bearer $VOCENYA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Maria Rivera",
  "phone_number": "(512) 555-0123",
  "reason": "Wants a quote for a water heater replacement",
  "callback": {
    "consent_text": "I agree to receive an automated AI phone call from Rivera Plumbing about my request.",
    "source_url": "https://www.example.com/contact"
  }
}'

Do Not Call

Numbers on your own Do Not Call list or on GH's list are never called. Manage yours with the Do Not Call endpoints. When a person asks not to be called, add them with opted_out: true: it becomes a permanent opt-out, their AI-call consent is revoked, and the entry cannot be removed (opt_out_permanent).

Calling hours and limits

  • Calls ring only between 8am to 8pm in the time zone of the number being called. That is stricter than the federal 8am to 9pm, because several states end at 8pm.
  • A number is called at most 3 times in 24 hours.
  • A number that is already on a call for your account is never rung twice at once.

None of these refuse the call: it is accepted and rings as soon as it is allowed.

The decision

POST /outbound-calls answers 202 Accepted with the queued call in data and a decision:

JSON
{
  "data": { "id": 88, "source": "api", "purpose": "marketing", "status": "queued", "phone_number": "+15125550123" },
  "decision": {
    "allowed": false,
    "reason": "outside_hours",
    "message": "It is outside calling hours (8am to 8pm) where that number is.",
    "retry_at": "2026-09-29T08:00:00-05:00"
  }
}

decision.allowed is true when the call can ring now. Otherwise decision.retry_at says when it will:

decision.reason Meaning
outside_hours It is outside calling hours (8am to 8pm) where that number is.
daily_limit That number has already been called three times in the last 24 hours.
call_in_progress That number is already on a call for this client.

Asking again for a number that already has a call from the API waiting returns that same call, so retries never stack up calls.

Refusals

A call that can never be placed is refused with 422, a code and, for calling rules, the decision:

code Meaning
invalid_number That is not a valid US phone number.
do_not_call That number is on a Do Not Call list.
no_consent There is no consent on record for AI calls to that number.
service_inactive The subscription is not active.
terms_not_accepted The outbound calling terms have not been accepted.
hipaa_marketing HIPAA accounts can only make appointment reminder calls.
trial_minutes_exhausted The AI minutes included in the free trial are used up. Start the plan to make more AI calls.
outbound_disabled Outbound AI calling is not switched on for this account.
no_receptionist This account has no AI receptionist to make the call.

Never try to work around a refusal, for example by changing the purpose without the matching consent.

Voicemail

Every AI call runs the carrier's answering machine detection. A call that voicemail answers ends with status voicemail and answered_by: "machine"; a call a person answered has answered_by: "human" (unknown when detection could not tell, null when there was no result). What happens next is the account's voicemail setting, chosen on the Outbound calls page of the portal:

  • Leave a short message (default): once the greeting ends, the virtual assistant says who called, why in one neutral sentence (never an appointment's details), and the number to call back. voicemail_left_at is set and the message is the last turn of the transcript.
  • Hang up and try again later: a new call is scheduled about 90 minutes later with blocked_reason: "voicemail_retry", within calling hours and the daily limit. The first call still ends as voicemail.
  • Hang up: nothing is left.

Following up

  • GET /outbound-calls/{outboundCall} shows a call's status, answered_by, and blocked_reason when it was blocked at dial time (the rules are checked again just before dialing).
  • Subscribe to outbound_call.completed to hear when calls end.