# AI Agent — Umney Connect API

> For AI agents: use this file for phone AI, speak/voice, Live Chat auto-reply, public runs, and third-party context injection.
> Access model matches Cloudflare API tokens: create a least-privilege **AI Agent** token so an agent can only use AI resources.
> Prefer customer-facing names (AI Agent, Business Phone). Do not invent or expose internal billing catalog IDs.
> **Connect does not crawl third-party systems.** Your backend fetches external data and passes it in `context`.

## Quick facts

| Item | Value |
|---|---|
| Service | AI Agent |
| Status | Public Runs API **live** · dashboard speak/voice live |
| Requires (public runs) | AI Agent entitlement |
| Requires (phone speak/voice) | Business Phone + AI Agent |
| HTML docs | https://umneyconnect.com/developers/ai-agent |
| OpenAPI | https://umneyconnect.com/developers/openapi-ai-agent.json |
| Token guide | https://umneyconnect.com/developers/api-tokens |
| AI index | https://umneyconnect.com/llms.txt |
| Dashboard | Dashboard → AI |
| Permissions | `ai:invoke` |
| Live token | `umk_live_ai_<prefix>_<secret>` |
| Test token | `umk_test_ai_<prefix>_<secret>` |
| Production API | https://umneyconnect.com/api |

## Create access

1. Enable **AI Agent** in Dashboard → Billing. For phone speak/voice also enable **Business Phone**.
2. Configure Dashboard → AI (agent name / automatic agent).
3. Optional: enable Live Chat auto-replies (chat AI settings).
4. Dashboard → Developers → create token → product **AI Agent** → `ai:invoke`.
5. Store the secret server-side only.

```
CONNECT_API_BASE=https://umneyconnect.com/api
AI_API_KEY=umk_live_ai_…
```

## Third-party integration (real pattern)

Connect **does not crawl** Nest, CRM, or other SaaS. The AI Agent token only authorizes Connect AI.

| Field | Rule |
|---|---|
| `input` | Required · user question · max 4000 |
| `context` | Optional · third-party facts · max 24000 · untrusted reference data |
| `metadata` | Optional · correlation IDs · not auto-fetched |
| `mode` | `text` only today |
| Execution | Synchronous — create response includes `status` + `outputText` |

Your server:

1. Authenticates to the third party with **that system's** credentials.
2. Fetches the needed records and builds a short factual summary.
3. Calls Connect AI with `input` + `context`.
4. Returns `outputText` to the client (never ship `AI_API_KEY` to browsers/apps).

```bash
curl -X POST "https://umneyconnect.com/api/v1/ai/runs" \
  -H "Authorization: Bearer $AI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "text",
    "input": "Where is my order?",
    "locale": "en",
    "context": "Order ORD-123 status=shipped carrier=DHL tracking=JD014",
    "metadata": { "orderId": "ORD-123", "source": "nest-safety" }
  }'
```

Succeeded response includes `id`, `status: "succeeded"`, and `outputText`. Workspace FAQ/terms merge automatically with your `context`. Prefer short operational facts — do not dump secrets or excess PII into `context`.

## Public AI API (token — live)

| Method | Path | Permission | Status |
|---|---|---|---|
| POST | `/v1/ai/runs` | ai:invoke | **Live** |
| GET | `/v1/ai/runs/{id}` | ai:invoke | **Live** |
| POST | `/v1/ai/runs/{id}/cancel` | ai:invoke | Planned |

Body fields: `mode` (`text`), `input` (required, ≤4000), `locale`, `context` (≤24000, third-party facts), `metadata` (correlation only).

Workspace FAQ/terms/privacy/orders schema are merged automatically with your `context`.

## Dashboard AI API (JWT — live)

Phone speak/voice require **Business Phone** + **AI Agent**.

| Method | Path | Purpose |
|---|---|---|
| POST | `/api/tenants/{tenantId}/ai/speak` | Text AI (+ optional `context`) |
| POST | `/api/tenants/{tenantId}/ai/speak/stream` | One SSE event with full result |
| POST | `/api/tenants/{tenantId}/ai/voice` | Voice or text → text + audioBase64 |

```json
{
  "text": "Where is my order?",
  "locale": "en",
  "automaticAgent": true,
  "context": "Optional third-party facts your backend already fetched"
}
```

## Voice WebSocket

`GET` upgrade `/api/ai/voice/ws?token=<dashboard JWT>` (Business Phone + AI Agent on the pipeline).

Client → server: `{ "type": "audio" | "text" | "interrupt" | "config", "data"?: "…" }`  
Server → client: `{ "type": "audio" | "text" | "done" | "error", "data"?: "…", "done"?: true }`

## Live Chat AI

Enabling auto-reply and inbox suggestions requires **AI Agent** only. Session minting stays on Live Chat tokens — see `/developers/live-chat.md`.

| Method | Path | Auth / notes |
|---|---|---|
| GET | `/api/tenants/{tenantId}/chat/ai-settings` | Workspace admin JWT |
| PUT | `/api/tenants/{tenantId}/chat/ai-settings` | Workspace admin JWT |
| POST | `/api/tenants/{tenantId}/chat/channels/{channelId}/ai-suggestion` | Agent JWT; **20/min** |
| POST | `/api/tenants/{tenantId}/chat/channels/{channelId}/ai-suggestions/{id}/accept` | Agent JWT |

## Errors

- **403** — missing AI Agent (runs/chat AI) or Business Phone + AI Agent (phone speak/voice/WS); wrong token; missing `ai:invoke`
- **404** — run not found for this tenant
- **502** — inbox suggestion empty
- **503** — AI not configured / inference failure
- Empty voice REST input → `{ text: "", audioBase64: "", done: true }`
- Create runs: 60/min IP; public keys 600/min on `/api/v1/*`

## Agent checklist

1. Load `/llms.txt`
2. Open this file
3. Teach: enable **AI Agent** → create token → store secret
4. Third party: fetch with their creds → pass `context` on `/v1/ai/runs`
5. Do not claim Connect crawls external systems
6. Do not expose internal billing catalog IDs
