Developer
Pay as you go
- Minimum first deposit$50
- Connected minute$0.15
- Phone number$3/month
- Text message$0.015
- Signed webhooksIncluded
- Test modeIncluded
Send a lead with its consent record and Avoonta handles the call, the follow-up and the booking. You get a signed webhook with the result.
curl https://api.avoonta.com/v1/orders \
-H "Authorization: Bearer $AVOONTA_TEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "agt_solar_booker",
"lead": {
"phone": "+15125550142",
"first_name": "Dana",
"custom_context": "Asked for a solar quote on Facebook."
},
"cadence": {
"max_attempts": 3,
"retry_interval_minutes": 120,
"send_sms_on_voicemail": true
},
"consent": {
"opt_in_confirmed": true,
"consented_at": "2026-10-14T10:41:02Z",
"source": "https://sunrisesolar.com/quote"
},
"webhook_url": "https://crm.example.com/hooks/avoonta",
"external_reference_id": "contact_8821"
}'
# 202 Accepted
{
"success": true,
"order_id": "ord_8kd2",
"status": "QUEUED",
"estimated_dial_seconds": 18
}
POST /v1/orders starts the call and the follow-up plan for one lead. Authenticate with a Bearer key.
Every order needs a consent object. Without it the request is refused before anything else happens.
Results arrive with an X-Avoonta-Signature header you can check with a few lines of code.
Test keys run the whole flow and send webhooks, but nothing dials and nothing is charged.
The consent object records what the lead agreed to, when and where. It is kept with the order as the record for every call and text.
opt_in_confirmed must be true.consented_at must be an ISO 8601 timestamp.source is the page or form where the lead agreed.If any of this is missing or invalid, the API answers 400 before it checks your balance, saves anything or dials.
{
"success": false,
"error": "consent_required",
"message": "consent.opt_in_confirmed must be true and consent.consented_at must be an ISO 8601 timestamp."
}
When a call ends, Avoonta posts the outcome, the answers, the booking and a recording link to your webhook_url. Failed deliveries are retried after 1 minute, 5 minutes, 30 minutes, 2 hours and 12 hours.
X-Avoonta-Signature: t=1760438691,v1=5f2b…c9e1
X-Avoonta-Event: order.completed
{
"event": "order.completed",
"order_id": "ord_8kd2",
"external_reference_id": "contact_8821",
"status": "BOOKED",
"duration_seconds": 134,
"billed_minutes": 3,
"charged_cents": 75,
"appointment": {
"booked": true,
"start_time": "2026-10-16T21:30:00Z"
},
"qualification": {
"summary": "Owns the home, about $240 a month. Booked a site survey."
}
}
import { createHmac, timingSafeEqual } from "node:crypto";
// header: "t=<unix seconds>,v1=<hex HMAC-SHA256>"
function verify(header, rawBody, secret) {
const [t, v1] = header
.split(",")
.map((part) => part.split("=")[1]);
const want = createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
const fresh = Math.abs(Date.now() / 1000 - Number(t)) < 300;
return fresh && want.length === v1.length
&& timingSafeEqual(Buffer.from(want), Buffer.from(v1));
}
Sign over the raw request body, exactly as received, before any JSON parsing.
Use your test key and every order runs end to end: validation, statuses and signed webhooks. Nothing dials, nothing texts and nothing is charged. Switch to your live key when you're ready.
From the developer area of your account.
With a consent object, to /v1/orders.
Check the signature and store the result.
Swap in your live key. Same code.
Paste it into Facebook Lead Ads, Zapier, Make, Typeform or your HighLevel workflows and each new lead gets a call, without writing a line.
See every integrationPay as you go
Read the docs, grab a test key and send your first order.