Zum Hauptinhalt springen

Documentation Index

Fetch the complete documentation index at: https://docs.talkturo.ai/llms.txt

Use this file to discover all available pages before exploring further.

Webhooks liefern Ereignisse in Echtzeit an Ihren Server — ohne API-Polling. Talkturo unterscheidet Anrufstatus-Ereignisse aus der Telefonie und Abrechnungsereignisse vom Abo-Anbieter. Ziel-URLs tragen Sie im Dashboard ein; bei einem Ereignis sendet Talkturo eine signierte POST-Anfrage an diese URL.

Configure webhook URLs

1

Open Integrations settings

In the Talkturo dashboard, navigate to SettingsIntegrations.
2

Enter your endpoint URL

In the Webhooks section, enter the publicly reachable HTTPS URL of your server for each webhook type. The URL must return a 200 status code within 5 seconds or Talkturo will treat the delivery as failed.
3

Save and test

Click Save. Use the Send test event button to verify your endpoint receives and processes the payload correctly.
Your webhook endpoint must be reachable over the public internet. Localhost URLs will not receive events in production.

Webhook security

Talkturo includes a cryptographic signature in the Telnyx-Signature-Ed25519 header (for call webhooks) and a X-Signature header (for billing webhooks). Verify this signature before processing the payload to confirm the request originated from Talkturo and was not tampered with. The signature is a base64-encoded HMAC or Ed25519 signature computed over the raw request body. Compare it against a signature you compute using your webhook secret, available in the dashboard under SettingsIntegrationsWebhook Secrets.
Always verify signatures in production. Skipping signature verification exposes your endpoint to spoofed events.

Call status webhook

POST /api/db/webhook Talkturo sends call status events to this endpoint as calls progress through their lifecycle. Configure the URL your server exposes for this path in the dashboard.

Event types

EventDescription
call.initiatedAn outbound call was placed or an inbound call arrived
call.answeredThe callee picked up
call.completedThe call ended normally
call.hangupOne party disconnected the call
call.machine_detection.endedAnswering machine detection completed
call.recording.savedA call recording was saved to storage

Payload structure

{
  "type": "call.completed",
  "data": {
    "call_control_id": "v2:T02llLL...",
    "call_leg_id": "0cf8a7d8-...",
    "call_session_id": "84a7e8b2-...",
    "client_state": "eyJhc3Npc3RhbnRJZCI6...",
    "connection_id": "1234567890",
    "from": "+14155550101",
    "to": "+12025551234",
    "direction": "outbound",
    "start_time": "2024-01-15T14:00:00Z",
    "end_time": "2024-01-15T14:04:32Z",
    "duration_secs": 272
  }
}
```| Feld | Geben Sie | ein Beschreibung |
|-------|------|-------------|
| „Typ“ | Zeichenfolge | Der Ereignistyp (z. B. „call.completed“) |
| `data.call_control_id` | Zeichenfolge | Telnyx-Anrufsteuerungskennung |
| `data.call_leg_id` | Zeichenfolge | Eindeutiger Bezeichner für diesen Anrufabschnitt |
| `data.call_session_id` | Zeichenfolge | Gruppiert alle Beine in derselben Sitzung |
| `data.client_state` | Zeichenfolge | Base64-codierte Metadaten, die bei der Initiierung des Anrufs übergeben wurden |
| `data.connection_id` | Zeichenfolge | Die vom Anruf verwendete Telnyx-Verbindung |
| `data.from` | Zeichenfolge | Anrufernummer im E.164-Format |
| `data.to` | Zeichenfolge | Angerufene Nummer im E.164-Format |
| `data.direction` | Zeichenfolge | „eingehend“ oder „ausgehend“ |
| `data.start_time` | Zeichenfolge | ISO 8601 Datum und Uhrzeit des Anrufbeginns |
| `data.end_time` | Zeichenfolge | ISO 8601 Datum und Uhrzeit des Endes des Anrufs (nur „call.completed“) |
| `data.duration_secs` | Ganzzahl | Anrufdauer in Sekunden (nur „call.completed“) |

### Beispielhandler```javascript
import { createHmac } from 'crypto';

export async function POST(request) {
  const body = await request.text();
  const signature = request.headers.get('Telnyx-Signature-Ed25519');

  // Verify the signature using your webhook secret from the dashboard
  const isValid = verifyTelnyxSignature(body, signature, process.env.WEBHOOK_SECRET);
  if (!isValid) {
    return new Response('Unauthorized', { status: 401 });
  }

  const event = JSON.parse(body);

  switch (event.type) {
    case 'call.completed':
      await handleCallCompleted(event.data);
      break;
    case 'call.answered':
      await handleCallAnswered(event.data);
      break;
  }

  return new Response('OK', { status: 200 });
}

Billing webhook

POST /api/billing/webhook Talkturo sends subscription and payment events to this endpoint when your billing status changes. Talkturo supports both Stripe and LemonSqueezy as billing providers.

Event types

EventDescription
subscription.createdA new subscription was activated
subscription.updatedSubscription plan or status changed
subscription.cancelledSubscription was cancelled
subscription.expiredSubscription reached end of billing period
invoice.paidA payment was successfully collected
invoice.payment_failedA payment attempt failed

Payload structure

{
  "type": "subscription.created",
  "data": {
    "subscription_id": "sub_...",
    "customer_id": "cus_...",
    "plan_name": "Growth",
    "status": "active",
    "current_period_start": "2024-01-15T00:00:00Z",
    "current_period_end": "2024-02-15T00:00:00Z",
    "metadata": {
      "team_id": "team_01j..."
    }
  }
}
```| Feld | Geben Sie | ein Beschreibung |
|-------|------|-------------|
| „Typ“ | Zeichenfolge | Der Abrechnungsereignistyp |
| `data.subscription_id` | Zeichenfolge | Die Abonnement-ID Ihres Abrechnungsanbieters |
| `data.customer_id` | Zeichenfolge | Die Kundenkennung Ihres Abrechnungsanbieters |
| `data.plan_name` | Zeichenfolge | Der Name des Plans (z. B. „Growth“, „Enterprise“) |
| `data.status` | Zeichenfolge | Abonnementstatus („aktiv“, „abgebrochen“, „überfällig“) |
| `data.current_period_start` | Zeichenfolge | ISO 8601 Beginn des aktuellen Abrechnungszeitraums |
| `data.current_period_end` | Zeichenfolge | ISO 8601 Ende des aktuellen Abrechnungszeitraums |
| `data.metadata.team_id` | Zeichenfolge | Die diesem Abonnement zugeordnete Talkturo-Team-ID |

### Beispielhandler```javascript
export async function POST(request) {
  const body = await request.text();
  const signature = request.headers.get('X-Signature');

  // Verify the signature using your billing webhook secret
  const isValid = verifySignature(body, signature, process.env.WEBHOOK_SECRET);
  if (!isValid) {
    return new Response('Unauthorized', { status: 401 });
  }

  const event = JSON.parse(body);

  switch (event.type) {
    case 'subscription.created':
      await activateTeamFeatures(event.data.metadata.team_id, event.data.plan_name);
      break;
    case 'subscription.cancelled':
      await downgradeTeamFeatures(event.data.metadata.team_id);
      break;
  }

  return new Response('OK', { status: 200 });
}

Retry behavior

If your endpoint does not return a 2xx status code within 5 seconds, Talkturo retries the delivery with exponential backoff. To avoid processing duplicate events, make your webhook handler idempotent — check whether you have already processed a given event ID before acting on it.