For developersREST + webhooks

One request.
One call.

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.

WEBHOOKS
Signed, for every event: call ended, booked, texted.
TEST MODE
Build against test keys. Nothing dials, nothing is charged.
CONSENT
Required. Missing or invalid consent returns a clear 400.
POST /v1/orderstest mode
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
}
The essentials

Four things to know before you build.

1

One endpoint

POST /v1/orders starts the call and the follow-up plan for one lead. Authenticate with a Bearer key.

400

Consent first

Every order needs a consent object. Without it the request is refused before anything else happens.

t,v1

Signed webhooks

Results arrive with an X-Avoonta-Signature header you can check with a few lines of code.

$0

Test mode

Test keys run the whole flow and send webhooks, but nothing dials and nothing is charged.

Consent is required

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.

400 Bad Request
{
  "success": false,
  "error": "consent_required",
  "message": "consent.opt_in_confirmed must be true and consent.consented_at must be an ISO 8601 timestamp."
}
Signed webhooks

The result comes to you.

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.

POST your webhook_urlorder.completed
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."
  }
}
Verify the signature · Node.js
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.

Test mode

Build the whole flow. Dial nothing.

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.

  1. 01

    Get a test key

    From the developer area of your account.

  2. 02

    Send an order

    With a consent object, to /v1/orders.

  3. 03

    Receive the webhook

    Check the signature and store the result.

  4. 04

    Go live

    Swap in your live key. Same code.

No code? No problem.

Every agent has a trigger link.

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 integration

Developer

Pay as you go

$0/mo
  • Minimum first deposit$50
  • Connected minute$0.15
  • Phone number$3/month
  • Text message$0.015
  • Signed webhooksIncluded
  • Test modeIncluded
Get API keys

One request in. One call out, 18 seconds later.

Read the docs, grab a test key and send your first order.