{"id":88343,"plugin_id":"plugin_asdk_app_6ae23b8ac7948191a7c2375c5a8d708f","kind":"skill","collection_source":"plugin_package","comparison_source":null,"observed_at":"2026-11-10T00:10:00.225Z","digest":"3c8b1a69816e1c0b82423f72a893b95de4e69dfa1d1534c4e418e122a73faf0b","against":null,"payload":{"description":"Handle Phonic conversation webhooks, extractions, and evaluations. Use for post-call processing, analysis results, and webhook receivers.","included_files":[],"name":"phonic-post-call","skill_md_contents":"---\nname: phonic-post-call\ndescription: Handle Phonic conversation webhooks, extractions, and evaluations. Use for post-call processing, analysis results, and webhook receivers.\nlicense: MIT\n---\n\n# Process Phonic conversation results\n\nSDKs: `npm install phonic` / `pip install phonic`. Entry points: `new PhonicClient({ apiKey })` (Node), `Phonic(api_key=...)` / `AsyncPhonic(...)` (Python). REST base: `https://api.phonic.ai/v1` with `Authorization: Bearer $PHONIC_API_KEY`. Always use the `.ai` domain for API and docs URLs — `phonic.co` addresses still resolve for backward compatibility, but all new code should use `phonic.ai`.\n\nFetch live docs rather than from memory: use the index at [llms.txt](https://docs.phonic.ai/llms.txt). For the REST API, see [openapi.json](https://docs.phonic.ai/openapi.json). For the WebSocket protocol, see [asyncapi.json](https://docs.phonic.ai/asyncapi.json). If an endpoint does not appear in these docs, it doesn't exist, do not invent one.\n\n## Webhooks and post-call steps\n\nWebhooks can indicate conversation progress: `conversation.ended`, `conversation.analysis`, `conversation.transferred`. A typical post-call pipeline looks like:\n\n1. **`conversation.ended`** fires when the call ends — log the outcome and kick off your downstream steps from here.\n2. **`conversation.analysis`** follows with performance metrics: its `conversation` payload carries `latencies_ms` and `interruptions_count` (also available via `GET /v1/conversations/{id}/analysis`). It does not contain extraction results.\n3. **Extractions** turn the transcript into typed fields you define. Create an extraction schema, then run it per conversation with `POST /v1/conversations/{id}/extractions` and read results with the matching GET — typically from your `conversation.ended` handler. Extractions read the transcript, so they fail if transcripts are deleted; run them promptly if you have a retention policy.\n4. **Eval prompts** grade calls against plain-language criteria. Create them at the project level (`name` + a criterion like \"the assistant made the required disclosure\"), evaluate a conversation via the conversation-evals endpoint, and read results per conversation or listed across the project — useful for compliance checks and QA queues.\n\n## Webhook receivers\n\n- **Webhook receivers** — Phonic delivers webhooks via svix, which retries, so the same event can arrive more than once (and concurrently). Build for that:\n  1. Verify the svix signature before touching the body.\n  2. Durably enqueue the event before returning 2xx; process slow work with a retryable worker.\n  3. Store each event id durably (DB unique constraint, not process memory) and skip events you've already processed.\n  4. For external side effects, use a stable idempotency key supported by the destination and persist the result. A crash after a side effect but before marking it complete can otherwise duplicate it on retry. A local started/done marker alone does not guarantee exactly-once execution; reconcile ambiguous outcomes before retrying non-idempotent operations.\n"},"changes":[],"summary":"First saved snapshot. No earlier version is available for comparison.","summary_kind":"deterministic","summary_metadata":{}}