API Reference
Webhooks

Webhooks

Aila sends signed HTTPS POST requests to your endpoint when calls finish processing, data is extracted, tasks and appointments are created, or a MISMO 3.4 file is ready.


Events

CategoryEventSent when
Callscall.completedA call finishes processing. The payload is lightweight (IDs, time, duration, contact); fetch details with the API.
Callscall.data.extractedStructured data from your Call setup is ready.
Taskstask.createdAila creates a follow-up task from a call.
Taskstask.syncedA task syncs to your CRM.
Appointmentsappointment.createdAila creates an appointment from a call.
Appointmentsappointment.syncedAn appointment syncs to your CRM calendar.
Loan filesmismo.readyA MISMO 3.4 file is generated for a call or contact.
Testingtest.pingOnly when you click Send test event.

call.completed and call.data.extracted are sent once per call.


Add an endpoint

In the app

  1. Go to Settings > Connections and open Outgoing webhooks.
  2. Click New webhook.
  3. Enter a Name and the URL. The URL must be HTTPS and publicly reachable (no localhost or private IPs).
  4. Select the events to send.
  5. Save, then copy the signing secret. It's shown only once.
  6. Click Send test event to check your endpoint.

Each endpoint's Recent deliveries shows the event, status, number of attempts, and time.

With the API

curl -X POST https://app.aila.fyi/api/v1/organizations/{organizationId}/webhooks \
  -H "Authorization: Bearer ak_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Internal CRM ingest",
    "url": "https://api.yourdomain.com/webhooks/aila",
    "eventTypes": ["call.completed", "call.data.extracted"]
  }'

The response includes the signing secret. The API also supports listing, updating, deleting, sending a test event, rotating the secret, and listing deliveries. See the OpenAPI spec (opens in a new tab).


Payload

{
  "id": "evt_...",
  "type": "call.completed",
  "createdAt": "2026-09-30T14:30:00.000Z",
  "organizationId": "org_...",
  "data": {
    "callId": "...",
    "organizationId": "org_...",
    "recordedAt": "2026-09-30T14:02:11.000Z",
    "durationSeconds": 642,
    "contactId": "...",
    "contactName": "Dana Brooks",
    "contactPhone": "+19195550123"
  }
}

Headers

HeaderValue
X-Aila-EventThe event type, for example call.completed.
X-Aila-Delivery-IdUnique per delivery. Use it to ignore duplicates.
X-Aila-Webhook-Endpoint-IdThe endpoint that received it.
X-Aila-Signaturet=<timestamp_ms>,v1=<hex HMAC>

Verify the signature

The signature is an HMAC-SHA256 of <timestamp>.<raw body> using your signing secret. Reject requests older than 5 minutes.

import crypto from 'crypto'
 
function verifyAilaWebhook(rawBody, signatureHeader, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(signatureHeader.split(',').map((kv) => kv.split('=')))
  const timestamp = Number(parts.t)
  if (!timestamp || !parts.v1) return false
  if (Math.abs(Date.now() - timestamp) / 1000 > toleranceSeconds) return false
 
  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex')
  const a = Buffer.from(expected, 'hex')
  const b = Buffer.from(parts.v1, 'hex')
  return a.length === b.length && crypto.timingSafeEqual(a, b)
}

Use the raw request body exactly as received, before parsing JSON.

To rotate the secret, click Rotate signing secret on the endpoint. The old secret stops working immediately.


Delivery and retries

  • Success: any 2xx response within 15 seconds. Redirects count as failures.
  • Retries: up to 5 attempts in total, with exponential backoff starting at 30 seconds (up to 1 hour between attempts, 7 hours overall).
  • Auto-disable: an endpoint is disabled after 20 consecutive failed deliveries. Fix the endpoint, then re-enable it in settings.