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.
Consent
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
informationalcalls.
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.
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:
{
"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_atis 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 asvoicemail. - Hang up: nothing is left.
Following up
GET /outbound-calls/{outboundCall}shows a call's status,answered_by, andblocked_reasonwhen it was blocked at dial time (the rules are checked again just before dialing).- Subscribe to
outbound_call.completedto hear when calls end.