Skip to main content

通話後ウェブフック

call.completedイベントを購読 — 文字起こし、録音、結果。

4 min read

郵便コールWebhooks

Finn コール エンドのたびにサーバーを始動させます。 トランスクリプト、記録URL、構造化された結果、感情、および費用を受け取る。 単一の最も重要な webhook は、呼び出しデータを CRM、分析、または ops パイプラインに同期します.

お問い合わせ

火事時

  • イベント: call.completed
  • 対象: 通話終了の5秒以内(理由は、ピックアップ、見逃し、ボイスメール、忙しい、失敗)
  • **オーダー:**ベストフォート。 created_at+のidempotentのハンドルを使用して下さい、厳密な順序で頼りにしません.
  • 注意: 5xx/タイムアウトの10分以上5回の試み。 ダッシュボードのwebhookログに記録された最後の試み.

お問い合わせ

サブスクリプションを登録する

ダッシュボード

設定 → インテグレーション → Webhooks → 新しい webhook.

イベントリストからcall.completedを選択します。 エンドポイント URL を貼り付けます。 保存 — Finn は署名の秘密を一度示します。 今それをコピー(もう一度参照することはできません).

APIに従って

curl https://api.hirefinn.ai/v1/webhooks \
  -H "Authorization: Bearer $FINN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-app.com/finn/post-call",
    "events": ["call.completed"],
    "description": "CRM + analytics sync"
  }'

応答には、secret — 安全に保存されます.

お問い合わせ

ペイロード

{
  "id": "evt_2H4abc",
  "type": "call.completed",
  "created_at": "2026-05-22T14:32:14.892Z",
  "org_id": "org_8fac17c5",
  "data": {
    "call_id": "cal_xyz789",
    "deployment_id": "dep_abc123",
    "finn_id": "fn_def456",
    "phone_number_id": "ph_1234",

    "from": "+919876543210",
    "to": "+918765432100",
    "call_type": "outbound",
    "channel": "pstn",

    "started_at": "2026-05-22T14:30:01.245Z",
    "answered_at": "2026-05-22T14:30:04.812Z",
    "ended_at": "2026-05-22T14:32:14.123Z",
    "duration_seconds": 130,
    "ring_seconds": 4,

    "outcome": {
      "label": "qualified",
      "confidence": 0.87,
      "extracted_fields": {
        "preferred_slot": "2026-05-24T15:00:00+05:30",
        "budget": "25000",
        "is_decision_maker": true
      }
    },

    "sentiment": "positive",
    "csat_score": null,
    "call_status": "completed",
    "hangup_party": "agent",

    "recording_url": "https://recordings.hirefinn.ai/.../cal_xyz789.mp3",
    "recording_duration_seconds": 130,
    "transcript_url": "https://transcripts.hirefinn.ai/.../cal_xyz789.json",

    "credits_charged": 3,
    "currency": "INR",
    "monetary_value": 10.05,

    "audience_id": "aud_xyz789",
    "audience_row": {
      "name": "Priya M",
      "phone": "+919876543210",
      "loan_amount": "500000"
    },

    "metadata": {
      "campaign_tag": "may-cohort-3"
    }
  }
}

フィールド参照

| フィールド | タイプ | ノート | お問い合わせ | call_id | 文字列 | グローバルに一意 ご愛用品としてお使い下さい。 | | deployment_id | 文字列 | ソースキャンペーン ワンオフテストコールのNull
| from / to | E.164 | 事前翻訳 WhatsAppコールは wa_id をここで使用しています。 | | channel | enum | pstn``pstn |whatsapp |sip | | started_at | ISO-8601 | Finnがダイヤルを開始/電話を受信したとき | | answered_at | ISO-8601 / NULL | コールがピックアップされていない場合はNull | | duration_seconds | int | 請求可能な期間、answered_atからended_at | | outcome.label | 文字列 | プロンプトからカスタム結果の分類 | | outcome.confidence | フロート 0–1 | ラベルのモデル自信 | | outcome.extracted_fields | オブジェクト | パーコール構造データ(プロンプト設計によるフリーフォーム) | | sentiment | enum | positive``positive |neutral |negative | | call_status | enum | completed``completed |no_answer |busy |failed |voicemail | | hangup_party | enum | caller``caller |agent |system | | credits_charged | フロート | ウォレットのデビット | | audience_row | オブジェクト | 全CSV行ダイヤル(下り線) インバウンド向けNull

お問い合わせ

署名検証

