---
name: bijection-convex-vapi
description: "Evaluate and integrate the Convex Vapi component with Bijection."
---

# Convex Vapi

Place outbound Vapi voice AI calls from Convex actions, and watch status, transcript, summary, and cost update reactively.

This is an upstream package. It has not been adapted or qualified for Bijection.

- Package: convex-vapi
- Source: https://github.com/sholajegede/convex-vapi
- npm: https://www.npmjs.com/package/convex-vapi
- Directory: https://bijection.com/components/convex-vapi

Read the upstream README for setup, license, and compatibility before using it.

## Integration workflow

1. Read the source README and package manifest at the recorded revision.
2. Confirm the required SDK, dependency availability, and runtime compatibility.
3. Follow the component's documented setup and configuration. Never invent an npm install command from a catalog package name.
4. Keep credentials in the project's existing secret store.
5. Follow the project's execution rules for verification and report what was actually checked.

## Original upstream skill

The following guidance describes convex-vapi. Its installation commands and APIs refer to the upstream package. Evaluate compatibility with the Bijection source separately.


> Agents: read this skill fully before writing code that uses Convex Vapi. Follow the installation and configuration steps exactly.

# Convex Vapi

## Instructions

convex-vapi syncs Vapi voice AI call state into your Convex database via server-URL webhooks, enabling reactive queries on call status, transcript, summary, and cost without polling. It also exposes a `createCall` action for placing outbound calls directly from Convex, recording the call immediately before the first webhook arrives. Webhook payloads are verified with constant-time secret comparison and deduplicated via SHA-256 body hashing, with non-destructive merges ensuring richer data from earlier events is never overwritten by sparser later ones.

### Installation

```bash
npm install convex-vapi
```

Current npm version: `convex-vapi@0.0.5`

## Use cases

- Building a voice AI call dashboard that needs live status updates (queued, ringing, in-progress, ended) without polling Vapi's REST API
- Triggering outbound phone calls from a Convex action and immediately showing call state in a React UI via `useQuery` before any webhook has fired
- Auditing or replaying webhook deliveries by querying the raw `webhookEvents` table for every payload received per call
- Recovering from missed webhook deliveries by calling `refreshCall` to pull the latest transcript, summary, and recording directly from the Vapi API on demand
- Aggregating call metrics across an entire deployment using `getStats` to count live, ended, and total calls without joining across your own app tables

## How it works

The component is registered in `convex/convex.config.ts` using `app.use(convexVapi)`, which provisions isolated `calls` and `webhookEvents` tables inside the component's own schema namespace, separate from your app's schema. A `Vapi` client instance is initialized with your Vapi API key and webhook secret, then used to mount `vapi.webhookHandler` as an HTTP route in `convex/http.ts`. This handler receives `status-update` and `end-of-call-report` events from Vapi, verifies the `X-Vapi-Secret` header, deduplicates by SHA-256 hash of the raw body, and patches the corresponding row in the `calls` table using a merge strategy that never overwrites existing non-null fields.

Placing a call uses `vapi.createCall(ctx, { assistantId, phoneNumberId, customerNumber })` from a Convex action, which calls the Vapi REST API and writes the initial call record before any webhook arrives, returning `{ callId, status }` immediately. Queries like `getCall`, `listCallsByAssistant`, and `listRecentCalls` can be wrapped in your own Convex query functions and consumed from React via `useQuery`, which re-renders reactively as each webhook patches the underlying row. The `refreshCall` action provides a manual fallback to re-fetch a call directly from Vapi's API, useful when webhook delivery is delayed or missed.

## When NOT to use

- When a simpler built-in solution exists for your specific use case
- If you are not using Convex as your backend
- When the functionality provided by Convex Vapi is not needed

## Resources

- [npm package](https://www.npmjs.com/package/convex-vapi)
- [GitHub repository](https://github.com/sholajegede/convex-vapi)
- [Live demo](https://convex-vapi.vercel.app)
- [Convex Components Directory](https://www.convex.dev/components/convex-vapi)
- [Convex documentation](https://docs.convex.dev)