Skip to main content

Webhooks

Webhooks are the recommended production completion path for Python integrations.

Create jobs with a webhook target​

receipt = conduit.reports.create(
source={"url": "https://storage.example.com/call.wav"},
output={"template": "general_report"},
target={"strategy": "dominant"},
webhook={
"url": "https://your-app.com/webhooks/conduit",
"headers": {"x-tenant-id": "tenant_123"},
},
)

print(receipt.job_id)

Verify before parsing​

Always verify the exact raw request body before calling parse_event(...).

import os

from fastapi import FastAPI, HTTPException, Request

from conduit import Conduit, WebhookVerificationError

app = FastAPI()
conduit = Conduit(api_key=os.environ["CONDUIT_API_KEY"])


@app.post("/webhooks/conduit")
async def conduit_webhook(request: Request) -> dict[str, bool]:
raw_payload = await request.body()
headers = dict(request.headers)

try:
conduit.webhooks.verify_signature(
raw_payload,
headers,
secret=os.environ["CONDUIT_WEBHOOK_SECRET"],
)
except WebhookVerificationError as error:
raise HTTPException(status_code=401, detail=error.code) from error

event = conduit.webhooks.parse_event(raw_payload)

if event.type == "report.completed":
report = conduit.reports.get(event.data["reportId"])
print(report.output.markdown)

if event.type == "matching.completed":
matching = conduit.matching.get(event.data["matchingId"])
print(matching.output.markdown)

return {"received": True}

Delivery rules​

  • Verify first, parse second.
  • Pass the raw bytes or raw text body exactly as received.
  • Header lookup is case-insensitive and reads conduit-signature.
  • Deduplicate on event.id because delivery is at least once.
  • Return a 2xx response quickly, then do heavier work asynchronously if needed.

Event types you will handle most often​

  • report.completed
  • report.failed
  • matching.completed
  • matching.failed

Local fallback when webhooks are unavailable​

report = receipt.handle.wait(timeout_ms=300_000)
print(report.id)

Use handle.wait() only when you cannot consume webhooks, such as local development or a small backoffice script.

Next steps​