# Deployed AI

The agents elsewhere in these guides answer your team. These two put an agent in front of
people who have no account: a widget embedded on your site, and a voice agent with a real
phone number.

Both wrap an agent you already have, so the knowledge, tools and prompt work you did for
internal use carries straight over.

## Chat widgets

Gated on **module-chat-widget**.

```bash
curl -X POST https://api.genuineai.app/api/v1/chat-widgets \
  -H "X-Api-Key: gai_…" -H "X-Tenant-Id: <workspace-id>" \
  -H "Content-Type: application/json" \
  -d '{
    "widget_name": "Support",
    "widget_agent": "3f2a9c1e-…",
    "widget_origins": ["https://example.com"],
    "widget_welcome": "Ask us anything about ordering."
  }'
```

<Callout type="caution">
**The agent must be marked `agent_audience: "public"`.** A widget is an anonymous
surface and an internal agent is not written to be one, so this refuses rather than
exposing it. Making an agent public also requires the widget entitlement. The two
checks are deliberately joined.
</Callout>

`widget_origins` is the allow-list of sites permitted to embed the widget. It is what
stops someone else's page from running your agent on your credits, so keep it tight: a
wildcard here lets anyone spend your budget.

### Limits

`widget_limits` sets the guardrails on an anonymous surface:

| | |
|---|---|
| `maxMessagesPerSession` | Caps one conversation. |
| `maxSessionsPerIpPerDay` | Caps one visitor. |
| `maxInputChars` | Caps one message. |
| `sessionTtlMinutes` | How long a session stays open. |
| `dailyCreditCap` | **The one that matters.** A ceiling on what this widget can spend per day. |

Set `dailyCreditCap` before you go live. It contains a bad day to one widget rather than
to your whole [credit balance](/usage-and-credits), because the public rate limits protect
the platform rather than your budget.

### Tools are off by default

```json
{ "widget_config": { "enableTools": true } }
```

Without this setting, the widget runs the agent **with no tools and no connections**, even
if the agent carries them. The default is deliberate: an anonymous visitor should not be
able to reach your [connected systems](/external-data) by asking. Turn it on only when you
have decided the public may reach whatever those tools touch.

### Conversations and leads

| | |
|---|---|
| `GET /chat-widgets/{id}/sessions` | Every conversation. `leads_only=true` narrows to those that captured contact details. |
| `GET /widget-sessions/{id}` | One lead with the conversation it came from. |
| `GET /chat-widgets/{id}/analytics` | Conversation and lead counts over the last `days` (30 by default). |

The lead endpoint returns the contact *and* the transcript together, which is what a CRM
handoff usually needs: not only who made contact, but what was said. Poll `sessions` with
`leads_only=true` and a `wses_created` range for a lead feed without a webhook.

## Voice agents

Gated on **module-voice-agent**. An agent, on a phone number, taking real calls.

```bash
curl -X POST https://api.genuineai.app/api/v1/voice-agents \
  -H "X-Api-Key: gai_…" -H "X-Tenant-Id: <workspace-id>" \
  -H "Content-Type: application/json" \
  -d '{"vag_name": "Front desk", "vag_agent": "3f2a9c1e-…"}'
```

That creates the agent and its configuration. **It has no phone number until you request
one**, which is a separate call because it is a separate commitment:

```bash
curl -X POST https://api.genuineai.app/api/v1/voice-agents/<id>/phone-number \
  -H "X-Api-Key: gai_…" -H "X-Tenant-Id: <workspace-id>" \
  -H "Content-Type: application/json" \
  -d '{"country": "US", "areaCode": "305"}'
```

<Callout type="danger">
**This rents a number and starts a recurring third-party charge.** `country` is `US`,
`CA`, `GB` or `AU`; `areaCode` applies where the country supports one.

An agent holds one number at a time, and requesting another while it has one returns 400.
Releasing with `DELETE /voice-agents/{id}/phone-number` returns the number to the provider
and stops the charge, but **you cannot get the same number back**. Update anything
advertising it before you release.
</Callout>

`vag_limits` bounds call volume and spend the same way `widget_limits` does, and
`vag_config.enableTools` gates tools on exactly the same terms as the widget: off unless
you turn it on.

### Calls

| | |
|---|---|
| `GET /voice-agents/{id}/calls` | The call log, filterable by `vcall_status` and `vcall_created`. |
| `GET /voice-agents/{id}/calls/{callId}` | One call in full. |
| `GET /voice-agents/{id}/calls/{callId}/recording` | The audio. |
| `GET /voice-agents/{id}/analytics` | Call count, total duration and credits consumed over the last `days`. |

The recording endpoint **streams audio rather than returning a provider URL**. The
provider's own links are raw bucket endpoints or expiring presigned URLs and are not
reliably playable in a browser, so this endpoint resolves a working source per request.
Expect audio rather than JSON, and do not cache the response as if it were a link.

Voice analytics report credits alongside duration, and both are worth watching: minutes
are what the telephony provider bills, credits are what the model costs, and the two do
not move together.

## Choosing between the two

| | |
|---|---|
| Widget | Visitors already on your site. Cheap to run, easy to cap, leads land as structured records. |
| Voice | People who would rather call. Carries a per-number cost whether or not anyone rings it. |

Both are deployments of an agent rather than separate products, so improving the agent
improves both. Point each at an agent whose [knowledge](/knowledge-bases) you would be
comfortable seeing quoted back to you by a stranger.

## Next steps

- [Agents and conversations](/agents-and-conversations) covers the agent underneath both.
- [Usage and credits](/usage-and-credits) is how you watch what public surfaces spend.
- [External data](/external-data) describes what `enableTools` exposes.
