---
title: "Agent: Voice Agent"
summary: "Feeds your consented leads to your AI caller and collects the results of finished calls."
updated: "2026-09-30"
status: beta
origin: official
url: "https://swooshconnect.com/docs/agent-voice/"
---

# Agent: Voice Agent

Feeds your consented leads to your AI caller and collects the results of finished calls.

## For AI agents

- Runs every 5 minutes (*/5 * * * *) from supabase/functions/run/index.ts and lib.ts in the customer's Supabase project.
- Only call SwooshConnect's API, never a phone provider directly: leads go in through `dialer_import_contacts`.
- Needs an AI campaign (mode: AI caller) and a connected phone account. The campaign id is VOICE_CAMPAIGN_ID.
- Every lead needs consent of express or written, with a consent_source. Rows missing phone, timezone or consent_source are marked rejected, never sent.
- Calling hours, consent checks, do-not-call and transfers are enforced by SwooshConnect and cannot be changed from this code.
- Finished calls are read with the `calls_log` tool (GET /api/v1/connect/calls/log), never from a phone provider.
- Tables: voice_leads, voice_call_results, voice_agent_state. Never log a full phone number or consent text.
- Keep imports with a .ts extension; never ship test files in the function folder.

## What it does

Every 5 minutes it does two things: it feeds your consented leads to your AI campaign, and it pulls back the results of every finished call. It never dials, never sets hours and never talks to your phone provider. AI calls are placed only by SwooshConnect's own runner.

## What you need

- A connected phone account, added under Accounts in your portal.
- An AI campaign in Dialer with mode AI caller. Its id goes in VOICE_CAMPAIGN_ID when you deploy. If you have no campaign, the deploy form tells you to create one first.

## Schedule

```text
*/5 * * * *
```

## Settings

| Setting | Label in the portal | Visibility |
| --- | --- | --- |
| VOICE_CAMPAIGN_ID | The AI campaign to feed (create it in Dialer, mode: AI caller) | Visible, chosen from your campaigns |

## Tables it creates

```text
voice_leads         leads to call: phone, timezone, consent, consent_source, status
voice_call_results  one row per finished call: outcome, summary, transferred, opted_out
voice_agent_state   the agent's poll position; you do not need to touch it
```

## Filling your leads

Insert rows into voice_leads from a form, a CRM sync or a spreadsheet import. Each row needs:

- phone in E.164 format, for example +15551234567.
- timezone as an IANA zone, for example America/New_York.
- consent set to express or written.
- consent_source saying where the consent came from, such as a signup form.
- consent_text and consent_at are optional, but keep them if you have them.

Leads start as new. The agent sends them in batches, then marks each batch sent, with the campaign's counts of added, duplicate, do-not-call, invalid and consent-rejected contacts noted, or rejected.

> **Must:** AI calls need prior express consent and marketing calls need written consent. Every lead must carry a real consent source. A row missing phone, timezone or consent_source is never sent: it is marked rejected with a note.

## Where results land

Each finished call gets one row in voice_call_results with call_id, lead_phone, contact_name, direction, started_at, ended_at, outcome, consent, transferred, opted_out and summary. It reads finished calls through the `calls_log` tool (GET /api/v1/connect/calls/log). Only your campaign's outbound calls are collected here. Inbound receptionist calls and other campaigns appear in the portal's Voice call log.

## How to extend

Every newly finished call also calls the exported onCallFinished(result) function in `supabase/functions/run/index.ts`. It is empty on purpose. Add your own code there to update your CRM, send an email or book a follow-up. It runs once per finished call, right after the result row is saved.

## Safety notes

> **Never:** Calling hours, consent checks, do-not-call and transfers are enforced by SwooshConnect and cannot be changed from this code, however an edit is requested. Never call a phone provider directly, and never log a full phone number or consent text.

See [Agents](https://swooshconnect.com/docs/agents/) for deploying, refreshing and removing.