FinnはHMAC-SHA256とすべてのwebhookに署名します。 ペイロードを信頼する前に確認します.

ヘッダー: X-Finn-Signature: t=1716391823,v1=abc123...

t=はタイムスタンプです。 v1=HMAC-SHA256(secret, t + "." + raw_body)です.

ノード

import crypto from "crypto";

function verifyFinnSignature(
  rawBody: string,
  header: string,
  secret: string,
  toleranceSeconds = 300,
): boolean {
  const parts = Object.fromEntries(
    header.split(",").map((p) => p.split("=") as [string, string]),
  );
  const ts = parseInt(parts.t, 10);
  const sig = parts.v1;
  if (!ts || !sig) return false;

  if (Math.abs(Date.now() / 1000 - ts) > toleranceSeconds) return false; // replay guard

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.${rawBody}`)
    .digest("hex");

  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}

フィードバック

import hmac, hashlib, time

def verify_finn_signature(raw_body: bytes, header: str, secret: str, tolerance=300) -> bool:
    parts = dict(p.split("=", 1) for p in header.split(","))
    ts = int(parts.get("t", 0))
    sig = parts.get("v1", "")
    if not ts or not sig: return False
    if abs(time.time() - ts) > tolerance: return False
    expected = hmac.new(secret.encode(), f"{ts}.".encode() + raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, sig)

常に未加工要求ボディで確認します、パースされたJSONではなく、再serializationは空白を変更し、HMACを破ります.

お問い合わせ

ペイロードの処理(ノード例)

import express from "express";

const app = express();

// raw body required for signature verification
app.post("/finn/post-call",
  express.raw({ type: "application/json" }),
  async (req, res) => {
    const sig = req.headers["x-finn-signature"] as string;
    const ok = verifyFinnSignature(req.body.toString(), sig, process.env.FINN_WEBHOOK_SECRET!);
    if (!ok) return res.status(401).send("bad signature");

    const event = JSON.parse(req.body.toString());

    // Dedupe — idempotent processing
    if (await db.eventExists(event.id)) {
      return res.status(200).send("dup");
    }
    await db.markEventSeen(event.id);

    // Route by event type
    if (event.type === "call.completed") {
      await handleCallCompleted(event.data);
    }

    res.status(200).send("ok");
  },
);

async function handleCallCompleted(call: any) {
  // 1. Update CRM record
  await crm.updateLead(call.audience_row?.phone, {
    last_call_outcome: call.outcome.label,
    last_call_sentiment: call.sentiment,
    last_call_recording: call.recording_url,
  });

  // 2. If qualified, fire a Slack alert
  if (call.outcome.label === "qualified") {
    await slack.notify("#sales-hot-leads", `Hot lead: ${call.audience_row.name}`);
  }

  // 3. Push to data warehouse
  await warehouse.insert("finn_calls", call);
}

お問い合わせ

信頼性+潜在能力

  • ** event.id** — Finnは、エンドポイントがタイムアウトしたときに既に配信されたイベントを再試行することができます
  • 5秒以内に2xxを返して下さい それ以外の場合は故障と再試行として扱います
  • ヘビーワーク非同期を行う - すぐにペイロードをキュー
  • ダッシュボードから再生 — 失敗した配送は、設定 → 統合 → Webhooks → ログ 「再生」ボタンで表示されます

お問い合わせ

普通のゴッチャ

| 症状 | 修正 | お問い合わせ | 署名は常に失敗します | 確認する前に JSON を解析しています。 生体を最初に確認 | | 重複する CRM行 | event.idで拒否しない。 ユニークなコンストラントやセットを追加。 | | レイトイベント | 終了点は 5 点 処理をキューに入れる | | ミスaudience_row | コールはインバウンド(聴衆なし) call_typeを最初に確認して下さい。 | | 録画URL 403 | 録画URLは30日後にデフォルトで有効期限が切れます。 長期のアーカイブのためのあなた自身の貯蔵へのミラー。 |

お問い合わせ

関連イベント

ポストコールのwebhookはいくつかあります。 フルカタログを見る:

| イベント | イベント | お問い合わせ | call.started | キャリアピックアップ | | call.completed | このページ | | call.transferred | 人への暖かい転送 | | deployment.completed | キャンペーン実施者 | | wallet.low_balance | 構成しきい値の下 |

お問い合わせ

関連記事

Was this page helpful?

Still stuck or have feedback?

Email [email protected] or use the chat bubble in the bottom-right corner — it's a Finn that knows the Academy cold.