# Get Chat Files Source: https://docs.useinvent.com/api-reference/chats-files/get-chat-files https://api.useinvent.com/openapi.json get /chats/{chat_id}/files Retrieve all files shared in this chat. # Clear conversation summaries Source: https://docs.useinvent.com/api-reference/chats-memories/clear-conversation-summaries https://api.useinvent.com/openapi.json delete /chats/{chat_id}/memories Delete all conversation summaries for a chat. This does not delete messages, only the summaries. # Delete a conversation summary Source: https://docs.useinvent.com/api-reference/chats-memories/delete-a-conversation-summary https://api.useinvent.com/openapi.json delete /chats/{chat_id}/memories/{memory_id} Delete a specific conversation summary by ID. # Get conversation summaries Source: https://docs.useinvent.com/api-reference/chats-memories/get-conversation-summaries https://api.useinvent.com/openapi.json get /chats/{chat_id}/memories Retrieve all conversation summaries for a chat, created automatically every 10 messages. # Add Message Reaction Source: https://docs.useinvent.com/api-reference/chats-messages/add-message-reaction https://api.useinvent.com/openapi.json post /chats/{chat_id}/messages/{message_id}/reactions React to a specific message with an emoji. # Create Chat Message Source: https://docs.useinvent.com/api-reference/chats-messages/create-chat-message https://api.useinvent.com/openapi.json post /chats/{chat_id}/messages Create a new message for a specific chat. # Decide Action Approval Source: https://docs.useinvent.com/api-reference/chats-messages/decide-action-approval https://api.useinvent.com/openapi.json post /chats/{chat_id}/messages/{message_id}/approvals/{tool_call_id} Decide on a specific action approval for a message. # Decide Action Approvals Source: https://docs.useinvent.com/api-reference/chats-messages/decide-action-approvals https://api.useinvent.com/openapi.json post /chats/{chat_id}/messages/{message_id}/approvals Decide several pending action approvals of a message in one request. The assistant resumes only when no pending approval remains, and exactly once. # Delete Chat Message Source: https://docs.useinvent.com/api-reference/chats-messages/delete-chat-message https://api.useinvent.com/openapi.json delete /chats/{chat_id}/messages/{message_id} Delete a specific message by its ID. # Edit Chat Message Source: https://docs.useinvent.com/api-reference/chats-messages/edit-chat-message https://api.useinvent.com/openapi.json patch /chats/{chat_id}/messages/{message_id} Edit the text content of a specific message. # Get Chat Message Source: https://docs.useinvent.com/api-reference/chats-messages/get-chat-message https://api.useinvent.com/openapi.json get /chats/{chat_id}/messages/{message_id} Get a specific message by its ID. # Get Chat Messages Source: https://docs.useinvent.com/api-reference/chats-messages/get-chat-messages https://api.useinvent.com/openapi.json get /chats/{chat_id}/messages Get a list of messages for a specific chat. # Remove Message Reaction Source: https://docs.useinvent.com/api-reference/chats-messages/remove-message-reaction https://api.useinvent.com/openapi.json delete /chats/{chat_id}/messages/{message_id}/reactions Remove your emoji reaction from a specific message. # Respond to Interactive Tool Source: https://docs.useinvent.com/api-reference/chats-messages/respond-to-interactive-tool https://api.useinvent.com/openapi.json post /chats/{chat_id}/messages/{message_id}/tools/{tool_call_id}/respond Submit a user response to an interactive tool (e.g. connecting an app). # Send Chat Template Message Source: https://docs.useinvent.com/api-reference/chats-messages/send-chat-template-message https://api.useinvent.com/openapi.json post /chats/{chat_id}/messages/template Send a message through the channel's template action (e.g. a WhatsApp template). Works outside the messaging window. # Update Chat Skills Source: https://docs.useinvent.com/api-reference/chats-skills/update-chat-skills https://api.useinvent.com/openapi.json patch /chats/{chat_id}/skills Replace the set of skills enabled in an org chat. # Assign Conversation Source: https://docs.useinvent.com/api-reference/chats-state/assign-conversation https://api.useinvent.com/openapi.json patch /chats/{chat_id}/state/assign Assign or unassign a conversation to/from a team member. # Get Chat State Info Source: https://docs.useinvent.com/api-reference/chats-state/get-chat-state-info https://api.useinvent.com/openapi.json get /chats/{chat_id}/state/info Get the state info of a specific chat by its ID. # Update Chat State Source: https://docs.useinvent.com/api-reference/chats-state/update-chat-state https://api.useinvent.com/openapi.json patch /chats/{chat_id}/state Update the state of a specific chat by its ID. # Mark Chat as Unseen Source: https://docs.useinvent.com/api-reference/chats-unseen/mark-chat-as-unseen https://api.useinvent.com/openapi.json post /chats/{chat_id}/unseen Mark a specific chat as unseen by its ID. # Cancel Chat Generation Source: https://docs.useinvent.com/api-reference/chats/cancel-chat-generation https://api.useinvent.com/openapi.json post /chats/{chat_id}/cancel Cancel the generation of a chat. # Delete Chat Source: https://docs.useinvent.com/api-reference/chats/delete-chat https://api.useinvent.com/openapi.json delete /chats/{chat_id} Delete a specific chat by its ID. # Fork Chat Source: https://docs.useinvent.com/api-reference/chats/fork-chat https://api.useinvent.com/openapi.json post /chats/{chat_id}/fork Fork a personal or org chat from a given message into a new chat owned by the caller. Copies the conversation up to and including the message, along with the model, tools, features and linked files. # Get Chat Source: https://docs.useinvent.com/api-reference/chats/get-chat https://api.useinvent.com/openapi.json get /chats/{chat_id} Get a specific chat by its ID. # Mark Chat Seen Source: https://docs.useinvent.com/api-reference/chats/mark-chat-seen https://api.useinvent.com/openapi.json post /chats/{chat_id}/seen Update the member's last seen time for the chat, optionally up to one message. # Report Chat Typing Source: https://docs.useinvent.com/api-reference/chats/report-chat-typing https://api.useinvent.com/openapi.json post /chats/{chat_id}/typing Report that a user is typing in a chat. # Update Chat Source: https://docs.useinvent.com/api-reference/chats/update-chat https://api.useinvent.com/openapi.json patch /chats/{chat_id} Update a specific chat by its ID. # Get the actions for a connection Source: https://docs.useinvent.com/api-reference/connections-actions/get-the-actions-for-a-connection https://api.useinvent.com/openapi.json get /connections/actions Get the actions for a connection # API Cookbook Source: https://docs.useinvent.com/api-reference/getting-started/cookbook Common end-to-end tasks against the Invent API, with copy-pasteable curl. These recipes assume you already have a credential. If not, start with [Invent for Agents](/api-reference/getting-started/for-agents). Every call uses the base URL `https://api.useinvent.com`, the header `Authorization: Bearer YOUR_API_KEY`, and the `c` org shorthand. The [OpenAPI spec](https://api.useinvent.com/openapi.json) is the authoritative contract for every endpoint and body. Keys authenticate the `/orgs` and `/chats` routes; the [OpenAPI spec](https://api.useinvent.com/openapi.json) lists everything available. Pagination uses `page` (1-based) and `take` (max 100); counts come back in the `pagination-count`, `pagination-page`, and `pagination-take` response headers. ## Stand up an assistant `name` is required (1 to 1024 characters); `enabled` is optional. Creating an assistant is limited to 10 per hour. ```bash theme={"system"} curl -X POST "https://api.useinvent.com/orgs/c/assistants" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Customer Support Bot", "enabled": true }' ``` ```bash theme={"system"} curl -X GET "https://api.useinvent.com/orgs/c/assistants/ASSISTANT_ID" \ -H "Authorization: Bearer YOUR_API_KEY" ``` These are set through additional assistant endpoints. Check [openapi.json](https://api.useinvent.com/openapi.json) for the exact paths and bodies, or use the dashboard. ## Work with your audience ```bash List contacts (filtered, paginated) theme={"system"} curl -X GET "https://api.useinvent.com/orgs/c/contacts?page=1&take=20&status=SUBSCRIBED" \ -H "Authorization: Bearer YOUR_API_KEY" ``` `status` accepts `ALL`, `SUBSCRIBED`, `UNSUBSCRIBED`, `BLOCKED`, or `AI_REPLIES_OFF`. To create or update contacts, see the contact endpoints in [openapi.json](https://api.useinvent.com/openapi.json). ## Audit your connections ```bash theme={"system"} curl -X GET "https://api.useinvent.com/orgs/c/connections?page=1&take=50" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Connections are the integrations (WhatsApp, Slack, Stripe, and more) wired to an organization. ## Put an assistant in front of customers Assistants talk to customers through connected channels (WhatsApp, Instagram, web chat, and more) and the [web widget](/assistants/widget). Wire up a channel or embed the widget to go live. See the channel and connection endpoints in [openapi.json](https://api.useinvent.com/openapi.json). ## Errors `401` means a missing or invalid key (or an endpoint not available to keys), `400` a bad parameter, `404` not found, and `429` rate limited (limits are per endpoint and vary — creating an assistant, for example, is capped at 10 per hour). See the [API introduction](/api-reference/getting-started/introduction) for the full table. # Invent for Agents Source: https://docs.useinvent.com/api-reference/getting-started/for-agents Connect to Invent and start managing assistants in a couple of calls. This page gets an AI agent connected to Invent and productive fast. The quickest path is an API key, and the full set of capabilities is in the OpenAPI spec. ## Paste this into your agent Point your agent (Cursor, Claude Code, Codex, OpenCode, or harness of choice) at Invent. The instructions live in [llms.txt](https://www.useinvent.com/llms.txt), which it will read and follow: ```text theme={"system"} Connect my Invent account and help me manage my AI support assistants. Read https://useinvent.com/llms.txt and follow it. ``` ## Quick start Create one on the [API Keys page](https://www.useinvent.com/o/settings/api-keys): **New API Key**, name it, copy the token (shown once). Send `Authorization: Bearer YOUR_API_KEY` on every request. Base URL is `https://api.useinvent.com`. Org routes are `/orgs/{org_id}/...`; use `c` for the org your key belongs to. ```bash theme={"system"} curl "https://api.useinvent.com/orgs/c/assistants?page=1&take=10" \ -H "Authorization: Bearer YOUR_API_KEY" ``` The [OpenAPI spec](https://api.useinvent.com/openapi.json) is the source of truth for every endpoint, parameter, and response. Fetch it to work against the exact current contract. ## What you can do Once connected you can: * List, create, and inspect **assistants**, and configure their instructions, knowledge, channels, and actions * Manage **contacts** and audiences (filterable by subscription status) * Inspect **connections**, the channels and integrations on an org (WhatsApp, Slack, Stripe, and more) * Read **analytics** and org data Full set: the [API Cookbook](/api-reference/getting-started/cookbook) and the [OpenAPI spec](https://api.useinvent.com/openapi.json). To put an assistant in front of customers, connect a channel or embed the [web widget](/assistants/widget). ## Example calls ```bash Create an assistant theme={"system"} curl -X POST "https://api.useinvent.com/orgs/c/assistants" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Customer Support Bot", "enabled": true }' ``` ```bash List contacts theme={"system"} curl "https://api.useinvent.com/orgs/c/contacts?page=1&take=20&status=SUBSCRIBED" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ```bash List connections theme={"system"} curl "https://api.useinvent.com/orgs/c/connections?page=1&take=50" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Pagination uses `page` (1-based) and `take` (max 100); counts come back in the `pagination-count`, `pagination-page`, and `pagination-take` response headers (some cursor-style endpoints also return `pagination-next`). Contact `status` accepts `ALL`, `SUBSCRIBED`, `UNSUBSCRIBED`, `BLOCKED`, or `AI_REPLIES_OFF`. Creating an assistant needs a `name` (1 to 1024 characters) and is limited to 10 per hour. ## Other ways to sign in An API key is the simplest path. Two more are available: * **Computer use:** drive the web app in a browser and sign in with email code or Google, exactly like a person. Good when you control a screen. * **Fully autonomous via email:** with inbox access you can sign in end to end. Request a code, read it from the email, exchange it for a token (send the `x-session-name` header to get the token in the response body), then use that token exactly like an API key. ```bash Request a code, then exchange it theme={"system"} curl -X POST "https://api.useinvent.com/auth/code" \ -H "Content-Type: application/x-www-form-urlencoded" \ -d "email=agent@company.com" curl -X POST "https://api.useinvent.com/auth" \ -H "Content-Type: application/x-www-form-urlencoded" \ -H "x-session-name: agent" \ -d "email=agent@company.com" -d "code=123456" ``` The token comes back in `session.token`. In local dev, `POST /auth/code` returns the `login_link` directly so you can skip the inbox. ## Good to know * Keys authenticate the `/orgs` and `/chats` routes; the OpenAPI spec lists everything available. * Rate limits are per endpoint and vary (write-heavy endpoints like assistant creation are capped at 10 per hour), so reuse your token rather than re-authenticating and back off on `429`s. * Native MCP with OAuth login is on the way. For now, an API key is the way in. For base concepts (response codes, pagination), see the [API introduction](/api-reference/getting-started/introduction). # Introduction Source: https://docs.useinvent.com/api-reference/getting-started/introduction Understand general concepts, response codes, and authentication strategies. **Building with an AI agent?** Point it at these and it can integrate on its own: * **OpenAPI spec:** `https://api.useinvent.com/openapi.json` * **Interactive reference:** [api.useinvent.com/docs](https://api.useinvent.com/docs) * **Machine-readable index:** [docs.useinvent.com/llms.txt](https://docs.useinvent.com/llms.txt) and [llms-full.txt](https://docs.useinvent.com/llms-full.txt) * **Any page as Markdown:** add `.md` to its URL (for example [introduction.md](https://docs.useinvent.com/api-reference/getting-started/introduction.md)) Create a key on the [API Keys page](https://www.useinvent.com/o/settings/api-keys), authenticate with `Authorization: Bearer YOUR_API_KEY`, then hand the agent the OpenAPI spec and let it go. Or just hand your agent the prompt (Cursor, Claude Code, Codex, OpenCode, or harness of choice): ```text theme={"system"} Connect my Invent account and help me manage my AI support assistants. Read https://useinvent.com/llms.txt and follow it. ``` ## Explore the full API The complete API is described by an OpenAPI 3.1 spec. Browse it interactively or hand the raw spec to your client or agent. The full machine-readable spec (`openapi.json`). Import it into your client or pass it to an agent. Navigate and try every endpoint interactively. ### Base URL The Invent API is built on **REST** principles. We enforce **HTTPS** in every request to improve data security, integrity, and privacy. The API does not support **HTTP**. All requests contain the following base URL: ``` https://api.useinvent.com ``` ### Authentication To authenticate, you need to add an Authorization header with the contents being `Bearer YOUR_API_KEY`. ``` Authorization: Bearer YOUR_API_KEY ``` Go to the [API Keys page](https://www.useinvent.com/o/settings/api-keys) and create a new API key. ### Permissions and scope A key is not a master credential. Three boundaries decide what it can reach: | Boundary | What it allows | | :---------------- | :---------------------------------------------------------------------------------------------------------------------------- | | **Route surface** | Keys reach the org routes under `/orgs` and the chat routes under `/chats`. Any other route answers `401`. | | **Organization** | The org the key was created in, plus that org's sub-organizations when it is a parent key. Any other workspace answers `403`. | | **Permissions** | The key acts as the member who created it, so it holds exactly that member's permissions. | Permissions are named `resource:action`: a resource such as contacts, inbox, assistants or tables, at read or write level. Every endpoint requires the one it needs, and a call that lacks it answers `403` with the code `ORGS_PERMISSION_REQUIRED`, naming the missing permission. The current set lives in the role editor and the permissions matrix in your workspace; [custom roles](/workspace-management/custom-roles) explains both. To narrow what a key can do, create a custom role with only the permissions you need, assign it to a member, and create the key as that member. A key created by an admin carries admin access. ### Organization-scoped routes Resources are under `/orgs/{org_id}/...` (for example `GET /orgs/{org_id}/assistants`). * **`{org_id}` = `c`**: with **Bearer API key** auth, `c` is always the org the key was **issued for** (e.g. the parent if the key was created on the parent). Example: `GET https://api.useinvent.com/orgs/c/assistants`. * **Explicit `org_id`**: use the real organization id for any other workspace, including a **sub-organization** when the key is a **parent** key. **`c` does not** refer to a sub-org, so you must pass the sub-org’s id in the path. See [sub-organizations in API Keys](/workspace-management/api-keys#parent-organization-keys-and-sub-organizations). ### Response codes Invent uses standard HTTP codes to indicate the success or failure of your requests. In general, `2xx` HTTP codes correspond to success, `4xx` codes are for user-related failures, and `5xx` codes are for infrastructure issues. | Status | Description | | ------ | ----------------------------------------------------------------------- | | `200` | Successful request. | | `400` | Check that the parameters were correct. | | `401` | Check that the API key is correct. | | `403` | Not allowed: wrong workspace, or the key's member lacks the permission. | | `404` | The resource was not found. | | `429` | The rate limit was exceeded. | | `5xx` | Indicates an error with Invent servers. | ### Rate limits Invent enforces rate limits to ensure fair usage of the API. If you exceed a rate limit, you will receive a `429` status code. Limits are applied **per endpoint** and keyed per caller (your API key's owner, or IP address). They vary by action: write-heavy endpoints are capped much tighter than reads — for example, creating an assistant is limited to **10 per hour**. Expect `429`s on those well below any general per-minute ceiling, and back off when you receive one. A broad edge limit of roughly **500 requests per minute per IP** may also apply at the gateway. # Pagination and Filtering Source: https://docs.useinvent.com/api-reference/getting-started/pagination-and-filtering Learn how to paginate and filter responses from the Invent API. ### Pagination When endpoints return large lists of records, pagination helps manage the response. Use the `page` and `take` query parameters to control pagination: * **`page`**: Specifies the page number to retrieve. Default is `1`. * **`take`**: Specifies the number of records per page. Default and maximum are `100`. Some endpoints cap it lower. * **`next`**: A cursor token, used only by the endpoints that return one. Counts come back in response headers: `pagination-count`, `pagination-page` and `pagination-take`, plus `pagination-next` on cursor endpoints. To retrieve the first 50 assistants in an organization, use the following query parameters: ```bash theme={"system"} curl --request GET \ --url 'https://api.useinvent.com/orgs/{org_id}/assistants?page=1&take=50' ``` ### Filtering Endpoints may support filtering to refine responses. Filtering parameters vary by endpoint. For example, the `/assistants` endpoint supports the following filters: * **`search`**: Search for a specific term within the response. To search for assistants with the term "Issue" use the query parameters: ```bash theme={"system"} curl --request GET \ --url 'https://api.useinvent.com/orgs/{org_id}/assistants?search=Issue' ``` Filtering parameters vary by endpoint. Refer to the endpoint documentation for the specific parameters supported. # Webhooks Source: https://docs.useinvent.com/api-reference/getting-started/webhooks Receive real-time events from Invent on your own HTTPS endpoint. A webhook endpoint is a URL of yours that Invent calls when something in your workspace needs your systems to react. Instead of polling the API, your server is told. The catalog is deliberately narrow: **events you have to act on** — a contact who can no longer be reached, a send that did not land. Routine create/read/update traffic belongs to the API, not to a push feed. Use these to suppress a bad address in your own CRM, keep an opt-out in sync, or alert whoever owns a failed campaign. ## Two secrets, two directions Webhooks involve two different credentials. They are not interchangeable. | Credential | Direction | Used for | | :-------------------------------------- | :----------- | :--------------------------------------------------------------------- | | **API key** (`Authorization: Bearer …`) | you → Invent | Creating, listing, updating and deleting endpoints via the API | | **Signing secret** (`whsec_…`) | Invent → you | Verifying that a request hitting your endpoint really came from Invent | Each endpoint gets its own signing secret. Rotating one endpoint's secret never affects any other endpoint, and a leaked signing secret grants no access to your workspace. ## Create an endpoint Manage endpoints from [**Settings → Webhooks**](/workspace-management/webhooks), or over the API with your [API key](/workspace-management/api-keys): ```bash theme={"system"} curl -X POST "https://api.useinvent.com/orgs/c/webhooks" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Production", "url": "https://example.com/webhooks", "events": ["contact.unsubscribed", "broadcast.bounced"] }' ``` ```json Response theme={"system"} { "id": "whk_...", "name": "Production", "url": "https://example.com/webhooks", "events": ["contact.unsubscribed", "broadcast.bounced"], "enabled": true, "secret": "whsec_a1b2c3...", "created_at": "2026-07-28T10:00:00.000Z" } ``` The full `secret` is returned **only** on create and on rotate. Every later read returns it masked. Store it in your secret manager right away — if you lose it, rotate to get a new one. Endpoint URLs must be **HTTPS**, must not embed credentials (`https://user:pass@…`), and must not resolve to a private or loopback address. ## The payload Every delivery is a `POST` with a JSON body in one envelope shape: metadata plus a `type` and its `data`. ```json theme={"system"} { "id": "evt_29fj20fj2", "type": "broadcast.bounced", "org_id": "org_8sk20dk1", "created_at": "2026-07-28T10:00:00.000Z", "data": { "broadcast_id": "bc_...", "contact_id": "ctc_...", "email": "someone@example.com", "message_id": "0100018f...", "reason": "smtp; 550 5.1.1 user unknown" } } ``` `type` tells you what happened; `data` is that event's payload. Switch on `type` and you can add new subscriptions later without changing how you parse the envelope. | Field | Meaning | | :----------- | :-------------------------------------------------------------- | | `id` | Unique per event, **stable across retries** — deduplicate on it | | `type` | The event id (see the catalog below) | | `org_id` | The workspace the event belongs to | | `created_at` | When the event happened, not when it was delivered | | `data` | Event-specific payload | ## Events | Event | Fires when | Act on it by | | :--------------------- | :--------------------------------------------------------------------------------------------------- | :---------------------------------------------------------------------- | | `chat.assigned` | A conversation changes hands: the AI hands off, a member takes it, or it is unassigned | Paging the new owner, opening a ticket | | `contact.blocked` | A contact is blocked | Stopping outreach to them on your side | | `contact.unsubscribed` | A contact opts out — manually, via an unsubscribe link, or automatically after a bounce or complaint | Syncing the opt-out to your CRM. `unsubscribe_reason` carries the cause | | `broadcast.failed` | A broadcast fails | Alerting whoever owns the campaign | | `broadcast.bounced` | A broadcast email hard-bounced | Marking the address invalid | | `broadcast.complained` | A recipient marked the email as spam | Suppressing them everywhere | | `broadcast.suppressed` | A send was blocked because the address is on the suppression list | Cleaning the address out of your source list | | `ping` | Sent by the **Test** action only — never by a subscription | — | `chat.assigned` covers **real customer conversations only** — internal workspace chats and the assistant playground never produce it. The payload is the full chat object. Assignment lives under `state`: `state.assigned_user` is who it landed on (**absent** means it was unassigned), alongside `state.assigned_at`, `state.assistant`, `state.channel_type` and `state.ai_enabled`. `broadcast.bounced`, `broadcast.complained` and `broadcast.suppressed` are **per recipient**, not per broadcast — one delivery per affected address, carrying `email`, `message_id`, the provider `reason`, and `contact_id` when the address still maps to a contact. The live list is always available at `GET /orgs/c/webhooks/events`. ## Verifying a request **Always verify the signature before trusting a payload.** Anyone can POST JSON at your URL; the signature is what proves Invent sent it. Every delivery carries these headers: | Header | Value | | :-------------------- | :-------------------------------------------- | | `x-webhook-id` | The event id — same value as `id` in the body | | `x-webhook-event` | The event type | | `x-webhook-timestamp` | Unix seconds when the request was signed | | `x-webhook-attempt` | Attempt number, starting at `1` | | `x-webhook-signature` | `t=,v1=` | The signature is an **HMAC-SHA256**, keyed with your endpoint's signing secret, over the **raw request body** joined to the id and timestamp: ``` signed_content = "{x-webhook-id}.{x-webhook-timestamp}.{raw_body}" v1 = hex(hmac_sha256(signing_secret, signed_content)) ``` Two rules matter for a correct implementation: 1. Sign the **raw body bytes**, exactly as received. Parsing the JSON and re-serializing it changes the bytes and the signature will not match. 2. Compare in **constant time** (`crypto.timingSafeEqual`, `hmac.compare_digest`), and reject a timestamp older than a few minutes so a captured request cannot be replayed later. ```ts Node.js (Express) theme={"system"} import express from 'express'; import { createHmac, timingSafeEqual } from 'node:crypto'; const SECRET = process.env.INVENT_WEBHOOK_SECRET!; const TOLERANCE_S = 5 * 60; const app = express(); // raw body — do NOT use express.json() before verifying app.post( '/hooks/invent', express.raw({ type: 'application/json' }), (req, res) => { const id = req.header('x-webhook-id') ?? ''; const timestamp = req.header('x-webhook-timestamp') ?? ''; const header = req.header('x-webhook-signature') ?? ''; const signature = header .split(',') .find((part) => part.startsWith('v1=')) ?.slice(3); if (!signature) return res.sendStatus(400); if (Math.abs(Date.now() / 1000 - Number(timestamp)) > TOLERANCE_S) { return res.sendStatus(400); } const expected = createHmac('sha256', SECRET) .update(`${id}.${timestamp}.${req.body.toString('utf8')}`) .digest('hex'); const a = Buffer.from(expected); const b = Buffer.from(signature); if (a.length !== b.length || !timingSafeEqual(a, b)) { return res.sendStatus(401); } const event = JSON.parse(req.body.toString('utf8')); switch (event.type) { case 'broadcast.bounced': { // handle it break; } default: { break; } } // acknowledge immediately, process asynchronously res.sendStatus(200); }, ); ``` ```python Python (Flask) theme={"system"} import hashlib import hmac import time from flask import Flask, request SECRET = os.environ["INVENT_WEBHOOK_SECRET"] TOLERANCE_S = 5 * 60 app = Flask(__name__) @app.post("/hooks/invent") def receive(): raw = request.get_data() # raw bytes, not request.json event_id = request.headers.get("x-webhook-id", "") timestamp = request.headers.get("x-webhook-timestamp", "") header = request.headers.get("x-webhook-signature", "") signature = next( (p[3:] for p in header.split(",") if p.startswith("v1=")), None ) if not signature: return "", 400 if abs(time.time() - int(timestamp or 0)) > TOLERANCE_S: return "", 400 expected = hmac.new( SECRET.encode(), f"{event_id}.{timestamp}.".encode() + raw, hashlib.sha256, ).hexdigest() if not hmac.compare_digest(expected, signature): return "", 401 event = request.get_json() if event["type"] == "broadcast.bounced": pass # handle it return "", 200 ``` ## Responding Return any `2xx` as soon as you have durably accepted the event — do the real work afterwards, out of the request. Requests time out after **10 seconds**. Anything that is not a `2xx`, plus timeouts and connection errors, counts as a failure and is retried. ## Retries Failed deliveries are retried with a widening backoff: **5s → 5m → 30m → 2h → 5h → 10h** (7 attempts total). After the last attempt the delivery is marked `FAILED`. Delivery is **at-least-once**: the same event can arrive twice if your `2xx` was lost on the way back. Deduplicate on `id` (or the `x-webhook-id` header) and make your handler idempotent. Ordering is **not guaranteed** — a retry can land after a newer event. Order by `created_at` if sequence matters. An endpoint that fails 30 deliveries in a row is **disabled automatically**, and the reason is shown on the endpoint. Re-enabling it (PATCH `enabled: true`) clears the failure streak. Deliveries also pause while a workspace has no balance, and resume once it is topped up. ## Inspecting and replaying Every attempt is recorded for **7 days**: status, response code, response body and duration. ```bash theme={"system"} # recent deliveries for an endpoint curl "https://api.useinvent.com/orgs/c/webhooks/whk_.../deliveries" \ -H "Authorization: Bearer YOUR_API_KEY" # send a signed ping to check the endpoint is reachable curl -X POST "https://api.useinvent.com/orgs/c/webhooks/whk_.../test" \ -H "Authorization: Bearer YOUR_API_KEY" # re-send a past event (succeeded or failed) curl -X POST \ "https://api.useinvent.com/orgs/c/webhooks/whk_.../deliveries/whd_.../replay" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Replay is how you backfill after an outage on your side, or reprocess events once your handler is fixed. ## Rotating a secret ```bash theme={"system"} curl -X POST "https://api.useinvent.com/orgs/c/webhooks/whk_.../rotate" \ -H "Authorization: Bearer YOUR_API_KEY" ``` The response contains the new secret in full. The old secret stops signing immediately, so deploy the new one first, or accept a short window of rejected deliveries — they will be retried. # List Connection Actions Source: https://docs.useinvent.com/api-reference/metadata-actions/list-connection-actions https://api.useinvent.com/openapi.json get /metadata/actions Every action a connection exposes, with its input fields. Pass `lang` to localise the copy. # List activities Source: https://docs.useinvent.com/api-reference/orgs-activities/list-activities https://api.useinvent.com/openapi.json get /orgs/{org_id}/activities Retrieve an activity timeline for the org, sorted by creation date (newest first). Filter by any combination of contact, table, record, actor, assistant, or segment. # Bulk Agent Actions Source: https://docs.useinvent.com/api-reference/orgs-agents/bulk-agent-actions https://api.useinvent.com/openapi.json post /orgs/{org_id}/agents/{agent_id}/actions/bulk Create and delete multiple agent actions in a single request. # Create Agent Action Source: https://docs.useinvent.com/api-reference/orgs-agents/create-agent-action https://api.useinvent.com/openapi.json post /orgs/{org_id}/agents/{agent_id}/actions Create a new action for a specific agent. # Delete Agent Action Source: https://docs.useinvent.com/api-reference/orgs-agents/delete-agent-action https://api.useinvent.com/openapi.json delete /orgs/{org_id}/agents/{agent_id}/actions/{action_id} Delete an existing agent action. # Get Agent Action Source: https://docs.useinvent.com/api-reference/orgs-agents/get-agent-action https://api.useinvent.com/openapi.json get /orgs/{org_id}/agents/{agent_id}/actions/{action_id} Fetch a specific agent action by ID. # Get Agent Actions Source: https://docs.useinvent.com/api-reference/orgs-agents/get-agent-actions https://api.useinvent.com/openapi.json get /orgs/{org_id}/agents/{agent_id}/actions Fetch all actions for a specific agent. # Reorder Agent Actions Source: https://docs.useinvent.com/api-reference/orgs-agents/reorder-agent-actions https://api.useinvent.com/openapi.json patch /orgs/{org_id}/agents/{agent_id}/actions/reorder Reorder the actions of a specific agent. # Update Agent Action Source: https://docs.useinvent.com/api-reference/orgs-agents/update-agent-action https://api.useinvent.com/openapi.json patch /orgs/{org_id}/agents/{agent_id}/actions/{action_id} Update an existing agent action. # Get Assistant Stats Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-assistant-stats https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/assistants Get per-assistant performance statistics for the specified organization. # Get Broadcast Analytics Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-broadcast-analytics https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/broadcasts Get aggregated delivery and engagement stats per broadcast. # Get Broadcast Detail Analytics Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-broadcast-detail-analytics https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/broadcasts/{broadcast_id} Funnel, per-day engagement series, channels and failure reasons for one broadcast. # Get Broadcasts Overview Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-broadcasts-overview https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/broadcasts/overview Org-wide broadcast analytics for a period: delivery funnel, volume over time, channel and failure breakdowns, and per-broadcast performance. # Get Channel Distribution Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-channel-distribution https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/channels Get conversation counts grouped by channel (channel_type) for the specified organization. # Get Contact Growth Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-contact-growth https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/contacts/growth Get new and unsubscribed contact counts over time with running total. # Get Contacts by Channel Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-contacts-by-channel https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/contacts/by-channel Get contact count per channel type. # Get Conversations Analytics Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-conversations-analytics https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/conversations Everything the Conversations analytics view renders, in one call: KPIs, the handoff flow, per-channel volume, message split, resolution and CSAT trends, and the takeover-time distribution. The channel filter applies to conversation and message volume; outcome metrics (resolution, handoffs, CSAT) are not channel-segmented. # Get Org Dashboard Analytics Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-org-dashboard-analytics https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/dashboard Get the analytics for the specified organization. # Get Org Metric Total Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-org-metric-total https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/metrics/total Get the total of metrics for the specified organization. # Get Org Metric Types Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-org-metric-types https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/metrics/types Get the types of metrics for the specified organization. # Get Org Metrics Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-org-metrics https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/metrics Get the metrics for the specified organization. # Get Response Times Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-response-times https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/response-times Get average and median resolution time and human response time after transfer. # Get Team Stats Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-team-stats https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/team Get per-member performance statistics for the specified organization. # Get Top Segments Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-top-segments https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/contacts/top-segments Get top segments by contact count. # Get Workflow Analytics Source: https://docs.useinvent.com/api-reference/orgs-analytics/get-workflow-analytics https://api.useinvent.com/openapi.json get /orgs/{org_id}/analytics/workflows Get aggregated run stats per workflow. # Bulk Assistant Actions Source: https://docs.useinvent.com/api-reference/orgs-assistants/bulk-assistant-actions https://api.useinvent.com/openapi.json post /orgs/{org_id}/assistants/{assistant_id}/actions/bulk Create and delete multiple assistant actions in a single request. # Create Assistant Source: https://docs.useinvent.com/api-reference/orgs-assistants/create-assistant https://api.useinvent.com/openapi.json post /orgs/{org_id}/assistants Create a new assistant for a specific org. # Create Assistant Action Source: https://docs.useinvent.com/api-reference/orgs-assistants/create-assistant-action https://api.useinvent.com/openapi.json post /orgs/{org_id}/assistants/{assistant_id}/actions Create a new action for a specific assistant. # Create Assistant Channel Source: https://docs.useinvent.com/api-reference/orgs-assistants/create-assistant-channel https://api.useinvent.com/openapi.json post /orgs/{org_id}/assistants/{assistant_id}/channels Connect a specific assistant to a new channel. # Delete Assistant Source: https://docs.useinvent.com/api-reference/orgs-assistants/delete-assistant https://api.useinvent.com/openapi.json delete /orgs/{org_id}/assistants/{assistant_id} Delete an existing assistant. # Delete Assistant Action Source: https://docs.useinvent.com/api-reference/orgs-assistants/delete-assistant-action https://api.useinvent.com/openapi.json delete /orgs/{org_id}/assistants/{assistant_id}/actions/{action_id} Delete an existing assistant action. # Delete Assistant Channel Source: https://docs.useinvent.com/api-reference/orgs-assistants/delete-assistant-channel https://api.useinvent.com/openapi.json delete /orgs/{org_id}/assistants/{assistant_id}/channels/{channel_id} Delete an existing assistant channel. # Duplicate an Assistant Source: https://docs.useinvent.com/api-reference/orgs-assistants/duplicate-an-assistant https://api.useinvent.com/openapi.json post /orgs/{org_id}/assistants/{assistant_id}/duplicate Duplicate an assistant including its actions, agents, and knowledge links. Integrations are not cloned. When duplicating to a different org, connections, agents, and knowledge links are excluded. # Get Assistant Source: https://docs.useinvent.com/api-reference/orgs-assistants/get-assistant https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants/{assistant_id} Fetch a specific assistant by ID. # Get Assistant Action Source: https://docs.useinvent.com/api-reference/orgs-assistants/get-assistant-action https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants/{assistant_id}/actions/{action_id} Fetch a specific assistant action by ID. # Get Assistant Actions Source: https://docs.useinvent.com/api-reference/orgs-assistants/get-assistant-actions https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants/{assistant_id}/actions Fetch all actions for a specific assistant. # Get Assistant Channel Source: https://docs.useinvent.com/api-reference/orgs-assistants/get-assistant-channel https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants/{assistant_id}/channels/{channel_id} Fetch a specific assistant channel by ID. # Get Assistant Channels Source: https://docs.useinvent.com/api-reference/orgs-assistants/get-assistant-channels https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants/{assistant_id}/channels Fetch all channels for a specific assistant. # Get Assistants Source: https://docs.useinvent.com/api-reference/orgs-assistants/get-assistants https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants Fetch all assistants for a specific org. # Get Contents Source: https://docs.useinvent.com/api-reference/orgs-assistants/get-contents https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants/{assistant_id}/knowledge/contents Fetch all contents for the organization. # Link Knowledge Content to Assistant Source: https://docs.useinvent.com/api-reference/orgs-assistants/link-knowledge-content-to-assistant https://api.useinvent.com/openapi.json post /orgs/{org_id}/assistants/{assistant_id}/knowledge/contents/{content_id} Link an existing knowledge content to an assistant. # Reorder Assistant Actions Source: https://docs.useinvent.com/api-reference/orgs-assistants/reorder-assistant-actions https://api.useinvent.com/openapi.json patch /orgs/{org_id}/assistants/{assistant_id}/actions/reorder Reorder the actions of a specific assistant. # Rotate Assistant Secret Key Source: https://docs.useinvent.com/api-reference/orgs-assistants/rotate-assistant-secret-key https://api.useinvent.com/openapi.json post /orgs/{org_id}/assistants/{assistant_id}/rotate-secret-key Rotate the secret key for a specific assistant. # Search Available Contents Source: https://docs.useinvent.com/api-reference/orgs-assistants/search-available-contents https://api.useinvent.com/openapi.json get /orgs/{org_id}/assistants/{assistant_id}/knowledge/contents/search Search for available contents that can be linked to the assistant. # Unlink Knowledge Content from Assistant Source: https://docs.useinvent.com/api-reference/orgs-assistants/unlink-knowledge-content-from-assistant https://api.useinvent.com/openapi.json delete /orgs/{org_id}/assistants/{assistant_id}/knowledge/contents/{content_id} Unlink an existing knowledge content from an assistant. # Update Assistant Source: https://docs.useinvent.com/api-reference/orgs-assistants/update-assistant https://api.useinvent.com/openapi.json patch /orgs/{org_id}/assistants/{assistant_id} Update an existing assistant. # Update Assistant Action Source: https://docs.useinvent.com/api-reference/orgs-assistants/update-assistant-action https://api.useinvent.com/openapi.json patch /orgs/{org_id}/assistants/{assistant_id}/actions/{action_id} Update an existing assistant action. # Update Assistant Channel Source: https://docs.useinvent.com/api-reference/orgs-assistants/update-assistant-channel https://api.useinvent.com/openapi.json patch /orgs/{org_id}/assistants/{assistant_id}/channels/{channel_id} Update an existing assistant channel. # Get Audit Logs Source: https://docs.useinvent.com/api-reference/orgs-audit-logs/get-audit-logs https://api.useinvent.com/openapi.json get /orgs/{org_id}/audit-logs Fetch all audit logs for a specific org. # Activate a Transactional Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/activate-a-transactional-broadcast https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/activate Activate a transactional broadcast so it can accept triggers. Allowed from DRAFT or PAUSED. Requires at least one template. # Cancel a Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/cancel-a-broadcast https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/cancel Cancel a broadcast, returning it to DRAFT so it can be edited and sent again. Can only cancel broadcasts in SCHEDULED or SENDING status. Cancelling a live send keeps the messages already delivered and discards the unsent remainder; a later send skips every contact that already received it. # Create a Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/create-a-broadcast https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts Create a new broadcast for the organization. # Create a Broadcast Template Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/create-a-broadcast-template https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/templates Create a new template for a broadcast. The broadcast must be in DRAFT status. # Create Broadcast Field Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/create-broadcast-field https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/fields Create a new field for a broadcast. # Delete a Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/delete-a-broadcast https://api.useinvent.com/openapi.json delete /orgs/{org_id}/broadcasts/{broadcast_id} Delete a broadcast. Cannot delete broadcasts that are currently sending. # Delete a Broadcast Template Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/delete-a-broadcast-template https://api.useinvent.com/openapi.json delete /orgs/{org_id}/broadcasts/{broadcast_id}/templates/{template_id} Delete a template. The broadcast must be in DRAFT status. Templates cannot be deleted after a broadcast starts. # Delete Broadcast Field Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/delete-broadcast-field https://api.useinvent.com/openapi.json delete /orgs/{org_id}/broadcasts/{broadcast_id}/fields/{field_id} Delete a field and all its entries from a broadcast. # Delete Broadcast Recipient Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/delete-broadcast-recipient https://api.useinvent.com/openapi.json delete /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/{recipient_id} Remove a recipient that has not reached anyone yet — imported, queued, failed or skipped. # Dry Run Update Broadcast Field Entries Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/dry-run-update-broadcast-field-entries https://api.useinvent.com/openapi.json patch /orgs/{org_id}/broadcasts/{broadcast_id}/fields/entries/dry Dry run to classify entries as valid or invalid without importing anything. # Duplicate a Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/duplicate-a-broadcast https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/duplicate Duplicate a broadcast including its segments and templates. The new broadcast will be in DRAFT status. # Get a Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-a-broadcast https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id} Get a specific broadcast by its ID. # Get a Broadcast Template Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-a-broadcast-template https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/templates/{template_id} Get a specific template by its ID. # Get Broadcast Channel Recipient Counts Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcast-channel-recipient-counts https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/counts Get recipient counts per channel type for a specific broadcast. # Get Broadcast Field Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcast-field https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/fields/{field_id} Get a specific field for a broadcast. # Get Broadcast Field Entries Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcast-field-entries https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/fields/entries List field entries for a broadcast. # Get Broadcast Fields Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcast-fields https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/fields List all fields for a broadcast. # Get Broadcast Recipient Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcast-recipient https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/{recipient_id} Get a specific recipient for a broadcast. # Get Broadcast Recipients Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcast-recipients https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/recipients Get recipients for a specific broadcast. # Get Broadcast Templates Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcast-templates https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/templates Get all templates for a specific broadcast. # Get Broadcasts Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcasts https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts Get a list of broadcasts for a specific org. # Get Broadcasts Interactions Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-broadcasts-interactions https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/interactions Get a list of interactions for a specific broadcast. # Get Imported Broadcast Recipients Count Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-imported-broadcast-recipients-count https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/import How many contacts were imported straight into this broadcast's audience. # Get Org Broadcast Recipients Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/get-org-broadcast-recipients https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/recipients Get recipients for a specific org. # Import Broadcast Recipients Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/import-broadcast-recipients https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/import Add contacts to a marketing broadcast's audience. They are resolved into recipients when the broadcast sends. # List Broadcast Audience Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/list-broadcast-audience https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/audience The contacts this broadcast sends to, resolved from everyone, its segments and the contacts imported into it. # List Imported Broadcast Contacts Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/list-imported-broadcast-contacts https://api.useinvent.com/openapi.json get /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/import/contacts The contacts imported straight into this broadcast's audience. # Pause a Transactional Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/pause-a-transactional-broadcast https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/pause Pause an active transactional broadcast. Triggers are rejected until the broadcast is activated again. Configuration is preserved. # Remove Imported Broadcast Recipients Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/remove-imported-broadcast-recipients https://api.useinvent.com/openapi.json delete /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/import Remove imported contacts from a broadcast's audience. Omit contact_ids to remove all of them. # Retry Failed Broadcast Recipients Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/retry-failed-broadcast-recipients https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/recipients/retry Put failed recipients back on the send queue. Omit recipient_ids to retry every failed recipient. # Schedule a Marketing Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/schedule-a-marketing-broadcast https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/schedule Queue a marketing broadcast for delivery. Fires immediately when the broadcast has no scheduled_at, otherwise waits for the scheduled time. Can only be called on broadcasts in DRAFT, CANCELLED or FAILED status. # Send a Broadcast Test Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/send-a-broadcast-test https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/send/test Send a broadcast test. Can only send tests for broadcasts in DRAFT, CANCELLED or FAILED status. # Send a Transactional Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/send-a-transactional-broadcast https://api.useinvent.com/openapi.json post /orgs/{org_id}/broadcasts/{broadcast_id}/send Fire a transactional broadcast for a single recipient. Fans out across the broadcast templates: one BroadcastRecipient row is created per template (sent or skipped). # Update a Broadcast Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/update-a-broadcast https://api.useinvent.com/openapi.json patch /orgs/{org_id}/broadcasts/{broadcast_id} Update a specific broadcast by its ID. Only draft broadcasts can be updated. # Update a Broadcast Template Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/update-a-broadcast-template https://api.useinvent.com/openapi.json patch /orgs/{org_id}/broadcasts/{broadcast_id}/templates/{template_id} Update an existing template. The broadcast must be in DRAFT status. # Update Broadcast Field Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/update-broadcast-field https://api.useinvent.com/openapi.json patch /orgs/{org_id}/broadcasts/{broadcast_id}/fields/{field_id} Update a specific field for a broadcast. # Update Broadcast Field Entries Source: https://docs.useinvent.com/api-reference/orgs-broadcasts/update-broadcast-field-entries https://api.useinvent.com/openapi.json patch /orgs/{org_id}/broadcasts/{broadcast_id}/fields/entries Update field entries for broadcast recipients. Replaces any existing entries for this broadcast. # Authenticate OAuth Provider Source: https://docs.useinvent.com/api-reference/orgs-connections/authenticate-oauth-provider https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/oauth/validate Authenticate with an OAuth provider to create a new connection. # Browse the WhatsApp template library Source: https://docs.useinvent.com/api-reference/orgs-connections/browse-the-whatsapp-template-library https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/templates/library Browse Meta's pre-approved template library (read through a Redis cache). # Connect OAuth Provider Source: https://docs.useinvent.com/api-reference/orgs-connections/connect-oauth-provider https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/oauth/connect Authenticate with an OAuth provider and create or re-authenticate the connection in one call. Credentials stay on the server. # Create a WhatsApp QR code Source: https://docs.useinvent.com/api-reference/orgs-connections/create-a-whatsapp-qr-code https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/{connection_id}/whatsapp/phone-numbers/{phone_number_id}/qr-codes Create a QR code with a prefilled message on the WhatsApp phone number. # Create a WhatsApp template Source: https://docs.useinvent.com/api-reference/orgs-connections/create-a-whatsapp-template https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/{connection_id}/whatsapp/templates Create a custom WhatsApp message template and submit it to Meta for review. # Create a WhatsApp template from the library Source: https://docs.useinvent.com/api-reference/orgs-connections/create-a-whatsapp-template-from-the-library https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/{connection_id}/whatsapp/templates/library Create a message template from an entry in Meta's pre-approved library. Submits the template to Meta for review. # Create OAuth Provider URL Source: https://docs.useinvent.com/api-reference/orgs-connections/create-oauth-provider-url https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/oauth/url Create a URL to authenticate with an OAuth provider for a specific organization. # Create User Connection Source: https://docs.useinvent.com/api-reference/orgs-connections/create-user-connection https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections Create a new connection for the specified app. # Delete a Connection Source: https://docs.useinvent.com/api-reference/orgs-connections/delete-a-connection https://api.useinvent.com/openapi.json delete /orgs/{org_id}/connections/{connection_id} Delete an existing connection. # Delete a WhatsApp QR code Source: https://docs.useinvent.com/api-reference/orgs-connections/delete-a-whatsapp-qr-code https://api.useinvent.com/openapi.json delete /orgs/{org_id}/connections/{connection_id}/whatsapp/phone-numbers/{phone_number_id}/qr-codes/{code} Delete a QR code from the WhatsApp phone number. # Delete a WhatsApp template Source: https://docs.useinvent.com/api-reference/orgs-connections/delete-a-whatsapp-template https://api.useinvent.com/openapi.json delete /orgs/{org_id}/connections/{connection_id}/whatsapp/templates/{template_id} Delete a WhatsApp message template from the WABA. Meta requires `name` (and `language` for cache invalidation) in the query alongside the template id. # Deregister a WhatsApp phone number Source: https://docs.useinvent.com/api-reference/orgs-connections/deregister-a-whatsapp-phone-number https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/{connection_id}/whatsapp/phone-numbers/{phone_number_id}/deregister Deregister the phone number from the Cloud API; it stays on the WhatsApp Business account and can be registered again. # Edit a WhatsApp template Source: https://docs.useinvent.com/api-reference/orgs-connections/edit-a-whatsapp-template https://api.useinvent.com/openapi.json patch /orgs/{org_id}/connections/{connection_id}/whatsapp/templates/{template_id} Edit an existing WhatsApp message template. Category and component changes may require Meta re-approval. # Get a Connection Source: https://docs.useinvent.com/api-reference/orgs-connections/get-a-connection https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id} Retrieve details of a specific connection. # Get a WhatsApp template Source: https://docs.useinvent.com/api-reference/orgs-connections/get-a-whatsapp-template https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/templates/{template_id} Fetch a single WhatsApp template by id (read-through cache). # Get Org Connections Source: https://docs.useinvent.com/api-reference/orgs-connections/get-org-connections https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections Retrieve a list of connections for the specified app. # Get the fields for an action Source: https://docs.useinvent.com/api-reference/orgs-connections/get-the-fields-for-an-action https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/actions/fields Returns the input field schema for a connection action, so your integration can dynamically render the form used to configure that action. # Get the live tools of a dynamic action Source: https://docs.useinvent.com/api-reference/orgs-connections/get-the-live-tools-of-a-dynamic-action https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/actions/tools Returns the tool catalog a dynamic action (an MCP server, an OpenAPI spec) exposes for the given input, minus the excluded tools, with the time it was last loaded. # Get the options for an action Source: https://docs.useinvent.com/api-reference/orgs-connections/get-the-options-for-an-action https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/actions/options Returns searchable, paginated options for a connection action's fields, so you can populate dropdowns and selectors as the user configures it. # Get the WhatsApp Business account overview Source: https://docs.useinvent.com/api-reference/orgs-connections/get-the-whatsapp-business-account-overview https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/account Account info, health, messaging limit, billing state and recent account activity, read through a Redis cache. # Get the WhatsApp business profile Source: https://docs.useinvent.com/api-reference/orgs-connections/get-the-whatsapp-business-profile https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/profile Fetch the WhatsApp business profile of a phone number, read through a Redis cache. # List the screens of a WhatsApp Flow Source: https://docs.useinvent.com/api-reference/orgs-connections/list-the-screens-of-a-whatsapp-flow https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/flows/{flow_id}/screens The screens declared in the flow's JSON, for picking a flow button's entry screen (read through a Redis cache). # List WhatsApp Flows Source: https://docs.useinvent.com/api-reference/orgs-connections/list-whatsapp-flows https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/flows List the WhatsApp Flows of a connection's WABA (read through a Redis cache). Flows are authored in Meta's Flow builder. # List WhatsApp phone numbers Source: https://docs.useinvent.com/api-reference/orgs-connections/list-whatsapp-phone-numbers https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/phone-numbers List the phone numbers on the WhatsApp Business accounts of a connection, read through a Redis cache. # List WhatsApp product catalogs Source: https://docs.useinvent.com/api-reference/orgs-connections/list-whatsapp-product-catalogs https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/catalogs List the product catalogs connected to a connection's WABA (read through a Redis cache). Catalogs are authored in Meta's Commerce Manager. # List WhatsApp QR codes Source: https://docs.useinvent.com/api-reference/orgs-connections/list-whatsapp-qr-codes https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/phone-numbers/{phone_number_id}/qr-codes List the QR codes and prefilled messages of a WhatsApp phone number, read through a Redis cache. # List WhatsApp templates Source: https://docs.useinvent.com/api-reference/orgs-connections/list-whatsapp-templates https://api.useinvent.com/openapi.json get /orgs/{org_id}/connections/{connection_id}/whatsapp/templates List WhatsApp message templates (all statuses) for a connection, read through a Redis cache. # Refresh WhatsApp templates Source: https://docs.useinvent.com/api-reference/orgs-connections/refresh-whatsapp-templates https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/{connection_id}/whatsapp/templates/refresh Bust the cache and refetch templates from Meta. # Request a WhatsApp display name change Source: https://docs.useinvent.com/api-reference/orgs-connections/request-a-whatsapp-display-name-change https://api.useinvent.com/openapi.json post /orgs/{org_id}/connections/{connection_id}/whatsapp/phone-numbers/{phone_number_id}/display-name Submit a new display name for WhatsApp review; the approval webhook applies it automatically. # Update a Connection Source: https://docs.useinvent.com/api-reference/orgs-connections/update-a-connection https://api.useinvent.com/openapi.json patch /orgs/{org_id}/connections/{connection_id} Update the details of an existing connection. # Update a WhatsApp QR code Source: https://docs.useinvent.com/api-reference/orgs-connections/update-a-whatsapp-qr-code https://api.useinvent.com/openapi.json patch /orgs/{org_id}/connections/{connection_id}/whatsapp/phone-numbers/{phone_number_id}/qr-codes/{code} Update the prefilled message of a WhatsApp QR code. # Update the WhatsApp business profile Source: https://docs.useinvent.com/api-reference/orgs-connections/update-the-whatsapp-business-profile https://api.useinvent.com/openapi.json patch /orgs/{org_id}/connections/{connection_id}/whatsapp/profile Update profile fields on WhatsApp; the profile picture URL is resolved to a media handle server-side. # Add a custom channel to a contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/add-a-custom-channel-to-a-contact https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/channels Add a new custom channel to an existing contact. At least one field (name, email, phone, or username) must be provided. # Add Segment to Contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/add-segment-to-contact https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/segments/{segment_id} Add a segment to a contact. # Clear all contact memories Source: https://docs.useinvent.com/api-reference/orgs-contacts/clear-all-contact-memories https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/{contact_id}/memories Delete all memories associated with a contact. # Create a chat on a contact channel Source: https://docs.useinvent.com/api-reference/orgs-contacts/create-a-chat-on-a-contact-channel https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/channels/{channel_id}/chats Start a new chat with a contact on one of its custom channels. The chat is seeded with the contact channel as the sole member; the admin is not a chat member. Any initial message is authored as the contact. # Create a Contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/create-a-contact https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts Create a new contact for the organization. # Create a contact comment Source: https://docs.useinvent.com/api-reference/orgs-contacts/create-a-contact-comment https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/comments Add a new comment to a contact. # Create Multiple Contacts Source: https://docs.useinvent.com/api-reference/orgs-contacts/create-multiple-contacts https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/bulk Create multiple contacts for the organization in bulk. # Decide Action Approval as a contact on a channel Source: https://docs.useinvent.com/api-reference/orgs-contacts/decide-action-approval-as-a-contact-on-a-channel https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/channels/{channel_id}/chats/{chat_id}/messages/{message_id}/approvals/{tool_call_id} Decide on a pending action approval, recorded as the contact (not as the admin / API key). Only custom channels are supported. Use this from custom integrations so the decision is attributed to the right chat member. # Delete a contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/delete-a-contact https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/{contact_id} Delete a contact and all associated channels and notes. # Delete a contact channel Source: https://docs.useinvent.com/api-reference/orgs-contacts/delete-a-contact-channel https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/{contact_id}/channels/{channel_id} Delete a contact channel. # Delete a contact comment Source: https://docs.useinvent.com/api-reference/orgs-contacts/delete-a-contact-comment https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/{contact_id}/comments/{activity_id} Remove a comment from a contact. # Delete a specific contact memory Source: https://docs.useinvent.com/api-reference/orgs-contacts/delete-a-specific-contact-memory https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/{contact_id}/memories/{memory_id} Delete a single memory by ID for a contact. # Delete Contact File Source: https://docs.useinvent.com/api-reference/orgs-contacts/delete-contact-file https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/{contact_id}/files/{file_id} Delete a file from a contact. If the file belongs to a note with no text and is the last attachment, the note is deleted too. # Delete Multiple Contacts Source: https://docs.useinvent.com/api-reference/orgs-contacts/delete-multiple-contacts https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/bulk Delete multiple contacts and all associated channels and notes. # Dry Run Create Multiple Contacts Source: https://docs.useinvent.com/api-reference/orgs-contacts/dry-run-create-multiple-contacts https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/bulk/dry Dry run create multiple contacts for the organization in bulk. # Get a Contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-a-contact https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id} Get a specific contact by its ID. # Get a contact comment Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-a-contact-comment https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/comments/{activity_id} Retrieve a specific comment for a contact. # Get Contact Files Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-contact-files https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/files Retrieve all files for this contact, including chat files and direct uploads. # Get Contact Last Seen Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-contact-last-seen https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/last-seen Get the timestamp of the last message from or to this contact. # Get contact memories Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-contact-memories https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/memories Retrieve all memories associated with a contact, sorted by importance. # Get Contact Segments Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-contact-segments https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/segments Get all segments for a specific contact. # Get Contact Stats Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-contact-stats https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/stats Get contact subscription stats (total, subscribed, unsubscribed, blocked). # Get Contacts Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-contacts https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts Get a list of contacts for a specific org. # Get related entity counts for a contact channel Source: https://docs.useinvent.com/api-reference/orgs-contacts/get-related-entity-counts-for-a-contact-channel https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/channels/{channel_id}/stats Returns the number of chats and broadcast recipients linked to this channel. Use before deletion to warn the user about impact. # List contact activities Source: https://docs.useinvent.com/api-reference/orgs-contacts/list-contact-activities https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/activities Retrieve the activity timeline for a contact, sorted by creation date (newest first). # List contact comments Source: https://docs.useinvent.com/api-reference/orgs-contacts/list-contact-comments https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/comments Retrieve all comments for a contact, sorted by creation date (newest first). # List contact fields Source: https://docs.useinvent.com/api-reference/orgs-contacts/list-contact-fields https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/fields List of custom contact fields # List duplicate contact groups Source: https://docs.useinvent.com/api-reference/orgs-contacts/list-duplicate-contact-groups https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/duplicates Paginated list of contacts in this org that share at least one external channel. Each group has a recommended primary and the duplicates that would be merged into it. # List duplicates of a contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/list-duplicates-of-a-contact https://api.useinvent.com/openapi.json get /orgs/{org_id}/contacts/{contact_id}/duplicates Returns every contact in the same org that shares at least one external channel with the contact in the URL. # Merge contacts Source: https://docs.useinvent.com/api-reference/orgs-contacts/merge-contacts https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/merge Merge other contacts INTO the contact in the URL. If `source_contact_ids` is provided, those exact contacts are merged in; otherwise every auto-detected duplicate is merged. Source contacts are deleted. # Remove Segment from Contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/remove-segment-from-contact https://api.useinvent.com/openapi.json delete /orgs/{org_id}/contacts/{contact_id}/segments/{segment_id} Remove a segment from a contact. # Respond to Interactive Tool as a contact on a channel Source: https://docs.useinvent.com/api-reference/orgs-contacts/respond-to-interactive-tool-as-a-contact-on-a-channel https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/channels/{channel_id}/chats/{chat_id}/messages/{message_id}/tools/{tool_call_id}/respond Submit a user response to an interactive tool (e.g. an action approval), recorded as the contact (not as the admin / API key). Only custom channels are supported. Use this from custom integrations so the response is attributed to the right chat member. # Send a message as a contact on a channel Source: https://docs.useinvent.com/api-reference/orgs-contacts/send-a-message-as-a-contact-on-a-channel https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/channels/{channel_id}/chats/{chat_id}/messages Post a message into an existing chat, authored as the contact (not as the admin). Only custom channels are supported. # Update a Contact Source: https://docs.useinvent.com/api-reference/orgs-contacts/update-a-contact https://api.useinvent.com/openapi.json patch /orgs/{org_id}/contacts/{contact_id} Update a specific contact by its ID. # Update a contact channel (only for custom channels) Source: https://docs.useinvent.com/api-reference/orgs-contacts/update-a-contact-channel-only-for-custom-channels https://api.useinvent.com/openapi.json patch /orgs/{org_id}/contacts/{contact_id}/channels/{channel_id} Update a contact channel. Only channels of type 'custom' can be updated. For other channel types, the channel information is managed by the integration and cannot be modified directly. # Update a contact comment Source: https://docs.useinvent.com/api-reference/orgs-contacts/update-a-contact-comment https://api.useinvent.com/openapi.json patch /orgs/{org_id}/contacts/{contact_id}/comments/{activity_id} Update the content of an existing comment. # Upload Contact File Source: https://docs.useinvent.com/api-reference/orgs-contacts/upload-contact-file https://api.useinvent.com/openapi.json post /orgs/{org_id}/contacts/{contact_id}/files Upload a file to a contact. # Create Domain Source: https://docs.useinvent.com/api-reference/orgs-domains/create-domain https://api.useinvent.com/openapi.json post /orgs/{org_id}/domains Add a new domain to an org. # Delete Domain Source: https://docs.useinvent.com/api-reference/orgs-domains/delete-domain https://api.useinvent.com/openapi.json delete /orgs/{org_id}/domains/{domain_id} Delete a domain from an org. # Get a Domain Source: https://docs.useinvent.com/api-reference/orgs-domains/get-a-domain https://api.useinvent.com/openapi.json get /orgs/{org_id}/domains/{domain_id} Get a specific domain by its ID. # Get Domain DNS Provider Source: https://docs.useinvent.com/api-reference/orgs-domains/get-domain-dns-provider https://api.useinvent.com/openapi.json get /orgs/{org_id}/domains/{domain_id}/provider Detect the DNS provider for a custom domain via NS lookup. # Get Domain Status Source: https://docs.useinvent.com/api-reference/orgs-domains/get-domain-status https://api.useinvent.com/openapi.json post /orgs/{org_id}/domains/{domain_id}/status Get the status of a domain. # Get Domains Source: https://docs.useinvent.com/api-reference/orgs-domains/get-domains https://api.useinvent.com/openapi.json get /orgs/{org_id}/domains Get a list of domains for a specific org. # Verify Domain Source: https://docs.useinvent.com/api-reference/orgs-domains/verify-domain https://api.useinvent.com/openapi.json post /orgs/{org_id}/domains/{domain_id}/verify Verify a domain. This will check DNS records or HTTP verification file. # Add an Email Domain Source: https://docs.useinvent.com/api-reference/orgs-emails/add-an-email-domain https://api.useinvent.com/openapi.json post /orgs/{org_id}/emails/domains Add a new email domain for DKIM verification. Returns the DKIM TXT record to add to DNS. # Create an Email Identity Source: https://docs.useinvent.com/api-reference/orgs-emails/create-an-email-identity https://api.useinvent.com/openapi.json post /orgs/{org_id}/emails/identities Add a new email identity for the organization. # Delete an Email Domain Source: https://docs.useinvent.com/api-reference/orgs-emails/delete-an-email-domain https://api.useinvent.com/openapi.json delete /orgs/{org_id}/emails/domains/{domain_id} Delete an email domain and remove the identity from SES. Senders linked to this domain will be unlinked. # Delete an Email Identity Source: https://docs.useinvent.com/api-reference/orgs-emails/delete-an-email-identity https://api.useinvent.com/openapi.json delete /orgs/{org_id}/emails/identities/{identity_id} Delete an email identity and remove the identity from SES. # Get an Email Domain Source: https://docs.useinvent.com/api-reference/orgs-emails/get-an-email-domain https://api.useinvent.com/openapi.json get /orgs/{org_id}/emails/domains/{domain_id} Get a specific email domain by its ID. # Get an Email Identity Source: https://docs.useinvent.com/api-reference/orgs-emails/get-an-email-identity https://api.useinvent.com/openapi.json get /orgs/{org_id}/emails/identities/{identity_id} Get a specific email identity by its ID. # Get DNS Provider Source: https://docs.useinvent.com/api-reference/orgs-emails/get-dns-provider https://api.useinvent.com/openapi.json get /orgs/{org_id}/emails/domains/{domain_id}/provider Detect the DNS provider for a domain via NS lookup. Returns provider info including logo, DNS settings URL, and auto-configure URL when supported. # Get Email Domains Source: https://docs.useinvent.com/api-reference/orgs-emails/get-email-domains https://api.useinvent.com/openapi.json get /orgs/{org_id}/emails/domains Get a list of email domains for a specific org. # Get Email Identities Source: https://docs.useinvent.com/api-reference/orgs-emails/get-email-identities https://api.useinvent.com/openapi.json get /orgs/{org_id}/emails/identities Get a list of email identities for a specific org. # Resend Verification Email Source: https://docs.useinvent.com/api-reference/orgs-emails/resend-verification-email https://api.useinvent.com/openapi.json post /orgs/{org_id}/emails/identities/{identity_id}/resend Resend the verification email for a pending identity. # Update an Email Identity Source: https://docs.useinvent.com/api-reference/orgs-emails/update-an-email-identity https://api.useinvent.com/openapi.json patch /orgs/{org_id}/emails/identities/{identity_id} Update the name or default status of an email identity. # Update Email Domain Settings Source: https://docs.useinvent.com/api-reference/orgs-emails/update-email-domain-settings https://api.useinvent.com/openapi.json patch /orgs/{org_id}/emails/domains/{domain_id} Update tracking configuration for an email domain. # Verify an Email Domain Source: https://docs.useinvent.com/api-reference/orgs-emails/verify-an-email-domain https://api.useinvent.com/openapi.json post /orgs/{org_id}/emails/domains/{domain_id}/verify Check the current DKIM verification status of an email domain. # Verify an Email Identity Source: https://docs.useinvent.com/api-reference/orgs-emails/verify-an-email-identity https://api.useinvent.com/openapi.json post /orgs/{org_id}/emails/identities/{identity_id}/verify Check the current verification status of an email identity. # Create File Source: https://docs.useinvent.com/api-reference/orgs-files/create-file https://api.useinvent.com/openapi.json post /orgs/{org_id}/files Create a new file. # Delete File Source: https://docs.useinvent.com/api-reference/orgs-files/delete-file https://api.useinvent.com/openapi.json delete /orgs/{org_id}/files/{file_id} Delete a specific file. # Get File Source: https://docs.useinvent.com/api-reference/orgs-files/get-file https://api.useinvent.com/openapi.json get /orgs/{org_id}/files/{file_id} Retrieve a specific file. # List Files Source: https://docs.useinvent.com/api-reference/orgs-files/list-files https://api.useinvent.com/openapi.json get /orgs/{org_id}/files Retrieve a list of files. # Chat Org Inbox WebSocket Source: https://docs.useinvent.com/api-reference/orgs-inbox/chat-org-inbox-websocket https://api.useinvent.com/openapi.json get /orgs/{org_id}/inbox/ws Get a WebSocket for chat events for an organization inbox. # Get Org Inbox Chats Source: https://docs.useinvent.com/api-reference/orgs-inbox/get-org-inbox-chats https://api.useinvent.com/openapi.json get /orgs/{org_id}/inbox Get a list of inbox chats for a specific org. # Create Child Content Source: https://docs.useinvent.com/api-reference/orgs-knowledge/create-child-content https://api.useinvent.com/openapi.json post /orgs/{org_id}/knowledge/contents/{content_id}/children Create a new child content for the organization. # Create Content Source: https://docs.useinvent.com/api-reference/orgs-knowledge/create-content https://api.useinvent.com/openapi.json post /orgs/{org_id}/knowledge/contents Create a new content for the organization. # Delete Content Source: https://docs.useinvent.com/api-reference/orgs-knowledge/delete-content https://api.useinvent.com/openapi.json delete /orgs/{org_id}/knowledge/contents/{content_id} Delete an existing content. # Get Content Source: https://docs.useinvent.com/api-reference/orgs-knowledge/get-content https://api.useinvent.com/openapi.json get /orgs/{org_id}/knowledge/contents/{content_id} Fetch a specific content by ID. # Get Content Chunk Source: https://docs.useinvent.com/api-reference/orgs-knowledge/get-content-chunk https://api.useinvent.com/openapi.json get /orgs/{org_id}/knowledge/contents/{content_id}/chunks/{chunk_id} Fetch a specific content chunk by ID. # Get Content Chunks Source: https://docs.useinvent.com/api-reference/orgs-knowledge/get-content-chunks https://api.useinvent.com/openapi.json get /orgs/{org_id}/knowledge/contents/{content_id}/chunks Fetch all chunks for a specific content. # Get Contents Source: https://docs.useinvent.com/api-reference/orgs-knowledge/get-contents https://api.useinvent.com/openapi.json get /orgs/{org_id}/knowledge/contents Fetch all contents for the organization. # Get Vector Index Source: https://docs.useinvent.com/api-reference/orgs-knowledge/get-vector-index https://api.useinvent.com/openapi.json get /orgs/{org_id}/knowledge/index Fetch the vector index for the organization. # Get Vector Index Source: https://docs.useinvent.com/api-reference/orgs-knowledge/get-vector-index-1 https://api.useinvent.com/openapi.json get /orgs/{org_id}/knowledge/main-index Fetch the vector index for the organization. # Reindex Content Source: https://docs.useinvent.com/api-reference/orgs-knowledge/reindex-content https://api.useinvent.com/openapi.json post /orgs/{org_id}/knowledge/contents/{content_id}/reindex Reindex an existing content. # Update Content Source: https://docs.useinvent.com/api-reference/orgs-knowledge/update-content https://api.useinvent.com/openapi.json patch /orgs/{org_id}/knowledge/contents/{content_id} Update an existing content. # Update Content URL Source: https://docs.useinvent.com/api-reference/orgs-knowledge/update-content-url https://api.useinvent.com/openapi.json patch /orgs/{org_id}/knowledge/contents/{content_id}/url Update the URL of an existing content. # Change Role in Sub-Organization Source: https://docs.useinvent.com/api-reference/orgs-orgs/change-role-in-sub-organization https://api.useinvent.com/openapi.json patch /orgs/{org_id}/orgs/{sub_org_id}/role Changes the role of the authenticated user in the specified sub-organization. # Create Sub-Organization Source: https://docs.useinvent.com/api-reference/orgs-orgs/create-sub-organization https://api.useinvent.com/openapi.json post /orgs/{org_id}/orgs Creates a new sub-organization belonging to the specified organization. # Detach Sub-Organization Source: https://docs.useinvent.com/api-reference/orgs-orgs/detach-sub-organization https://api.useinvent.com/openapi.json delete /orgs/{org_id}/orgs/{sub_org_id} Detaches a sub-organization from the parent, making it a standalone organization. The sub-organization retains its current features and data. # Get Consolidated Sub-Organizations Usage Source: https://docs.useinvent.com/api-reference/orgs-orgs/get-consolidated-sub-organizations-usage https://api.useinvent.com/openapi.json get /orgs/{org_id}/orgs/usage Returns aggregated meter usage across all sub-organizations for the specified date range and interval. # Get Sub-Organization Source: https://docs.useinvent.com/api-reference/orgs-orgs/get-sub-organization https://api.useinvent.com/openapi.json get /orgs/{org_id}/orgs/{sub_org_id} Returns a single sub-organization by ID belonging to the specified parent organization. # Join Sub-Organization Source: https://docs.useinvent.com/api-reference/orgs-orgs/join-sub-organization https://api.useinvent.com/openapi.json post /orgs/{org_id}/orgs/{sub_org_id}/join Adds the authenticated parent org admin as a member of the specified sub-organization with the given role. # List Sub-Organizations Source: https://docs.useinvent.com/api-reference/orgs-orgs/list-sub-organizations https://api.useinvent.com/openapi.json get /orgs/{org_id}/orgs Returns all sub-organizations belonging to the specified organization. # Transfer Organization Source: https://docs.useinvent.com/api-reference/orgs-orgs/transfer-organization https://api.useinvent.com/openapi.json post /orgs/{org_id}/orgs/{sub_org_id} Transfers an existing standalone organization to become a sub-organization of the specified parent. The requesting user must be an admin of both organizations. # Update Sub-Organization Source: https://docs.useinvent.com/api-reference/orgs-orgs/update-sub-organization https://api.useinvent.com/openapi.json patch /orgs/{org_id}/orgs/{sub_org_id} Updates a sub-organization from the parent. Accepts a partial `config` (deep-merged server-side, includes `modules` visibility toggles) and an optional `logo_id`. Feature flags are not writable from this endpoint. # Update Sub-Organization Billing Config Source: https://docs.useinvent.com/api-reference/orgs-orgs/update-sub-organization-billing-config https://api.useinvent.com/openapi.json patch /orgs/{org_id}/orgs/{sub_org_id}/billing Updates billing configuration for a sub-organization, including spending cap. Only parent organization admins can call this endpoint. # Add a block Source: https://docs.useinvent.com/api-reference/orgs-pages/add-a-block https://api.useinvent.com/openapi.json post /orgs/{org_id}/pages/{page_ref}/blocks Add a block to a page. Only the type is required; data blocks can be pointed at a table or view later. # Create a page Source: https://docs.useinvent.com/api-reference/orgs-pages/create-a-page https://api.useinvent.com/openapi.json post /orgs/{org_id}/pages Create a new page. The slug is auto-generated from the title when omitted. # Delete a page Source: https://docs.useinvent.com/api-reference/orgs-pages/delete-a-page https://api.useinvent.com/openapi.json delete /orgs/{org_id}/pages/{page_ref} Permanently delete a page and its blocks. Child pages are promoted to roots. # Get a page Source: https://docs.useinvent.com/api-reference/orgs-pages/get-a-page https://api.useinvent.com/openapi.json get /orgs/{org_id}/pages/{page_ref} Get a single page with its blocks, by slug or id. # Get block data Source: https://docs.useinvent.com/api-reference/orgs-pages/get-block-data https://api.useinvent.com/openapi.json get /orgs/{org_id}/pages/{page_ref}/blocks/{block_id}/data Compute a stat or chart block from its stored config, validated against the live table fields. Windows resolve to real dates at query time. # List pages Source: https://docs.useinvent.com/api-reference/orgs-pages/list-pages https://api.useinvent.com/openapi.json get /orgs/{org_id}/pages List the pages defined for an org. # Move a block Source: https://docs.useinvent.com/api-reference/orgs-pages/move-a-block https://api.useinvent.com/openapi.json post /orgs/{org_id}/pages/{page_ref}/blocks/{block_id}/move Reposition a block between two neighbors on its page. # Remove a block Source: https://docs.useinvent.com/api-reference/orgs-pages/remove-a-block https://api.useinvent.com/openapi.json delete /orgs/{org_id}/pages/{page_ref}/blocks/{block_id} Permanently remove a block from its page. # Reorder pages Source: https://docs.useinvent.com/api-reference/orgs-pages/reorder-pages https://api.useinvent.com/openapi.json patch /orgs/{org_id}/pages/positions Bulk-update the sidebar position of multiple pages in one transaction. # Update a block Source: https://docs.useinvent.com/api-reference/orgs-pages/update-a-block https://api.useinvent.com/openapi.json patch /orgs/{org_id}/pages/{page_ref}/blocks/{block_id} Update a block config or repoint its source table or view. # Update a page Source: https://docs.useinvent.com/api-reference/orgs-pages/update-a-page https://api.useinvent.com/openapi.json patch /orgs/{org_id}/pages/{page_ref} Update a page. # Create a record comment Source: https://docs.useinvent.com/api-reference/orgs-records/create-a-record-comment https://api.useinvent.com/openapi.json post /orgs/{org_id}/records/{record_id}/comments Add a new comment to a table record. # Delete a record Source: https://docs.useinvent.com/api-reference/orgs-records/delete-a-record https://api.useinvent.com/openapi.json delete /orgs/{org_id}/records/{record_id} Permanently delete a record. Blocked if referenced by restrict-mode fields; cascades referenced rows on cascade-mode fields. # Delete a record comment Source: https://docs.useinvent.com/api-reference/orgs-records/delete-a-record-comment https://api.useinvent.com/openapi.json delete /orgs/{org_id}/records/{record_id}/comments/{activity_id} Remove a comment from a record. # Get a record Source: https://docs.useinvent.com/api-reference/orgs-records/get-a-record https://api.useinvent.com/openapi.json get /orgs/{org_id}/records/{record_id} Get a single record by id. The table is resolved from the record and asserted to belong to this org. # Get a record comment Source: https://docs.useinvent.com/api-reference/orgs-records/get-a-record-comment https://api.useinvent.com/openapi.json get /orgs/{org_id}/records/{record_id}/comments/{activity_id} Retrieve a specific comment by id. # List org records Source: https://docs.useinvent.com/api-reference/orgs-records/list-org-records https://api.useinvent.com/openapi.json get /orgs/{org_id}/records List records across every custom table in the org. Primarily used to browse archived records org-wide. Pass `status=ARCHIVED` for the archive view. # List record activities Source: https://docs.useinvent.com/api-reference/orgs-records/list-record-activities https://api.useinvent.com/openapi.json get /orgs/{org_id}/records/{record_id}/activities Retrieve the activity timeline for a record, sorted by creation date (newest first). Contacts- and conversations-table records resolve to the underlying contact. # List record comments Source: https://docs.useinvent.com/api-reference/orgs-records/list-record-comments https://api.useinvent.com/openapi.json get /orgs/{org_id}/records/{record_id}/comments Retrieve all comments for a record, sorted by creation date (newest first). Contacts- and conversations-table records resolve to the underlying contact. # Set a single record field value Source: https://docs.useinvent.com/api-reference/orgs-records/set-a-single-record-field-value https://api.useinvent.com/openapi.json patch /orgs/{org_id}/records/{record_id}/fields/{field_id_or_key} Upsert one field value on a record. The path accepts an encoded field id or the field key. # Update a record Source: https://docs.useinvent.com/api-reference/orgs-records/update-a-record https://api.useinvent.com/openapi.json patch /orgs/{org_id}/records/{record_id} Update record values and/or archived flag. # Update a record comment Source: https://docs.useinvent.com/api-reference/orgs-records/update-a-record-comment https://api.useinvent.com/openapi.json patch /orgs/{org_id}/records/{record_id}/comments/{activity_id} Update the content or attachments of an existing comment. # Create a Segment Source: https://docs.useinvent.com/api-reference/orgs-segments/create-a-segment https://api.useinvent.com/openapi.json post /orgs/{org_id}/segments Create a new segment for the organization. # Delete a Segment Source: https://docs.useinvent.com/api-reference/orgs-segments/delete-a-segment https://api.useinvent.com/openapi.json delete /orgs/{org_id}/segments/{segment_id} Delete a segment and all associated contact segment relationships. Contacts will not be deleted. # Get a Segment Source: https://docs.useinvent.com/api-reference/orgs-segments/get-a-segment https://api.useinvent.com/openapi.json get /orgs/{org_id}/segments/{segment_id} Get a specific segment by its ID. # Get Segments Source: https://docs.useinvent.com/api-reference/orgs-segments/get-segments https://api.useinvent.com/openapi.json get /orgs/{org_id}/segments Get a list of segments for a specific org. # Update a Segment Source: https://docs.useinvent.com/api-reference/orgs-segments/update-a-segment https://api.useinvent.com/openapi.json patch /orgs/{org_id}/segments/{segment_id} Update a specific segment by its ID. # Create Skill Source: https://docs.useinvent.com/api-reference/orgs-skills/create-skill https://api.useinvent.com/openapi.json post /orgs/{org_id}/skills Create a new skill for a specific org. # Delete Skill Source: https://docs.useinvent.com/api-reference/orgs-skills/delete-skill https://api.useinvent.com/openapi.json delete /orgs/{org_id}/skills/{skill_id} Delete an existing skill. # Get Skill Source: https://docs.useinvent.com/api-reference/orgs-skills/get-skill https://api.useinvent.com/openapi.json get /orgs/{org_id}/skills/{skill_id} Fetch a specific skill by ID. # Get Skills Source: https://docs.useinvent.com/api-reference/orgs-skills/get-skills https://api.useinvent.com/openapi.json get /orgs/{org_id}/skills Fetch all skills for a specific org. # Update Skill Source: https://docs.useinvent.com/api-reference/orgs-skills/update-skill https://api.useinvent.com/openapi.json patch /orgs/{org_id}/skills/{skill_id} Update an existing skill. # Dry Run Suppress Identifiers in Bulk Source: https://docs.useinvent.com/api-reference/orgs-suppressions/dry-run-suppress-identifiers-in-bulk https://api.useinvent.com/openapi.json post /orgs/{org_id}/suppressions/bulk/dry Preview what a bulk suppression import would create, skip and reject. # Get Suppressions Source: https://docs.useinvent.com/api-reference/orgs-suppressions/get-suppressions https://api.useinvent.com/openapi.json get /orgs/{org_id}/suppressions Get the org suppression list — the emails and phone numbers excluded from automated messaging. # Remove a Suppression Source: https://docs.useinvent.com/api-reference/orgs-suppressions/remove-a-suppression https://api.useinvent.com/openapi.json delete /orgs/{org_id}/suppressions/{suppression_id} Remove an email or phone number from the org suppression list. # Suppress an Identifier Source: https://docs.useinvent.com/api-reference/orgs-suppressions/suppress-an-identifier https://api.useinvent.com/openapi.json post /orgs/{org_id}/suppressions Add an email or phone number to the org suppression list. Suppressing an identifier that is already on the list refreshes its reason. # Suppress Identifiers in Bulk Source: https://docs.useinvent.com/api-reference/orgs-suppressions/suppress-identifiers-in-bulk https://api.useinvent.com/openapi.json post /orgs/{org_id}/suppressions/bulk Add many emails or phone numbers to the org suppression list at once. Contacts are never created or modified. # Update a Suppression Source: https://docs.useinvent.com/api-reference/orgs-suppressions/update-a-suppression https://api.useinvent.com/openapi.json patch /orgs/{org_id}/suppressions/{suppression_id} Update the reason or note of a suppression entry. # Bulk record operations Source: https://docs.useinvent.com/api-reference/orgs-tables/bulk-record-operations https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/records/bulk Apply a batch of create / patch / delete operations in a single request. # Bulk update record values Source: https://docs.useinvent.com/api-reference/orgs-tables/bulk-update-record-values https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/records/values/bulk Update individual field values across many existing records in one request. Update-only: unknown records are reported in `failed`, never created. # Create a record Source: https://docs.useinvent.com/api-reference/orgs-tables/create-a-record https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/records Create a new record in a table. # Create a table Source: https://docs.useinvent.com/api-reference/orgs-tables/create-a-table https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables Create a new table. # Create a table field Source: https://docs.useinvent.com/api-reference/orgs-tables/create-a-table-field https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/fields Create a new field on a table. Pass `before` / `after` (a sibling field key) to slot it at a global position; omit both to append. # Delete a table Source: https://docs.useinvent.com/api-reference/orgs-tables/delete-a-table https://api.useinvent.com/openapi.json delete /orgs/{org_id}/tables/{table_id} Permanently delete a table. Irreversible: cascades all records, fields, and refs. Rejected while Record fields on other tables link to this one, unless `force` is set — those fields are then deleted with it. # Delete a table field Source: https://docs.useinvent.com/api-reference/orgs-tables/delete-a-table-field https://api.useinvent.com/openapi.json delete /orgs/{org_id}/tables/{table_id}/fields/{field_id} Permanently delete a field. Cascades all values. Deleting the display field promotes the first available field, or clears it. # Duplicate a record Source: https://docs.useinvent.com/api-reference/orgs-tables/duplicate-a-record https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/records/{record_id}/duplicate Duplicate a record in a table. Unique-field values are not copied (left empty on the duplicate). Not available for system tables. # Duplicate a table Source: https://docs.useinvent.com/api-reference/orgs-tables/duplicate-a-table https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/duplicate Duplicate a table structure: its fields and views. Records are not copied. Not available for system tables. # Export records Source: https://docs.useinvent.com/api-reference/orgs-tables/export-records https://api.useinvent.com/openapi.json get /orgs/{org_id}/tables/{table_id}/records/export Export a table's records as a CSV file. Reflects the same `status` and `search` filters as the list endpoint. Synchronous and capped — over the limit the request is rejected with `EXPORT/OVER_SYNC_LIMIT`. # Get a table Source: https://docs.useinvent.com/api-reference/orgs-tables/get-a-table https://api.useinvent.com/openapi.json get /orgs/{org_id}/tables/{table_id} Get a single table by id. # Get a table field Source: https://docs.useinvent.com/api-reference/orgs-tables/get-a-table-field https://api.useinvent.com/openapi.json get /orgs/{org_id}/tables/{table_id}/fields/{field_id} Get a single field by id. # Import records Source: https://docs.useinvent.com/api-reference/orgs-tables/import-records https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/records/import Import records from a CSV or XLSX file. Headers map to field keys (override per column with `mapping`). Synchronous and capped — over the limit the request is rejected with `IMPORT/OVER_SYNC_LIMIT`. Partial success: valid rows commit, failed rows are returned per row. # List records Source: https://docs.useinvent.com/api-reference/orgs-tables/list-records https://api.useinvent.com/openapi.json get /orgs/{org_id}/tables/{table_id}/records List the records in a table. # List table fields Source: https://docs.useinvent.com/api-reference/orgs-tables/list-table-fields https://api.useinvent.com/openapi.json get /orgs/{org_id}/tables/{table_id}/fields List the fields defined on a table, ordered by position. # List table views Source: https://docs.useinvent.com/api-reference/orgs-tables/list-table-views https://api.useinvent.com/openapi.json get /orgs/{org_id}/tables/{table_id}/views List the views defined on a table, ordered by tab-strip `position`. # List tables Source: https://docs.useinvent.com/api-reference/orgs-tables/list-tables https://api.useinvent.com/openapi.json get /orgs/{org_id}/tables List the tables defined for an org. # Reorder a table field Source: https://docs.useinvent.com/api-reference/orgs-tables/reorder-a-table-field https://api.useinvent.com/openapi.json post /orgs/{org_id}/tables/{table_id}/fields/move Move a field to a new global position. Pass `field_id` for the field being moved and `after` / `before` for the neighbor field key. Resequences the table and returns the updated field. # Reorder tables Source: https://docs.useinvent.com/api-reference/orgs-tables/reorder-tables https://api.useinvent.com/openapi.json patch /orgs/{org_id}/tables/positions Bulk-update the display position of an org's tables in one transaction. # Reorder this table's tab strip Source: https://docs.useinvent.com/api-reference/orgs-tables/reorder-this-tables-tab-strip https://api.useinvent.com/openapi.json patch /orgs/{org_id}/tables/{table_id}/views/positions Bulk-update the position of multiple views on one table in one transaction. # Update a table Source: https://docs.useinvent.com/api-reference/orgs-tables/update-a-table https://api.useinvent.com/openapi.json patch /orgs/{org_id}/tables/{table_id} Update a table. # Update a table field Source: https://docs.useinvent.com/api-reference/orgs-tables/update-a-table-field https://api.useinvent.com/openapi.json patch /orgs/{org_id}/tables/{table_id}/fields/{field_id} Update a field. `type` and `key` can both be changed. Changing the type preserves existing values in place (they go dormant in their original column and return if the type is reverted); same-storage types reuse the value directly. System fields stay immutable. # Create Org Variable Source: https://docs.useinvent.com/api-reference/orgs-variables/create-org-variable https://api.useinvent.com/openapi.json post /orgs/{org_id}/variables Create a variable for a specific org. # Delete Org Variable Source: https://docs.useinvent.com/api-reference/orgs-variables/delete-org-variable https://api.useinvent.com/openapi.json delete /orgs/{org_id}/variables/{key} Delete a variable for a specific org. # Get Org Variables Source: https://docs.useinvent.com/api-reference/orgs-variables/get-org-variables https://api.useinvent.com/openapi.json get /orgs/{org_id}/variables Fetch all variables for a specific org. # Rename Org Variable Source: https://docs.useinvent.com/api-reference/orgs-variables/rename-org-variable https://api.useinvent.com/openapi.json patch /orgs/{org_id}/variables/{key} Rename a variable for a specific org. # Update Org Variables Source: https://docs.useinvent.com/api-reference/orgs-variables/update-org-variables https://api.useinvent.com/openapi.json patch /orgs/{org_id}/variables Update variables for a specific org. # Aggregate view records Source: https://docs.useinvent.com/api-reference/orgs-views/aggregate-view-records https://api.useinvent.com/openapi.json post /orgs/{org_id}/views/{view_id}/aggregate Compute count/sum/avg/min/max over the records of a view, optionally grouped, windowed and filtered. Honors the view filter on top of the spec filter. # Create a view Source: https://docs.useinvent.com/api-reference/orgs-views/create-a-view https://api.useinvent.com/openapi.json post /orgs/{org_id}/views Create a view on a table. `table_id` may be a regular table id or a system-table keyword (`contacts`, `chats`, `users`) — system tables are lazy-created on first interaction. # Delete a view Source: https://docs.useinvent.com/api-reference/orgs-views/delete-a-view https://api.useinvent.com/openapi.json delete /orgs/{org_id}/views/{view_id} Permanently delete a view. Blocked if this is the only view on the table. # Duplicate a view Source: https://docs.useinvent.com/api-reference/orgs-views/duplicate-a-view https://api.useinvent.com/openapi.json post /orgs/{org_id}/views/{view_id}/duplicate Duplicate a view within the same table. The copy is appended to the tab strip and is never the default view. # Get a view Source: https://docs.useinvent.com/api-reference/orgs-views/get-a-view https://api.useinvent.com/openapi.json get /orgs/{org_id}/views/{view_id} Get a single view by id. # List fields available on a view Source: https://docs.useinvent.com/api-reference/orgs-views/list-fields-available-on-a-view https://api.useinvent.com/openapi.json get /orgs/{org_id}/views/{view_id}/fields Every field the view's entity exposes (built-ins + dynamic TableField rows) with its `type`, `readonly`, `sortable`, and `groupable_in` capability flags. Drives the FE's axis / sort / filter / column pickers and the inline cell editor dispatch from one payload. # List groups (columns) for a view Source: https://docs.useinvent.com/api-reference/orgs-views/list-groups-columns-for-a-view https://api.useinvent.com/openapi.json get /orgs/{org_id}/views/{view_id}/groups Returns the board column descriptors (enum items, boolean buckets, date / number ranges, distinct strings) plus capability flags — `reorderable_columns` enables column-header DnD, `movable_items` enables card DnD between columns (only meaningful for enum / user / boolean axes), `axis` carries the resolved field for the FE header. No pagination — bounded by `MAX_BOARD_COLUMNS`. Throws 400 for kinds that have no groups (table / calendar / timeline). # List org views Source: https://docs.useinvent.com/api-reference/orgs-views/list-org-views https://api.useinvent.com/openapi.json get /orgs/{org_id}/views Non-archived views in the org, ordered by `position`. Pass `table_type=contacts` for the Audience tab strip, `table_type=chats` for Inbox, `table_type=custom` for user-created tables. Omit to fetch all. Per-table tab order lives under `/tables/:table_id/views`. # List records for a view Source: https://docs.useinvent.com/api-reference/orgs-views/list-records-for-a-view https://api.useinvent.com/openapi.json get /orgs/{org_id}/views/{view_id}/items Paginated records for the view, applying its sort + per-view manual positions. # Move an item in a view Source: https://docs.useinvent.com/api-reference/orgs-views/move-an-item-in-a-view https://api.useinvent.com/openapi.json post /orgs/{org_id}/views/{view_id}/move Drag-reorder an item in any view kind. Updates the item's per-view manual position between `after` and `before`. For board views, optionally set `group_value` to drag the card between columns — the runner writes the new axis value back to the row (rejected for readonly fields and for axes that can't take drop-writes, e.g. date / number ranges). # Reorder a group (board column) Source: https://docs.useinvent.com/api-reference/orgs-views/reorder-a-group-board-column https://api.useinvent.com/openapi.json post /orgs/{org_id}/views/{view_id}/groups/move Move a board column to a new position. Pass `group_key` for the column being moved and `after` / `before` for the neighbor group keys. The new full column order is persisted on `view.config.board.columns`. Returns the updated view. # Update a view Source: https://docs.useinvent.com/api-reference/orgs-views/update-a-view https://api.useinvent.com/openapi.json patch /orgs/{org_id}/views/{view_id} Update a view. `sort` is re-validated against the table's field catalog when present. # Create Webhook Source: https://docs.useinvent.com/api-reference/orgs-webhooks/create-webhook https://api.useinvent.com/openapi.json post /orgs/{org_id}/webhooks Create a webhook endpoint. The signing secret is returned in full here and never again — store it. # Delete Webhook Source: https://docs.useinvent.com/api-reference/orgs-webhooks/delete-webhook https://api.useinvent.com/openapi.json delete /orgs/{org_id}/webhooks/{webhook_id} Delete a webhook endpoint and its delivery history. # Get Webhook Source: https://docs.useinvent.com/api-reference/orgs-webhooks/get-webhook https://api.useinvent.com/openapi.json get /orgs/{org_id}/webhooks/{webhook_id} Retrieve a single webhook endpoint. # List Webhook Deliveries Source: https://docs.useinvent.com/api-reference/orgs-webhooks/list-webhook-deliveries https://api.useinvent.com/openapi.json get /orgs/{org_id}/webhooks/{webhook_id}/deliveries List recent delivery attempts for an endpoint. # List Webhook Events Source: https://docs.useinvent.com/api-reference/orgs-webhooks/list-webhook-events https://api.useinvent.com/openapi.json get /orgs/{org_id}/webhooks/events List every event type an endpoint can subscribe to. # List Webhooks Source: https://docs.useinvent.com/api-reference/orgs-webhooks/list-webhooks https://api.useinvent.com/openapi.json get /orgs/{org_id}/webhooks List the webhook endpoints of an organization. # Replay Webhook Delivery Source: https://docs.useinvent.com/api-reference/orgs-webhooks/replay-webhook-delivery https://api.useinvent.com/openapi.json post /orgs/{org_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/replay Re-send a past event to the endpoint as a new delivery. Works for succeeded and failed deliveries alike. # Rotate Webhook Secret Source: https://docs.useinvent.com/api-reference/orgs-webhooks/rotate-webhook-secret https://api.useinvent.com/openapi.json post /orgs/{org_id}/webhooks/{webhook_id}/rotate Issue a new signing secret. The previous secret stops signing immediately. # Test Webhook Source: https://docs.useinvent.com/api-reference/orgs-webhooks/test-webhook https://api.useinvent.com/openapi.json post /orgs/{org_id}/webhooks/{webhook_id}/test Send a signed `ping` event to the endpoint and return the delivery result. # Update Webhook Source: https://docs.useinvent.com/api-reference/orgs-webhooks/update-webhook https://api.useinvent.com/openapi.json patch /orgs/{org_id}/webhooks/{webhook_id} Update a webhook endpoint. # Cancel a Workflow Run Source: https://docs.useinvent.com/api-reference/orgs-workflows/cancel-a-workflow-run https://api.useinvent.com/openapi.json post /orgs/{org_id}/workflows/{workflow_id}/runs/{run_id}/cancel Cancel a workflow run that is currently running. # Get a Workflow Run Source: https://docs.useinvent.com/api-reference/orgs-workflows/get-a-workflow-run https://api.useinvent.com/openapi.json get /orgs/{org_id}/workflows/{workflow_id}/runs/{run_id} Retrieve details of a specific workflow run. # Get Runs Source: https://docs.useinvent.com/api-reference/orgs-workflows/get-runs https://api.useinvent.com/openapi.json get /orgs/{org_id}/workflows/runs Retrieve a list of runs. # Get Workflow Runs Source: https://docs.useinvent.com/api-reference/orgs-workflows/get-workflow-runs https://api.useinvent.com/openapi.json get /orgs/{org_id}/workflows/{workflow_id}/runs Retrieve a list of runs for a specific workflow. # Replay a Workflow Run Source: https://docs.useinvent.com/api-reference/orgs-workflows/replay-a-workflow-run https://api.useinvent.com/openapi.json post /orgs/{org_id}/workflows/{workflow_id}/runs/{run_id}/replay Replay a specific workflow run. # Run a Workflow Source: https://docs.useinvent.com/api-reference/orgs-workflows/run-a-workflow https://api.useinvent.com/openapi.json post /orgs/{org_id}/workflows/{workflow_id}/runs Run a specific workflow by its ID. # Actions Source: https://docs.useinvent.com/assistants/actions Give your assistant the power to perform real tasks, not just answer questions Actions transform your assistant from a simple chatbot into a powerful agent that can actually do things. Book appointments, send emails, create records, process payments, all automatically during conversations. Actions Overview ## What Are Actions? Actions are integrations that let your assistant interact with external services. Instead of just saying "I can help you book an appointment," your assistant actually books it. **Without actions:** "Please visit our website to book an appointment." **With actions:** "I've booked you for Tuesday at 2 PM. You'll receive a calendar invite shortly." ## Adding Actions 1. Go to your assistant's **Actions** tab 2. Click **Add Action** 3. Choose an integration (like Google Calendar) 4. Select the specific action (like Create Event) 5. Configure the action settings 6. Click **Add Action** Add Action Add Action Add Action ## Available Integrations Invent integrates with popular services across multiple categories: * **Scheduling**: Book and manage appointments with calendar services like Google Calendar, Cal.com, and Calendly * **Communication**: Send messages via email, Slack, SMS, and other communication platforms * **CRM & Sales**: Connect to your CRM to manage contacts, leads, deals, and customer relationships * **Productivity**: Work with spreadsheets, project management tools, note-taking apps, and task managers * **Payments**: Process payments and create checkout links through payment processors * **E-commerce**: Access order information, product catalogs, and customer data from your store * **Utilities**: Search the web, scrape data from websites, call any API endpoint, or trigger custom workflows ## AI Controlled Fields This is where the magic happens. When configuring an action, most fields are set to **AI Controlled** by default. AI Controlled Fields ### What Does AI Controlled Mean? Instead of you hardcoding values, your assistant figures them out from the conversation. **Example: Creating a Calendar Event** | Field | AI Controlled Behavior | | -------------- | ------------------------------------------------------- | | Event Title | AI extracts from conversation ("Yoga class with Maria") | | Start Date | AI understands "next Tuesday at 2 PM" | | Description | AI summarizes what was discussed | | Attendee Email | AI asks if not provided | You don't write code. You don't create complex rules. The AI understands context and fills in the right values. ### Auto-Discovery AI Controlled Fields go beyond reading the conversation. When a field needs a provider-specific value the assistant cannot infer from chat alone, like a Calendar ID, a Trello list, or a spreadsheet sheet name, the assistant **automatically runs the provider's discovery actions** to resolve it. You no longer need to wire up those lookups yourself. You only add the actions the assistant should *perform*. Discovery runs behind the scenes using the same [Connection](/workspace-management/connections) as your explicit actions, so permissions and access scopes stay consistent. For a setup like the one above with just `Create Event` and `Create Card`, the assistant automatically invokes supporting lookups whenever it needs a value to fill an AI Controlled field: * `List Calendars` to know which Google Calendar to create the event in * `List Boards` and `List Lists` to pick the right Trello destination * `List Members` to assign the card to the right person * ...and similar discovery actions for every other integration Auto-discovery invoking List Calendars at runtime In the example above, the assistant has **only** `Create Event` and `Create Card` configured. When a customer asks "Which calendars do I have?", the assistant automatically invokes `List Calendars` to answer, even though that action is not in the configured list. The same happens for Trello when the assistant needs a board or list ID to create a card. Auto-discovery only runs for fields left as **AI Controlled**. Override a field to a fixed Manual value (see below) whenever you want to lock it down to a specific resource. ### When to Override AI Control Sometimes you want specific values regardless of conversation: * **Calendar ID**: Always use your business calendar * **Default duration**: All appointments are 1 hour * **Notification settings**: Always send email reminders Click the three-dot menu next to any field to switch from AI Controlled to a fixed value. ## Action Configuration Each action has: ### Action Name (Optional) A custom name to help your assistant identify this action. Useful when you have multiple similar actions. ### When To Use (Optional) Guidance for your assistant on when to trigger this action. For example: > "Use this action when a customer wants to book an appointment and has provided their preferred date and time." ### Connection Which account to use. For Google Calendar, this is which Google account's calendar to access. You can connect multiple accounts and choose the right one for each action. Manage all your connected accounts from the [Connections](/workspace-management/connections) page. ### Action-Specific Fields Each action has different fields. For Google Calendar's Create Event: * **Calendar**: Which calendar to add the event to * **Event Title**: Name of the event * **Description**: Event details * **Start Date**: When it starts * **End Date**: When it ends * **Attendees**: Who to invite * **Visibility**: Public or private * **Reminders**: Notification settings ## Enabling and Disabling Actions Each action has a toggle to enable or disable it. Disabled actions won't be used by your assistant, but the configuration is preserved. This is useful for: * Testing new actions before going live * Temporarily disabling actions during maintenance * A/B testing different action configurations ## Multiple Actions Your assistant can have many actions. During a conversation, it automatically chooses the right one based on context. **Customer:** "I need to book an appointment for next week" → Assistant uses **Create Event** action **Customer:** "Can you check if I have anything scheduled tomorrow?" → Assistant uses **Search Events** action **Customer:** "Actually, can we move it to Thursday?" → Assistant uses **Update Event** action ## Testing Actions Always test your actions in the [Playground](/assistants/introduction#the-playground) before going live. The Playground lets you simulate real conversations and verify that actions trigger correctly with the right values. Here is an example of a "Book Consultation" action configured with a mix of AI Controlled and Manual fields: Book Consultation action configuration And here is what it looks like when the action triggers during a Playground conversation: Testing the action in the Playground ### How to Test 1. Open your assistant and click **Create Conversation** in the Playground 2. Have a conversation that should trigger your action (e.g., ask to book an appointment) 3. Watch for the action execution in the conversation. You will see when the assistant calls an action and what values it used 4. Verify the result in the external service (e.g., check that the calendar event was actually created) ### What to Check * **Does the action trigger at the right time?** If it triggers too early (before the customer confirmed) or not at all, adjust your "When To Use" instructions * **Are the AI Controlled fields correct?** Check that the assistant extracted the right values from the conversation. If a field is consistently wrong, consider switching it to a fixed Manual value * **Does the assistant confirm before acting?** Add confirmation rules to your [Instructions](/guides/practical/writing-instructions) so the assistant verifies details with the customer before triggering irreversible actions * **What happens when information is missing?** The assistant should ask for required details instead of guessing. If it guesses, add a rule to your Instructions like "Always ask for the customer's email before booking" Test edge cases too: what if the customer changes their mind, provides incomplete information, or asks for something the action cannot handle? These scenarios reveal where you need to refine your [Instructions](/guides/practical/writing-instructions) or "When To Use" guidance. For a complete walkthrough of multiple actions working together in a real scenario, see [Build a Booking Assistant](/learn-by-example). ## Best Practices 1. **Start simple**: Add one action, test it thoroughly, then add more 2. **Use descriptive names**: "Book Yoga Class" is better than "Create Event" 3. **Write clear "When To Use" instructions**: Help your assistant know when to trigger each action 4. **Test in the Playground**: Verify actions work before customers use them 5. **Monitor action usage**: Check that actions are triggering correctly ## Troubleshooting ### Action Not Triggering * Check that the action is enabled (toggle is on) * Verify the "When To Use" instructions are clear * Test in the Playground with explicit requests ### Wrong Values Being Used * Review which fields are AI Controlled vs fixed * Add more specific "When To Use" instructions * Consider overriding AI Control for problematic fields ### Connection Errors * Reconnect the integration * Verify the connected account has necessary permissions * Check if the external service is experiencing issues # Capabilities Source: https://docs.useinvent.com/assistants/capabilities What your assistant can understand and how it responds in conversations Your assistant can go beyond plain text messages. It understands multiple input types from your customers and can respond with interactive elements that make conversations more engaging and actionable. ## Multimodal Understanding Your assistant can understand more than just text. Customers can send voice messages, images, files, contacts, and locations across supported channels, and the assistant processes them naturally as part of the conversation. For example, a customer can send a voice note on WhatsApp and the assistant will transcribe, understand, and reply. ## Location Sharing Your assistant can send and receive locations natively. Customers can share their location, and the assistant understands the address and coordinates. The assistant can also send locations back as native map items. | | Send Location | Request Location | | -------------- | ------------- | ---------------- | | **WhatsApp** | Supported | Supported | | **Telegram** | Supported | Supported | | **Web Widget** | Supported | Supported | The assistant can also request a customer's location with a **Share Location** button. On WhatsApp and Telegram this opens the native location picker. On the Web Widget it uses the browser's geolocation API. Location sharing on WhatsApp ## Contact Sharing On WhatsApp, customers can share contact cards (name, phone number) directly in the conversation. Your assistant reads the contact details and can act on them. ## Typing Indicators Your assistant shows a typing indicator while composing a response, giving customers a natural chat experience. Supported on WhatsApp, Instagram, Messenger, TikTok and Telegram. Typing indicator on WhatsApp ## Read Receipts Your assistant sends read receipts when it processes a customer's message, so customers know their message was seen. Supported on WhatsApp. ## Options Options let your assistant present a set of choices as interactive buttons. Instead of listing items in a text message and asking the customer to type their choice, the assistant displays a clean menu that customers can tap to select. Assistant presenting Yes/No options and a menu on WhatsApp When a customer taps an option, it gets selected and sent as their response automatically. ### When to Use Options Options work best when the assistant needs the customer to pick from a defined set of choices: * **Service menus**: "What can I help you with? Services, Contact Us, FAQ" * **Product categories**: "Which category are you interested in?" * **Appointment types**: "What type of session would you like to book?" * **Survey responses**: "How would you rate your experience?" ### Configuring Options via Instructions Your assistant decides when to use options based on conversation context. To guide this behavior, add rules to your assistant's [Instructions](/assistants/introduction#instructions). **Example instruction:** ``` When presenting a menu or list of choices, always use options so the customer can tap to select instead of typing. ``` ## Link Buttons Link buttons let your assistant display URLs as tappable buttons. Instead of pasting a raw URL into the chat, the assistant presents a clean, labeled button that customers can tap to open the link. ### How Link Buttons Work on Each Channel Link buttons are supported across all major channels. On messaging apps, tapping a link button opens the URL natively within the app. Pricing Page link button on WhatsApp Pricing link button on Telegram On messaging apps (WhatsApp, Messenger, Instagram, Telegram), tapping a link button opens the page in the app's built-in browser. On the web widget, links appear in a card with an external link icon and open in a new browser tab. ### Use Cases Link buttons are ideal for any URL you want customers to access quickly without copying and pasting: * **Payment links**: Direct customers to a checkout or payment page * **Pricing pages**: Share your pricing or plan comparison page * **Booking pages**: Link to a scheduling tool or calendar * **Documentation**: Point customers to help articles or guides * **Any external page**: Product pages, forms, downloads, or portals ### Configuring Link Buttons via Instructions Like options, your assistant uses link buttons when it makes sense in the conversation. You can control this by adding specific rules to your assistant's [Instructions](/assistants/introduction#instructions). **Force all links as buttons:** ``` Always present links as buttons so the customer can tap to open them directly. ``` **Force specific links as buttons:** ``` When sharing the pricing page, always present it as a button labeled "Pricing Plans". When sharing a payment link, always present it as a button labeled "Make a Payment". ``` If your assistant frequently shares certain URLs (pricing, booking, support pages), add instructions that tell it to always present those as buttons. This gives customers a cleaner, more professional experience. # Channels Source: https://docs.useinvent.com/assistants/channels Connect your assistant to WhatsApp, Instagram, Messenger, TikTok, Telegram, Slack, Gmail, SMS and your website Channels are how your customers reach your assistant. Connect the platforms your customers already use, and every message lands in the same [Inbox](/guides/inbox) with the same assistant answering, no matter which channel it came from. Channels Overview ## Every Channel | Channel | What it connects | Setup guide | | :------------------------ | :------------------------------------------------------------------------------------------- | :-------------------------------------- | | WhatsApp Business | A WhatsApp Business phone number | [Guide](/assistants/channels/whatsapp) | | Facebook Messenger | A Facebook Page | [Guide](/assistants/channels/messenger) | | Instagram Direct Messages | A professional Instagram account | [Guide](/assistants/channels/instagram) | | TikTok Direct Messages | A TikTok Business Account | [Guide](/assistants/channels/tiktok) | | Telegram Bot | A bot you create with @BotFather | [Guide](/assistants/channels/telegram) | | Web Widget | Your own website | [Guide](/assistants/widget) | | Slack Bot | A Slack workspace, where people mention the bot in a channel | Universal flow below | | Gmail | A Gmail inbox | Universal flow below | | Email | Outbound only: sends from your verified identities and domains, and carries email broadcasts | Universal flow below | | Twilio | SMS and MMS on a Twilio number | Universal flow below | | Telnyx | SMS and MMS on a Telnyx number | Universal flow below | | SMPP | SMS over a direct carrier bind | Universal flow below | ## How Channels Work Every channel in Invent follows the same shape: * A **channel type**, one of the rows above. * A reusable **[Connection](/workspace-management/connections)** that holds the authenticated link to that provider (your Meta account, your Telegram bot token, etc.). * A per-assistant **binding** that picks a specific resource on that connection (a WhatsApp phone number, a Facebook Page, an Instagram account) and turns it on. Because connections are separate from the assistants that use them, you authenticate with a provider **once**. From then on, any assistant in your workspace can reuse that connection without signing in again. ## The Universal Connection Flow Adding any channel to an assistant follows the same five steps. The only thing that changes is the provider's sign-in screen in the middle. Open your assistant's **Channels** tab, find the channel you want to add, and click **Connect**. A dialog opens with two fields: a **Connection** (the authenticated link to the provider) and the channel-specific resource picker (phone number, page, bot, etc.). The example below shows the WhatsApp dialog the first time it is opened, but every channel works the same way. WhatsApp channel connect dialog on first open, with a + Connect WhatsApp button inside the Connection field If you already have a connection for this channel, it shows up in the **Connection** dropdown and you can skip straight to the resource picker. If not, open the dropdown and click the **+ Connect *Channel*** button at the top (for example **+ Connect WhatsApp**) to start the provider's sign-in flow. Invent opens the channel's **standard sign-in flow** in a popup or new tab. This is the provider's own screen, run by Meta, Telegram, or whoever owns the channel, so your credentials are only entered on their domain, never on Invent's. Finish the provider's flow as you normally would: pick the business, select the number, page, or account to grant access to, and confirm the permissions. When you are done, the provider redirects you back to Invent automatically. Back in Invent, you are asked to give this connection a label (for example, "Acme WhatsApp" or "Support Team Messenger"). This is just the name you will see inside Invent, it does not change anything on the provider. Click **Create** and Invent stores the connection in [Settings → Connections](/workspace-management/connections), where you can rename or disconnect it at any time. The channel dialog reopens with your new connection already selected and any channel-specific fields listed underneath. Invent fetches the available options for you, so you just pick from a dropdown: * **WhatsApp Business** → pick the phone number to receive and send messages on * **Facebook Messenger** → pick the Page * **Instagram** → pick the connected Instagram account * **Telegram** → pick the bot No copy-pasting IDs, no hunting through provider settings. WhatsApp dialog with the connection auto-selected and a phone number picked, ready to click Connect Channel Invent binds the resource to this assistant. The channel appears in the Channels tab with an **Enabled** toggle and a **Manage** button. Send it a test message, and you are live. The next time you add this same channel to *any* assistant in your workspace, you will see your existing connection in the dropdown. Just pick it, choose the resource, and click **Connect Channel**. No re-authentication required. ## Managing Connected Channels Each channel you have added to an assistant shows up as its own row with: * **Identifier**: the phone number, Page name, account handle, or bot username for this binding. * **Status**: **Connected** when the connection is healthy (**Disconnected** when disabled), or a warning if the provider requires re-authentication. * **Enable / Disable toggle**: pause the channel without removing its configuration. Useful during maintenance or while you refine Instructions. * **Manage**: open channel-specific settings. * **Disconnect**: remove this binding from the assistant. The underlying [Connection](/workspace-management/connections) itself is untouched, so other assistants that share it keep working. ## Multiple Connections Per Channel A single assistant can have **more than one connection of the same channel type**. Add two WhatsApp Business numbers, three Facebook Pages, a mix of Instagram accounts, or any combination, all under the same assistant running in parallel. Assistant with multiple WhatsApp numbers and Facebook Pages connected Once a channel is connected once, click **+ Add another** below the existing connections and run through the same flow with a different number, page, or account. ### When to Use Multiple Connections * **Regional numbers**: one WhatsApp number per country or language, all sharing the same Instructions, Knowledge, and Memory. * **Brand portfolio**: several Facebook Pages from different product lines routed to a single assistant. * **Migrations and handoffs**: keep a legacy number active alongside a new one during a rollout, then disable the old connection when you are ready. * **Team and department splits**: route sales and support numbers to the same assistant without duplicating its configuration. All connections under the same assistant share its Instructions, [Knowledge](/guides/knowledge), [Memory](/guides/memory), and [Actions](/assistants/actions). Every conversation lands in the same [Inbox](/guides/inbox), with the originating channel shown on each conversation. ## One Assistant, Every Channel A single assistant handles every connected channel at once. A customer might: 1. Ask a question on Instagram 2. Continue the conversation on WhatsApp a few days later 3. Complete a purchase on your website Your assistant remembers everything through [Memory](/guides/memory), so the customer never has to repeat themselves. The channel the message came in on is recorded on the conversation, but the assistant itself stays the same across all of them. ## Channel-Specific Capabilities Your assistant's personality is consistent everywhere, but each channel has its own native features and the assistant uses them automatically: * **WhatsApp**: voice messages, images, documents, contact cards, location sharing, typing indicators, read receipts, interactive buttons. * **Instagram**: DMs, story mentions, image messages. * **Messenger**: Page messages, quick replies. * **TikTok**: direct messages with reply buttons, inside a 48-hour reply window. * **Telegram**: bot commands, inline buttons. * **Slack**: replies in the channel where the bot was mentioned, with buttons. * **Gmail**: threaded email replies with attachments. Two-way email runs on Gmail; the Email channel sends only. * **SMS**: plain text and MMS. * **Web Widget**: rich cards, suggested questions, inline embed or bubble button. For the full list of what the assistant can send and receive, see [Capabilities](/assistants/capabilities). ## Seeing It in Action Once a channel is connected, customers can message your assistant directly from that platform. Here is what it looks like when a customer sends a message through WhatsApp: Customer messaging through WhatsApp Every message lands in your [Inbox](/guides/inbox), where you can see the full conversation, the originating channel, the contact's profile, and [memories](/guides/memory) for that customer: Conversation from WhatsApp in the Inbox ## Channel Guides Each channel has its own authentication screens and requirements. Pick a channel below for the full setup walkthrough, including prerequisites, screenshots, and channel-specific settings. Connect a WhatsApp Business phone number through Meta's embedded signup and start replying in minutes Put your assistant on Messenger for your Facebook Page with Meta login and Page authorization Reply to Instagram DMs, Story replies, and Reel shares from a professional account in one popup Spin up a Telegram bot with @BotFather, paste the token, and start replying in under five minutes Answer TikTok DMs from a Business Account, with reply buttons and a 48-hour reply window More channel guides are on the way. For channels not yet documented here, everything still follows the [universal connection flow](#the-universal-connection-flow) above: click **Connect**, authenticate with the provider, name the connection, pick the channel resource (Page, bot, number, etc.), then **Connect Channel**. ## Best Practices 1. **Start with one channel**: get the experience right on a single channel before turning on more. 2. **Match your customers**: add the channels your customers already use, not every channel you can find. 3. **Keep branding consistent**: use the same assistant name and avatar across all channels so the experience feels unified. 4. **Test every channel after connecting**: send a real message from your own device to confirm round-trip works. 5. **Reuse connections**: authenticate once per provider and share the same [Connection](/workspace-management/connections) across every assistant that needs it. 6. **Monitor the Inbox**: check it regularly, especially "Waiting for Human" conversations the AI transferred. ## Next Steps Manage every authenticated link to external platforms in one place See everything your assistant can understand and send on each channel Embed the chat widget on your website with platform-specific install guides Manage every conversation from every channel in one unified space # Comment Replies Source: https://docs.useinvent.com/assistants/channels/comment-replies Turn a comment on your post into a private conversation your assistant answers This guide builds on a channel you have already connected. If Messenger is not connected yet, start with the [Messenger guide](/assistants/channels/messenger). Someone comments **INFO** under your post. Your assistant sends them a private message with the answer, and the conversation continues in your [Inbox](/guides/inbox) like any other chat. This is the fastest way to turn a post that performs well into real conversations. You publish as usual, invite people to comment a word, and every person who does gets a personal answer within seconds, without anyone watching the comments. ## Where It Works | Channel | Status | Comments it reads | | :----------------- | :------------------ | :------------------------------- | | Facebook Messenger | Available | Comments on your Page posts | | Instagram | In review with Meta | Comments on your posts and reels | Instagram uses a separate Meta permission for reading comments, and Meta is reviewing it. The setting appears on the Instagram channel once that review is approved. Everything else on this page works the same way on both. ## Before You Start 1. **A connected channel.** The Page (or account) must already be answering direct messages. See the [Messenger guide](/assistants/channels/messenger). 2. **A post to use it on.** Any post on the connected Page. The feature reads comments across the whole Page, so you do not select posts one by one. 3. **A word to ask for.** Pick one short word people would not type by chance, like `INFO`, `GUIDE` or `PRICE`. ## Turn It On 1. Open your assistant's **Channels** tab. 2. Click the settings icon on the connected channel. 3. Set **Reply to comments** to **Comments with keywords**. 4. Add your words under **Keywords**. Press Enter after each one. 5. Save. **Every comment** is also available. It answers everyone who comments, keyword or not. Read the next section before you pick it. Facebook Messenger channel settings with Reply to comments set to Comments with keywords and the keywords INFO and GUIDE added The setting is off by default, and it stays off until you pick the keywords. Capital letters and accents do not matter: `GUIA`, `guía` and `Guia` all match the same keyword. Say the word out loud in the video and put it in the caption: *"Comment GUIDE and I will send it to you."* People who type it are telling you they want the answer, and that is exactly the conversation your assistant is good at. ### Keywords or Every Comment The Reply to comments options: No, Every comment, and Comments with keywords, each with a short hint Keywords are the safe default. Answering every single comment is the fastest way to get an account restricted: Meta watches for accounts that message everyone who comments, and a post that takes off turns that into hundreds of unwanted messages in minutes. People writing *"nice one"* or tagging a friend do not want a private message, and enough of them reporting it puts the account at risk. Keywords keep the volume matched to real intent, so only the people who asked get an answer. Use **Every comment** on posts where every comment is a real question, such as a product launch or a giveaway with a small audience, and switch back to keywords if a post starts to take off. ## What Happens Next When someone comments a keyword, your assistant sends them one private message. That message is the whole conversation until they answer. | Step | What happens | | :--------------------- | :--------------------------------------------------------------------------------------------------------------- | | The comment arrives | It appears in your [Inbox](/guides/inbox) as a new conversation, showing the comment text and a link to the post | | Your assistant answers | One private message, sent within seconds | | The person answers | The conversation opens, and from then on it behaves like any other chat | The first message is a single text message. It cannot carry files, buttons or option lists, because the platform allows exactly one message before the person replies. Your assistant knows this and writes accordingly: it does the work first, then answers in one message, and invites the person to reply if it needs anything else. Once they answer, everything is available again: files, buttons, follow-ups, and your team taking over from the Inbox. **One reply per comment, within 7 days.** If the same person comments a second time on another post, that is a new comment and gets its own reply. If someone comments but never answers, no further message can be sent to them until they do. ## When Someone Already Has a Chat If the person messaged you in the last 24 hours, the conversation is already open. In that case your assistant answers the comment as a normal message in the existing chat, with everything available: files, buttons, several messages if it needs them. It also stays in the same conversation. A comment never starts a second chat with someone you are already talking to. ## What the Assistant Knows The comment reaches your assistant as part of the conversation, quoted, so it can answer the actual question rather than send a canned reply. Your [Instructions](/assistants/introduction), [Knowledge](/guides/knowledge) and [Actions](/assistants/actions) all apply exactly as they do in a normal chat. Nothing extra to configure: if your assistant can answer the question in a DM, it can answer it from a comment. ## Best Practices `INFO`, `GUIDE`, `PRICE` and `START` work well. Avoid `thanks`, `nice`, `wow`, `love` or your brand name: those show up in normal comments and turn every conversation into an unwanted message. In the video, the caption and the on-screen text. People follow a clear instruction, and the comments you get are from people who actually want the answer. A first message that is only a URL reads as spam to both people and platforms. Answer the question, then offer the link once the person replies and the conversation is open. Comment replies here are private. If you also reply publicly under the comment, vary the wording. Identical public replies repeated dozens of times is the pattern platforms look for. ## Troubleshooting Work through these in order: 1. **Your own comments are ignored.** A comment from the connected Page or account never starts a conversation. Test from a different profile. 2. **Check the word.** The comment must contain one of the keywords you saved. Extra words around it are fine. 3. **Re-save the channel.** Channels connected before this feature shipped need one save to start receiving comments. Open the channel settings and click Save, with no other change. 4. **Check the assistant is on** for that conversation. If a team member took the conversation over, or AI replies are off, the comment still arrives in the Inbox but no automatic answer is sent. That is the AI switch. When AI replies are off for a conversation, or a team member has taken it over, the comment is recorded and left for a person to answer. Anyone on the team can reply from the Inbox, and that reply goes out as the private message. Meta only notifies us about comments that still exist when the notification is sent. A comment deleted a few seconds after it was posted may never reach us at all. Nothing is wrong on your side. That is the platform rule, not a failure. Until the person answers your first message, nothing else can be sent to them. This is also why your assistant invites a reply instead of promising a follow-up. Switch **Reply to comments** to **Comments with keywords** and add a word. Messaging everyone who comments is the behavior that gets accounts restricted, and a single post that performs well can turn it into hundreds of unwanted messages. Ask for the word in the post instead. ## Next Steps Connect a Facebook Page if you have not yet See where the comment and the conversation land Give the assistant the answers people ask for in comments See which posts bring conversations in # Instagram Direct Messages Source: https://docs.useinvent.com/assistants/channels/instagram Connect an Instagram professional account to your assistant and reply to DMs automatically New to channels? Start with the [Channels Overview](/assistants/channels) to see the universal connect flow that every channel shares. This guide walks through the Instagram-specific screens on top of that flow. Connecting Instagram puts your assistant inside the DMs of a real Instagram account. Anyone who taps **Message** on your profile, replies to a Story, sends a Reel, or messages you from an Instagram ad lands in a conversation that your assistant answers instantly, 24/7. Everything appears in the same [Inbox](/guides/inbox) as your other channels, with the same assistant, the same [Knowledge](/guides/knowledge), and the same [Memory](/guides/memory). The whole setup happens in a single popup. You sign in to Instagram, switch the account to a professional (Business or Creator) account if it is not already one, and Invent takes care of the messaging permissions and webhook subscription for you. ## Before You Start You need three things: 1. **An Instagram account** for the business you want to connect, with the password to hand. If your business does not have an account yet, create one in the Instagram app first. 2. **A professional account type** (Business or Creator). Personal accounts cannot grant messaging access to third-party tools. Don't worry if you are still on a personal account today, the connect flow lets you switch in two clicks without losing followers, posts, or your username. 3. **DMs turned on for the account**. This is the default for every Instagram account, but if you have ever blocked DMs from non-followers in **Settings → Privacy → Messages**, loosen those rules so customers can reach you. You do **not** need to link the Instagram account to a Facebook Page anymore. Invent uses Instagram's own login (the Login with Instagram flow), so a standalone Instagram professional account is enough. If you already manage your Instagram from a Facebook Page, that still works, just sign in here with your Instagram credentials directly. ## Step 1: Open the Instagram Connect Dialog From your assistant's **Channels** tab, find **Instagram Direct Messages** in the list and click **Connect**. The Instagram connect dialog opens. Empty Instagram Direct Messages connect dialog with a + Connect Instagram button inside the Connection field The dialog has one field: * **Connection**: the authenticated link to an Instagram account. If this is your first Instagram connection, the dropdown is empty apart from a blue **+ Connect Instagram** button you use to start the sign-in flow (covered in the next step). If you have already connected Instagram for another assistant, your existing connections are listed here and you can reuse any of them, in which case you can skip to [Step 9](#step-9-pick-the-connection). You can attach more than one Instagram connection to your workspace. After you add the first one, opening the **Connection** dropdown again shows all existing connections plus a **+ Connect Instagram** button at the top to add another. Pick whichever fits this assistant's use case. ## Step 2: Sign In to Instagram Open the **Connection** dropdown and click **+ Connect Instagram**. Instagram's login popup opens. Instagram login screen with a phone, username, or email field, password field, and a Log in with Facebook option This is Instagram's standard sign-in, run entirely on `instagram.com`. Your credentials are only entered on Instagram's domain, never on Invent's. You have two paths: * **Log in with Instagram credentials**: enter the phone number, username, or email and the password for the account that owns the DMs you want the assistant to handle. This is the recommended path because it does not depend on a linked Facebook Page. * **Log in with Facebook**: only use this if the Instagram account is linked to a Facebook profile and you would rather authenticate through Facebook. The end result inside Invent is the same. Sign in with the **business owner's** Instagram account, not a personal employee account that may leave the company later. Access to the Invent connection follows whoever signed in: if that account is deleted, has its password rotated without informing you, or revokes the Invent integration in Instagram's settings, the connection breaks until it is re-authenticated. Click **Log in** to continue. ## Step 3: Complete Two-Factor Authentication If the account has two-factor authentication enabled (and it should), Instagram asks for a one-time code. Depending on the account's 2FA configuration, the code is sent to: * **WhatsApp** on the phone number registered to the Instagram account. * **An SMS** to the same number, if WhatsApp delivery is not configured. * **An authenticator app** like Google Authenticator or Authy, if the account uses one. Check your WhatsApp messages screen prompting for the 6-digit verification code Instagram sent to a masked phone number Open the relevant inbox or app on the phone that owns the account, copy the 6-digit code, paste it into the **Code** field, and click **Continue**. The code is single-use and expires after a few minutes; if it does not arrive, click **Get a new code** or **Try another way** to switch delivery method. If you do not have access to the phone that receives the code, stop here and have the account owner run this step on their own machine. They can complete the rest of the connect flow inside their own Invent session and the connection will appear in your shared workspace, ready for you to bind to this assistant. ## Step 4: Switch to a Professional Account (If Needed) Invent's messaging integration only works with **professional accounts** (Business or Creator). If the Instagram account you signed in with is already a professional account, Instagram skips this step entirely and jumps straight to the [permissions screen](#step-7-review-permissions-and-confirm). If the account is still personal, Instagram shows the **Change to professional account** prompt below. Change to professional account prompt explaining that a professional Instagram account is required to connect to Invent-IG Click **Change** to start the upgrade. The switch is **non-destructive**: * Your username, profile, posts, Reels, Stories, followers, and follower count all stay exactly as they are. * You can revert to a personal account at any time from **Instagram → Settings → Account → Switch to personal account**. * No followers are notified, no Stories or posts get republished, nothing is announced anywhere. The only change customers might notice is a small **Business** or **Creator** label under the bio (which you can hide later if you want). ### Step 4a: Pick a Professional Account Type Instagram asks whether you are a **Creator** or a **Business**. Which best describes you? screen with Creator and Business radio options | Option | When to pick it | | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Creator** | You are a public figure, content producer, artist, influencer, podcaster, or any individual whose Instagram presence is built around personal content rather than a brand. | | **Business** | You are a retailer, local business, brand, organisation, agency, or service provider. This is the right choice for almost every customer-support or sales use case. | Both account types unlock the messaging API the assistant needs. Pick whichever describes the account most accurately, then click **Next**. Business overview screen showing the perks of a Business account: insights, promotions, and contact options Instagram shows a quick summary of what the chosen type unlocks (insights, promotions, contact options). Click **Next** to continue. ### Step 4b: Select a Category Select a category screen with a search field and suggested categories like Personal blog, Product/service, Art, Musician/band, Shopping & retail Pick the category that best describes what the business actually does. Use the search field if your industry is not in the suggested list. The category drives Instagram's discovery surfaces; it has no effect on the assistant. If you would rather not show the category under your bio publicly, leave **Show category on profile** unchecked at the top. The category is still set internally, just not visible to visitors. Click **Done**. ### Step 4c: Confirm the Switch Instagram shows a final confirmation explaining that professional profiles are public. Switch to a professional account? confirmation modal warning that the profile and content will be public A few things to know before you click **Continue**: * **The account becomes public** if it is currently private. Pending follower requests are auto-approved. * **Search engines may index your content** (Instagram's wording, not ours). In practice this only applies to public posts and the profile page. * You can switch back to **Private** later from the Instagram app, but messaging access for the assistant requires a professional, public account. Click **Continue** to commit the switch. ## Step 5: Review Your Contact Info Instagram offers to surface a public **email**, **phone number**, and **address** on the profile so customers can reach you outside of DMs. Review your contact info form with email, phone, street address, town/city, and postcode fields, plus Don't Use My Contact Info and Save buttons This step is **optional** and has no effect on the assistant integration. You have three sensible defaults: * **Skip it entirely**: click **Don't Use My Contact Info** at the bottom-left. The assistant still works perfectly; customers just contact you through DMs. * **Fill it in but keep it private**: enter the fields and leave **Show contact info on profile** unchecked. Useful if Instagram requires the data internally for some categories, but you do not want it shown publicly. * **Fill it in and publish it**: enter the fields and tick **Show contact info on profile**. Customers see the email and phone as buttons under your bio. Click **Save** (or **Don't Use My Contact Info**) to continue. ## Step 6: Confirmation Screen Instagram confirms the account is ready. Your Instagram business account is ready confirmation screen with mobile-app and Business Suite next-step suggestions The on-screen tips about the Instagram mobile app and Meta Business Suite are Instagram's own suggestions; they are not required for the Invent integration. Click **Done** to move on. ## Step 7: Review Permissions and Confirm This is the most important screen in the entire flow. Instagram now asks which messaging permissions to grant Invent. Instagram permissions screen with toggles for Allow access to messages, View profile and access media, and Access and manage messages, plus an Allow button You will see three rows. **Both message-related toggles must be ON** for the assistant to send and receive DMs. | Permission | Default | Required for assistant? | What it does | | --------------------------------- | ------------------------ | ----------------------- | --------------------------------------------------------------------------------------------------------------- | | **Allow access to messages** | ON | **Yes, leave on** | The master switch. Lets Invent receive incoming DMs and send replies on behalf of the account. | | **View profile and access media** | Locked ON, cannot toggle | **Yes, automatic** | Lets Invent read the profile (username, avatar, bio) and any media customers reference (Reels, posts, Stories). | | **Access and manage messages** | ON | **Yes, leave on** | The actual send-and-respond capability. Without this, Invent could see DMs but never reply to them. | If you toggle **Allow access to messages** off here, Invent's connection is created but the assistant cannot send or receive a single DM until you re-run this step and turn it back on. Same for **Access and manage messages**. Leave both on. Click **Allow** to grant access. Instagram briefly provisions the connection, then redirects you back to Invent. ## Step 8: Name the Connection in Invent Instagram redirects you back to Invent and prompts you to label the new connection (for example, "Brand Sales DMs"). This is the name you will see inside Invent, it does not change anything on Instagram's side. Click **Create** and Invent stores the connection in [Settings → Connections](/assistants/connections), where you can rename it or disconnect it at any time. Pick a name that describes *which account this connection is for*, not who signed in. "Sales Instagram" or "EU Brand DMs" reads better in the channel list a year from now than "Alice's Instagram". ## Step 9: Pick the Connection Back on the Instagram connect dialog, your new connection is already selected. Instagram dialog with the Brand Sales DMs connection auto-selected, ready to click Connect Channel Each option in the dropdown shows the Instagram avatar and the connection name you gave it (or the username if you skipped naming), so you can tell sister accounts apart at a glance. Pick the connection this assistant should own if it is not already selected. **One Instagram account, one assistant.** An Instagram account can only be bound to **one** assistant at a time. If two assistants need to share the same account, [AI routing](/assistants/routing) is usually a better pattern than splitting the inbox. Binding an account already attached to another Invent assistant overrides the previous binding and the new assistant takes over from the next message onwards. Click **Connect Channel**. Behind the scenes Invent subscribes its webhook to the account, validates that the messaging permissions are healthy, and turns the channel on. Instagram now shows up in the assistant's Channels tab with an enable/disable toggle, a **Manage** button, and the Instagram username as its identifier. ## Step 10: Send a Test Message Open Instagram on your personal device, search for the connected username (or open `instagram.com/` and tap **Message**), and send a DM. You should see your assistant reply within a few seconds. The conversation also appears in your [Inbox](/guides/inbox) immediately, with the originating account and the Instagram channel shown on the conversation. That is it, the assistant is live on Instagram. People who comment on your posts can start a conversation too. See [Comment Replies](/assistants/channels/comment-replies). ## Connecting More Accounts You can add additional Instagram accounts to the same assistant at any time. From the Channels tab, click **+ Add another** under the Instagram section and either: * **Pick another account from the same connection** (rare, since each Instagram login covers one account), or * **Connect a new account** by opening the Connection dropdown and choosing **Connect Instagram** again. This is the path you will take most often, because each Instagram account needs its own login. Each account runs in parallel under the same assistant, sharing the same Instructions, Knowledge, Memory, and Actions. Conversations are tagged with the originating account in the Inbox so your team always knows which brand or region a DM belongs to. See [Multiple Connections Per Channel](/assistants/channels#multiple-connections-per-channel) for common patterns. ## Reusing a Connection Across Assistants Once an Instagram connection exists in your workspace, any assistant can pick it up from the **Connection** dropdown without going through the Instagram popup again. Authenticate once, reuse everywhere. Manage every connection centrally from [Settings → Connections](/assistants/connections): * **Rename** a connection to keep the list readable as you add more. * **Reconnect** — open the connection with **Edit** and click **Reconnect** inside the dialog — if Instagram's session expires, the password is rotated, or the user revokes the integration from `instagram.com/accounts/manage_access`. * **Disconnect** to remove the link entirely. Any assistant still using that connection stops sending and receiving until it is pointed at a new one. ## Troubleshooting Nothing is saved until Instagram redirects back to Invent with a success. Click **Connect** on the channel again and run through the flow. Your account is already a professional account if you reached Step 4, so the second run will skip straight past the account-type screens. Instagram sometimes prefers WhatsApp delivery on the registered phone number even when SMS would be faster. On the 2FA screen, click **Try another way** and switch to SMS or to an authenticator app. If the registered phone number is no longer in use, recover the account from `instagram.com/accounts/login/` first, update the phone number, then retry the connect flow. Instagram occasionally rejects the switch when the account is too new (less than \~24 hours old) or has triggered an integrity check. Wait a few hours, sign in to Instagram on the mobile app, complete any verification prompts shown there (email confirmation, phone confirmation), and try the connect flow again from Invent. The most common cause is that **Allow access to messages** was toggled off on the permissions screen in [Step 7](#step-7-review-permissions-and-confirm). Open [Settings → Connections](/assistants/connections), click **Fix** (or **Edit**) on the Instagram connection, then **Reconnect** inside the dialog, and confirm both **Allow access to messages** and **Access and manage messages** are ON when you reach the permissions screen this time. A second cause is that DMs from non-followers are restricted on the account. Open Instagram → **Settings → Privacy → Messages** and make sure your message controls allow DMs from the audience you expect. Instagram's access token has expired or was revoked. Common reasons: the password was rotated, the integration was removed from `instagram.com/accounts/manage_access`, or the account was switched back to Personal (which strips messaging access). Open [Settings → Connections](/assistants/connections), find the Instagram connection, click **Fix** (or **Edit**), then **Reconnect** inside the dialog to run a short re-authentication flow. Channels bound to that connection start working again as soon as the reconnection finishes. Instagram blocks promotional content sent outside the 24-hour window. To re-engage a customer who went quiet for longer than that, your message must fit a [Message Tag](https://developers.facebook.com/docs/messenger-platform/instagram/features/message-tags) (such as `POST_PURCHASE_UPDATE` or `ACCOUNT_UPDATE`) and the content must match what that tag allows. Use [Auto Follow-ups](/guides/auto-follow-ups) for in-window re-engagement, or reply manually as a member through the Inbox using the appropriate tag. Instagram hides identifying information for accounts with restricted profile visibility, accounts under 18, or customers who interact through certain regional entry points. The conversation works end-to-end; the assistant just does not have a name to use until the customer shares it. You can prompt for it from your Instructions, for example: *"If you do not know the customer's name, ask for it the first time you reply, then save it to memory."* Instagram supports only **one active messaging integration per account at a time**. If a partner needs to manage the inbox from a different workspace, they have to run the connect flow on their own Invent workspace and bind the same account, which overrides the previous binding. Coordinate with the partner before switching, or use a second Instagram account so each tool can stay active independently. ## Next Steps See the universal connection flow that every channel uses Manage every authenticated link, including Instagram, in one place See everything your assistant can send and receive on Instagram Capture referrals from Instagram ads, products, and Story mentions on every conversation # Facebook Messenger Source: https://docs.useinvent.com/assistants/channels/messenger Connect a Facebook Page to your assistant and reply to Messenger conversations automatically New to channels? Start with the [Channels Overview](/assistants/channels) to see the universal connect flow that every channel shares. This guide walks through the Messenger-specific screens on top of that flow. Connecting Messenger gives your assistant the inbox of a real Facebook Page. Anyone who taps **Send Message** on your Page, finds you through search, or replies to a Messenger ad lands in a conversation that your assistant answers instantly, 24/7. Everything appears in the same [Inbox](/guides/inbox) as your other channels, with the same assistant, the same [Knowledge](/guides/knowledge), and the same [Memory](/guides/memory). The whole setup happens in a single popup. You sign in with the Facebook account that manages your Page, pick the Page, and Invent takes care of the webhook subscription and Page authorization for you. ## Before You Start You need three things: 1. **A Facebook account** that is an admin (or has Messaging access) on the Page you want to connect. Editor and Moderator roles on a Page do not have permission to grant Messenger access on behalf of the business; ask the Page admin to run this flow if you do not have that role. 2. **A Facebook Page** for the business you are connecting. If your business does not have a Page yet, create one at [facebook.com/pages/create](https://www.facebook.com/pages/create) before you start. The Page does not need to be Verified, and it does not need to be linked to a Business Portfolio for inbound Messenger to work. 3. **Messenger turned on for the Page**. This is the default for every Page, but if you have ever paused Messenger from the Page settings, switch it back on first. With it off, customers cannot start a conversation and the assistant has nothing to reply to. Messenger is the easiest Meta channel to onboard, since it does not require a Business Portfolio, business verification, or message templates the way WhatsApp does. If you can already receive DMs on your Page, your assistant will be able to reply to them. ## Step 1: Open the Messenger Connect Dialog From your assistant's **Channels** tab, find **Facebook Messenger** in the list and click **Connect**. The Messenger connect dialog opens. Empty Facebook Messenger connect dialog with a + Connect Messenger button inside the Connection field The dialog has two fields: * **Connection**: the authenticated link to your Facebook account. If this is your first Messenger connection, the dropdown is empty apart from a blue **+ Connect Messenger** button you use to start the sign-in flow (covered in the next step). If you have already connected Messenger for another assistant, your existing connections are listed here and you can reuse any of them, in which case you can skip to [Step 6](#step-6-pick-the-page). * **Page**: the specific Facebook Page on that connection that this assistant should send and receive messages for. Disabled with *Requires Connection* until a connection is selected, then populated automatically with every Page Invent has access to under that connection. You can attach more than one Messenger connection to your workspace. After you add the first one, opening the **Connection** dropdown again shows all existing connections plus a **+ Connect Messenger** button at the top to add another. Pick whichever fits this assistant's use case. ## Step 2: Authenticate with Facebook Open the **Connection** dropdown and click **+ Connect Messenger**. Facebook's login popup opens. Facebook login screen showing the current profile with Continue, Use another profile, and Create new account buttons This is Facebook's standard sign-in, run entirely on `facebook.com`. Your credentials are only entered on Facebook's domain, never on Invent's. You have three options: * **Continue** as the suggested profile. Use this when the profile shown is the Facebook account that manages the Page you want to connect. * **Use another profile** to switch to a different Facebook account on this device. * **Create new account** if the right Facebook account does not exist yet. We do not recommend this route for businesses; assign a real admin's Facebook account instead so Page access is not tied to a throwaway profile. Pick the Facebook profile that is an **admin** on the Page you intend to connect. Signing in as a profile that only has Editor, Moderator, Advertiser, or Analyst access on the Page will succeed at the Facebook login step, but Facebook will hide that Page from the next screen because the profile cannot grant Messenger access on its behalf. Click **Continue** to proceed. ## Step 3: Choose the Pages Invent Can Access Facebook now asks which of your Pages this integration is allowed to manage. Choose the Pages you want Invent to access screen with two radio options: opt in to all current and future Pages, or opt in to current Pages only You have two options: | Option | When to pick it | | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Opt in to all current and future Pages** | You manage one or only a few Pages, or you expect to add more Pages to this assistant over time. New Pages you create later become available inside the Messenger connect dialog automatically, with no return trip to Facebook. | | **Opt in to current Pages only** | You manage many Pages and want to scope Invent's access to a known subset. Only the Pages you explicitly select on the next screen are exposed to Invent. To add another Page later, you have to rerun the Facebook flow and grant access to it. | If you pick **Opt in to current Pages only**, Facebook shows a multi-select list of every Page your profile manages. Tick the Pages you want Invent to be able to bind to and continue. For most teams, **Opt in to all current and future Pages** is the right choice. The set of Pages a given assistant can use is still controlled inside Invent (you pick one Page per binding in [Step 6](#step-6-pick-the-page)), so granting broad access on Facebook does not automatically connect any of them. Click **Continue**. ## Step 4: Review Permissions and Confirm Facebook shows a final summary of what Invent is requesting access to. Review Invent's access request listing the permissions: manage your business, manage and access Page conversations on Messenger, read content posted on the Page, manage accounts and settings, show a list of Pages you manage Invent requests the minimum set of Page permissions required to run a Messenger assistant: * **Manage your business**: identify which businesses and Pages your profile manages, so the right ones surface in the next steps. * **Manage and access Page conversations on Messenger**: receive incoming Messenger messages and send replies on behalf of the Page. This is the core capability that powers the assistant. * **Read content posted on the Page**: pick up the context of comments, story replies, and other content that customers reference when they message you. * **Manage accounts, settings, webhooks, and access content enforcement data for a Page**: subscribe Invent's webhook to the Page so new messages arrive in your Inbox in real time, without polling. * **Show a list of Pages you manage**: surface the list of eligible Pages inside the Messenger connect dialog so you can pick one without copy-pasting any IDs. Click **Save** to grant access. Facebook then provisions the connection and shows the success screen. Acme Inc has been connected to Invent confirmation screen with a Got it button and a link to manage the integration in Business integrations The success screen includes a **go to Business integrations** link for managing this connection inside Facebook's settings. You do not need to use it now. Most day-to-day operations (rename, reconnect, disconnect) can be done directly from [Settings → Connections](/assistants/connections) inside Invent. Click **Got it** to close the popup. ## Step 5: Name the Connection in Invent Facebook redirects you back to Invent and prompts you to label the new connection (for example, "Acme Inc" or "Sales Pages"). This is the name you will see inside Invent, it does not change anything on Facebook's side. Click **Create** and Invent stores the connection in [Settings → Connections](/assistants/connections), where you can rename it or disconnect it at any time. Pick a name that describes *which Pages this connection covers*, not which person signed in. "Acme Pages" or "EU Brand Pages" reads better in the channel list a year from now than "Alice's Facebook". ## Step 6: Pick the Page Back on the Messenger connect dialog, your new connection is already selected. The **Page** dropdown now lists every Facebook Page that connection has access to. Facebook Messenger dialog with the Acme Inc connection selected and the Page dropdown ready to choose a Page, with a Connect Channel button at the bottom Each option shows the Page name, its profile picture, and the Page category, so it is easy to tell sister brands apart. Pick the Page this assistant should own. **One Page, one assistant.** A Facebook Page can only be bound to **one** assistant at a time. If two assistants need to share the same Page, [AI routing](/assistants/routing) is usually a better pattern than splitting the Page. If you bind a Page that is already attached to another Invent assistant or a different Messenger automation tool, the previous binding is overridden and the new assistant takes over the inbox. Click **Connect Channel**. Behind the scenes Invent subscribes its webhook to the Page, validates that messaging permissions are healthy, and turns the channel on. Messenger now shows up in the assistant's Channels tab with an enable/disable toggle, a **Manage** button, and the connected Page name as its identifier. ## Step 7: Send a Test Message Open Messenger on your personal device, search for the connected Page (or open `m.me/`), and send a message. You should see your assistant reply within a few seconds. The conversation also appears in your [Inbox](/guides/inbox) immediately, with the originating Page and the Messenger channel shown on the conversation. That is it, the assistant is live on Messenger. People who comment on your posts can start a conversation too. See [Comment Replies](/assistants/channels/comment-replies). ## Connecting More Pages You can add additional Facebook Pages to the same assistant at any time. From the Channels tab, click **+ Add another** under the Messenger section and either: * **Pick another Page from the same connection** (if your Facebook profile manages more than one Page that this connection has access to), or * **Connect a new account** by opening the Connection dropdown and choosing **Connect Messenger** again. This is the path to take when the new Page lives under a different Facebook profile or business. Each Page runs in parallel under the same assistant, sharing the same Instructions, Knowledge, Memory, and Actions. Conversations are tagged with the originating Page in the Inbox so your team always knows which brand a message belongs to. See [Multiple Connections Per Channel](/assistants/channels#multiple-connections-per-channel) for common patterns. ## Reusing a Connection Across Assistants Once a Messenger connection exists in your workspace, any assistant can pick it up from the **Connection** dropdown without going through the Facebook popup again. Authenticate once, reuse everywhere. Manage every connection centrally from [Settings → Connections](/assistants/connections): * **Rename** a connection to keep the list readable as you add more. * **Reconnect** — open the connection with **Edit** and click **Reconnect** inside the dialog — if the Facebook session expires, an admin removes the integration from Business integrations, or a user revokes the permissions on `facebook.com/settings/business_integrations`. * **Disconnect** to remove the link entirely. Any assistant still using that connection stops sending and receiving until it is pointed at a new one. ## Troubleshooting Nothing is saved until Facebook reaches the **Connected to Invent** confirmation screen. Click **Connect** on the channel again and run through the flow. Your previous selections (which Pages to grant access to, which permissions to approve) are remembered on Facebook's side, so you will move through the prompts faster on the second try. There are three common causes: 1. The Facebook profile you signed in with is not an **admin** on that Page. Editor, Moderator, Advertiser, and Analyst roles can read messages but cannot grant Messenger access. Ask the Page admin to run this flow, or have them promote your account to admin first. 2. You picked **Opt in to current Pages only** in [Step 3](#step-3-choose-the-pages-invent-can-access) and forgot to tick this Page. Open [facebook.com/settings/business\_integrations](https://www.facebook.com/settings/business_integrations), find Invent, click **View and edit**, and add the Page to the granted list. Then reopen the Page dropdown in Invent. 3. The Page is already bound to another Invent assistant in your workspace. Disconnect it from the other assistant first, or pick a different Page. The most common reason is that **Messenger is paused** on the Page. Open the Page's settings on Facebook (Page → Settings → Privacy → Public Posts, or **Messages** depending on your Page version), make sure Messenger is allowed, and that automated responses from previous tools are turned off. Then send a fresh message from your personal account to verify. A second cause is a stale webhook subscription after a Facebook outage. Open [Settings → Connections](/assistants/connections), click **Fix** (or **Edit**) on the Messenger connection, then **Reconnect** inside the dialog, and the webhook resubscribes automatically. Facebook's access token has expired or was revoked. Common reasons: the admin who originally signed in left the business, the integration was removed from `facebook.com/settings/business_integrations`, or the Page was reassigned to a different Business Portfolio. Open [Settings → Connections](/assistants/connections), find the Messenger connection, click **Fix** (or **Edit**), then **Reconnect** inside the dialog to run a short re-authentication flow. Channels bound to that connection start working again as soon as the reconnection finishes. Messenger blocks promotional content sent outside the 24-hour window. To re-engage a customer who went quiet for longer than that, your message must fit a [Message Tag](https://developers.facebook.com/docs/messenger-platform/send-messages/message-tags) (such as `POST_PURCHASE_UPDATE` or `ACCOUNT_UPDATE`) and the content must match what that tag allows. Use [Broadcasts](/guides/broadcasts/introduction) for tagged outbound at scale, and rely on [Auto Follow-ups](/guides/auto-follow-ups) for in-window re-engagement. Meta hides identifying information for customers who have restricted profile visibility or who interact with the Page through certain regional Messenger entry points. The conversation still works end-to-end; the assistant just does not have a name to use until the customer shares it. You can prompt for it from your Instructions, for example: *"If you do not know the customer's name, ask for it the first time you reply, then save it to memory."* Facebook supports multiple integrations on the same Page. Have the partner run their own Messenger connect flow inside their Invent workspace and pick the Page from the dropdown. Bear in mind that **only one tool can hold the active Messenger automation at a time per Page**, so whichever workspace was the most recent to bind the Page becomes the one that replies. Coordinate with the partner before switching, or split sales and support onto two separate Pages. ## Next Steps See the universal connection flow that every channel uses Manage every authenticated link, including Messenger, in one place See everything your assistant can send and receive on Messenger Capture referrals from Messenger ads and m.me deep links on every conversation # Telegram Bot Source: https://docs.useinvent.com/assistants/channels/telegram Connect a Telegram bot to your assistant and reply to chats automatically New to channels? Start with the [Channels Overview](/assistants/channels) to see the universal connect flow that every channel shares. This guide walks through the Telegram-specific steps on top of that flow. Connecting Telegram puts your assistant inside a real Telegram bot. Anyone who finds your bot in Telegram search, opens its `t.me/` link, or taps a Start button in your marketing material lands in a chat that your assistant answers instantly, 24/7. Everything appears in the same [Inbox](/guides/inbox) as your other channels, with the same assistant, the same [Knowledge](/guides/knowledge), and the same [Memory](/guides/memory). Telegram does not use OAuth. Instead, it gives every bot a **bot token** that uniquely identifies and authenticates it. You generate the token with Telegram's official **@BotFather** (a bot for creating bots) and paste it into Invent once. From then on the bot belongs to your workspace. ## Before You Start You need two things: 1. **A Telegram account** to chat with @BotFather. Any personal Telegram account works; the bot you create is independent of the account that creates it, so this is not a long-term ownership decision. Use Telegram on your phone or `web.telegram.org` on the desktop, whichever is easier. 2. **A name and username for your bot**. The username has to be **globally unique** across all of Telegram and must end in `bot` or `_bot` (for example, `acme_support_bot`). Have a couple of variants ready in case your first pick is taken. Unlike WhatsApp or Instagram, there is no "professional account" requirement and no 24-hour messaging window on Telegram. Once a user has clicked **Start** on your bot, your assistant can message them at any time, as often as you want, with text, voice, images, files, or interactive buttons. ## Step 1: Open the Telegram Connect Dialog From your assistant's **Channels** tab, find **Telegram Bot** in the list and click **Connect**. The Telegram connect dialog opens. Empty Telegram Bot connect dialog with a + Connect Telegram button inside the Connection field The dialog has one field: * **Connection**: the authenticated link to a Telegram bot, identified by its token. If this is your first Telegram connection, the dropdown is empty apart from a blue **+ Connect Telegram** button you use to start the setup (covered in the next step). If you have already connected a Telegram bot for another assistant, your existing connections are listed here and you can reuse any of them, in which case you can skip to [Step 5](#step-5-pick-the-bot). You can attach more than one Telegram bot to your workspace. After you add the first one, opening the **Connection** dropdown again shows all existing bots plus a **+ Connect Telegram** button at the top to add another. Pick whichever fits this assistant's use case. ## Step 2: Open the Connection Form Open the **Connection** dropdown and click **+ Connect Telegram**. The connection form opens. Empty Telegram connection form with Connection Name and Telegram Bot Token fields, plus Test Connection and Create Connection buttons The form has two fields: * **Connection Name** *(optional)*: a label you will see inside Invent (for example, "Acme Support Bot"). If you leave it blank, Invent uses the bot's own Telegram name as the label. * **Telegram Bot Token** *(required)*: the secret token issued by @BotFather, in the format `123456:ABCDEF1234abcdef1234ABCDEF1234abcdef`. You will create this in the next step. Leave the form open in your browser. We need the token before we can fill it in. Click the small **link icon** (↗) next to the **Telegram Bot Token** label at any time to open `t.me/BotFather` in a new tab and jump straight into the bot creation flow. ## Step 3: Create a Bot with @BotFather Open Telegram (mobile, desktop, or `web.telegram.org`) and search for **BotFather**. Pick the **verified** result, the one with the blue checkmark next to the name. Tap **Start** to begin the conversation. BotFather start screen on Telegram with the Start button at the top right and the bot's introduction message There are **many fake "BotFather" clones** in Telegram search. Always pick the one with the blue verified checkmark, the one that says it has millions of monthly users. Pasting your real bot token into a fake support bot is the most common way Telegram bots get hijacked. ### Step 3a: Send `/newbot` Type `/newbot` and send it. BotFather replies asking for a **display name** for the new bot. Sending the /newbot command to BotFather, with the autocomplete suggestion shown above the message composer ### Step 3b: Pick a Display Name and Username BotFather walks you through two prompts: 1. **Display name**: the friendly name customers see at the top of the chat (for example, "Acme Enterprise Enquiry Bot"). Spaces and most characters are allowed. You can change this later from BotFather with `/setname`. 2. **Username**: the globally unique identifier that becomes your bot's `t.me/` link. It **must end in `bot`** (or `_bot`), is case-insensitive, and cannot be changed once chosen. If your first pick is taken, BotFather rejects it with *"Sorry, this username is already taken"* and asks for another. BotFather conversation showing the display name reply, a rejected username, an accepted username, and the success message that includes the bot token When BotFather accepts both, it replies with a success message ending in **"Use this token to access the HTTP API:"** followed by the actual token. ### Step 3c: Copy the Token Tap (or click) the token to copy it to your clipboard. The format is always: ``` 123456:ABCDEF1234abcdef1234ABCDEF1234abcdef ``` A short numeric prefix, a colon, and a long alphanumeric secret. **Treat the bot token like a password.** Anyone who has it can read every message your bot receives and send messages on its behalf. Never paste it into a public chat, never commit it to a Git repository, never share it in a screenshot. If a token leaks, immediately go back to BotFather and run `/revoke` on the bot to rotate it; then update the connection in Invent with the new token. While you are still in the @BotFather chat, this is also a good time to set the bot's **avatar** (`/setuserpic`), **about** text (`/setabouttext`), and **description** (`/setdescription`). These show up on the bot's profile and on the empty-chat splash screen the first time a customer opens your bot. None of them are required for the assistant to work, but a polished profile increases the rate at which visitors actually click **Start**. ## Step 4: Create the Connection in Invent Switch back to the Invent connection form you left open in [Step 2](#step-2-open-the-connection-form). Telegram connection form filled in with the connection name 'Acme Enterprise Enquiry Bot' and a masked Telegram bot token 1. **Connection Name**: enter a label that will read well in the channel list a year from now. "Acme Enterprise Enquiry Bot" is better than "Test" or "Alice's bot". 2. **Telegram Bot Token**: paste the token you copied from @BotFather. Invent masks it with dots as soon as you paste, so it is never visible in plain text on screen again. 3. *(Optional)* Click **Test Connection**. Invent calls Telegram with the token and confirms that it is valid and that the bot is reachable. If anything is wrong (mistyped token, revoked token, bot deleted), the error surfaces here before you save anything. 4. Click **Create Connection**. Invent stores the connection in [Settings → Connections](/assistants/connections), where you can rename it, rotate the token, or disconnect it at any time. Invent encrypts the bot token at rest and never returns it in plain text after creation. If you forget the token, regenerate it with `/revoke` in @BotFather and update the connection. ## Step 5: Pick the Bot Back on the Telegram Bot connect dialog, your new connection is already selected. Telegram Bot dialog with the Acme Enterprise Enquiry Bot connection auto-selected, ready to click Connect Channel If you have multiple Telegram bots in your workspace, pick the one this assistant should own from the dropdown. **One bot, one assistant.** A Telegram bot can only be bound to **one** assistant at a time. If two assistants need to share the same bot, [AI routing](/assistants/routing) is usually a better pattern than splitting the bot. Binding a bot already attached to another Invent assistant overrides the previous binding and the new assistant takes over from the next message onwards. Click **Connect Channel**. Behind the scenes Invent registers its webhook with Telegram so new messages arrive in your Inbox in real time, validates that the token is healthy, and turns the channel on. Telegram now shows up in the assistant's Channels tab with an enable/disable toggle, a **Manage** button, and the bot's `@username` as its identifier. ## Step 6: Send a Test Message Open Telegram on your personal device, search for your bot's username (or open `t.me/` from any browser and let it deep-link into the Telegram app), and tap **Start**. You should see your assistant reply within a second or two. The conversation also appears in your [Inbox](/guides/inbox) immediately, with the originating bot and the Telegram channel shown on the conversation. That is it, the assistant is live on Telegram. ## Connecting More Bots You can add additional Telegram bots to the same assistant at any time. From the Channels tab, click **+ Add another** under the Telegram section and either: * **Pick another bot from the existing connections list** in the Connection dropdown, or * **Connect a new bot** by clicking **+ Connect Telegram** in the dropdown, creating a fresh bot with @BotFather, and pasting its token into a new connection. Each bot runs in parallel under the same assistant, sharing the same Instructions, Knowledge, Memory, and Actions. Conversations are tagged with the originating bot in the Inbox so your team always knows which brand or campaign a message belongs to. See [Multiple Connections Per Channel](/assistants/channels#multiple-connections-per-channel) for common patterns. ## Reusing a Connection Across Assistants Once a Telegram connection exists in your workspace, any assistant can pick it up from the **Connection** dropdown without re-entering the token. Set up a bot once, reuse it everywhere. Manage every connection centrally from [Settings → Connections](/assistants/connections): * **Rename** a connection to keep the list readable as you add more. * **Rotate the token**: if you regenerate the bot token in @BotFather (with `/revoke`), open the connection in Invent, click **Edit**, paste the new token, and save. Channels bound to that connection start working again immediately. * **Disconnect** to remove the link entirely. Any assistant still using that connection stops sending and receiving until it is pointed at a new bot. ## Troubleshooting Three common causes: 1. The token has whitespace or a stray character around it from the copy-paste. Re-copy the token directly from the @BotFather success message and paste it again. 2. The token has already been **revoked**. Run `/mybots` in @BotFather, pick this bot, choose **API Token**, and verify that the visible token matches what you pasted. Use **Revoke current access token** to mint a fresh one if needed and update Invent with the new value. 3. The bot was **deleted** in @BotFather. There is no recovery, you have to create a new bot, paste its token into a new Invent connection, and rebind the channel. The most common reason is that another tool, automation, or script still owns the bot's webhook. Telegram only delivers each update to **one webhook URL at a time**. Open [Settings → Connections](/assistants/connections), click **Edit** on the Telegram connection, and re-save the token (or **Disconnect** and re-run **Connect Channel**) to re-register its webhook: any old subscriber stops receiving messages. A second cause is that the bot was added to a Telegram **group** with **privacy mode** still on (the default). In groups, privacy-mode bots only see messages that mention them or reply to them. For one-on-one DMs, this does not matter, the bot always receives them. If you intend to use the bot in groups too, talk to @BotFather, run `/setprivacy`, pick the bot, and set privacy to **Disable**. Telegram usernames are first-come, first-served and never released, even when a bot is deleted. Try variations: add your industry (`acme_support_bot`), your region (`acme_eu_bot`), or a year (`acme_bot_2026`). Keep it short, all-lowercase, and easy to dictate over the phone, since customers will type it into Telegram search. Treat this as a security incident. Open @BotFather, run `/mybots`, pick the affected bot, choose **API Token**, then **Revoke current access token**. BotFather issues a new token and the old one is permanently invalidated. Open [Settings → Connections](/assistants/connections) in Invent, edit the Telegram connection, paste the new token, and save. The channel resumes service the moment the new token is saved; the leaked token can no longer be used by anyone. Either the token was revoked in @BotFather without updating Invent, or the bot was deleted. Open [Settings → Connections](/assistants/connections), find the Telegram connection, and click **Fix** (shown when the row has a status error) or **Edit**, then paste a fresh token. If the bot itself was deleted, you have to create a new one and rebind the channel. This is a Telegram platform rule, not an Invent limitation. Bots cannot DM users who have not opened a chat with them first. Customers always have to tap **Start** (or send any message) at least once before the bot, and therefore the assistant, can reply or follow up. Use a `t.me/?start=` deep link in your marketing material, ads, or QR codes to make that first tap as smooth as possible. Telegram supports only **one active webhook per bot**, so only one workspace can be bound to a given bot at a time. If a partner needs to manage the same bot from a different Invent workspace, share the token with them; the moment they bind it, your workspace's webhook is replaced and stops receiving messages. To run two integrations in parallel, create a second bot with @BotFather and give the partner the new bot's token instead. ## Next Steps See the universal connection flow that every channel uses Manage every authenticated link, including Telegram, in one place See everything your assistant can send and receive on Telegram Manage every Telegram conversation alongside your other channels # TikTok Direct Messages Source: https://docs.useinvent.com/assistants/channels/tiktok Connect a TikTok Business Account to your assistant and reply to DMs automatically New to channels? Start with the [Channels Overview](/assistants/channels) to see the universal connect flow that every channel shares. This guide walks through the TikTok-specific parts on top of that flow. Connecting TikTok puts your assistant inside the direct messages of your TikTok Business Account. Someone who taps **Message** on your profile, clicks a Click-to-Message ad, shares one of your videos, or opens a `tiktok.me` link lands in a conversation your assistant answers instantly. Everything appears in the same [Inbox](/guides/inbox) as your other channels, with the same assistant, the same [Knowledge](/guides/knowledge), and the same [Memory](/guides/memory). TikTok has stricter entry rules than any other channel. Read **Before You Start** carefully. If your account does not meet all four conditions, either the connection fails with an error or no message ever arrives. ## Before You Start You need four things: 1. **A TikTok Business Account.** Personal and Creator accounts cannot be connected. You can switch for free in the TikTok app under **Settings and privacy → Account → Switch to Business Account**. Your username, videos, and followers stay exactly as they are. The Account settings screen in the TikTok app with the Switch to Business Account option highlighted 2. **The Professional messaging suite.** In the TikTok app, go to **Settings and privacy → Inbox & Messaging** and, under **Select a messaging suite**, choose **Professional · Engage followers**. This is what opens the account's inbox to messaging tools. If the account is still on **Personal**, the channel connection fails with an error at **Connect Channel**. The Settings and privacy screen in the TikTok app with the Inbox and Messaging preference highlighted The Select a messaging suite screen in the TikTok app with Professional, Engage followers selected instead of Personal, Chat with friends 3. **An account registered outside the European Economic Area, Switzerland, and the United Kingdom.** TikTok decides this by where the account was signed up, not where you or your customers are today. Accounts registered in those places cannot use TikTok messaging through any third-party tool yet. 4. **Direct messages open to everyone.** In the TikTok app, go to **Settings and privacy → Privacy → Direct messages** and allow messages from **Everyone**. If this is left on "Friends", customer messages sit in a request folder and never reach your assistant. Customers in the European Economic Area, Switzerland, and the United Kingdom can still message you, but TikTok removes the text before it leaves their servers. Those conversations arrive empty, so your assistant cannot answer them. This is a TikTok restriction and applies to every tool, not only Invent. **TikTok Shop messages are separate.** This channel covers direct messages sent to your TikTok profile. Messages from TikTok Shop orders run on a different TikTok system and are not included. ## Step 1: Open the TikTok Connect Dialog From your assistant's **Channels** tab, find **TikTok Direct Messages** in the list and click **Connect**. TikTok Direct Messages connect dialog showing a reminder that the account must be a Business Account and is not supported in the EU, Switzerland, or the UK, above a Connection field holding a Connect TikTok button and a disabled Connect Channel button The reminder inside the dialog repeats the two rules that block most connections: the account has to be a Business Account, and it cannot be registered in the EU, Switzerland, or the UK. The dialog has one field: * **Connection**: the authenticated link to a TikTok Business Account. If this is your first TikTok connection, the dropdown holds a **+ Connect TikTok** button that starts the sign-in. If you already connected TikTok for another assistant, pick that connection and skip to [Step 4](#step-4-pick-the-connection). ## Step 2: Sign In to TikTok Open the **Connection** dropdown and click **+ Connect TikTok**. TikTok's authorization page opens. This page runs entirely on `tiktok.com`. Your password is only ever entered on TikTok's own domain, never on Invent's. Sign in with the account that owns the messages you want the assistant to handle, then review the permissions TikTok lists. The assistant needs all of them to read incoming messages and send replies. Sign in with the **business owner's** TikTok account, not a personal employee account. Access follows whoever signed in. If that account is deleted, has its password changed, or removes Invent from its authorized apps, the channel stops working until someone reconnects it. ## Step 3: Name the Connection in Invent TikTok sends you back to Invent and asks you to label the new connection, for example "Brand TikTok DMs". This name is only used inside Invent. Click **Create**. The connection is stored in [Settings → Connections](/assistants/connections), where you can rename or disconnect it later. ## Step 4: Pick the Connection Back on the TikTok dialog, your new connection is already selected. Click **Connect Channel**. **One TikTok account, one assistant.** A TikTok account can only be bound to one assistant at a time. If two assistants need the same account, [AI routing](/assistants/routing) is usually a better fit than splitting the inbox. ## Step 5: Send a Test Message Click the connected TikTok channel to open the test dialog. It shows the connected profile, a QR code to your TikTok page, and an **Open TikTok** button. Test your assistant dialog showing the connected TikTok profile, a QR code to it, and Open TikTok, Copy, and Open Inbox buttons Scan the code with your phone, using a different account from the one you connected, and send a direct message. Your assistant should reply within a few seconds, and the conversation appears in your [Inbox](/guides/inbox), with a TikTok badge on the contact and their handle under their name. Invent Inbox showing a TikTok conversation, the customer handle under their name, assistant replies in the thread, and an Outside 48h window notice on the reply box That is it, the assistant is live on TikTok. ## What Goes Through, Each Way TikTok is not symmetric: customers can send you more than your assistant can send back. Plan your Instructions around this table. | | Your assistant sends | Customers send | | :------------------------------ | :------------------------------------ | :---------------------------------------- | | Text | Yes, up to 6,000 characters | Yes | | Photos | Yes, JPG, PNG, GIF and BMP up to 3 MB | Yes | | Video | No | Yes | | Voice notes and audio | No | No | | iPhone Live Photos | Not applicable | No, they arrive empty | | Documents and files | No | No | | Stickers and emojis | No | Yes | | Shared TikTok posts | No | Yes | | Reply buttons | Yes, up to 3 on a question card | Tapping one sends its text as their reply | | Text and a photo in one message | No, they go as two messages | Not applicable | | Bold, italic, links as buttons | No, everything is plain text | Not applicable | | Starting the conversation | No, the customer always writes first | Yes, always | | Broadcasts | No | Not applicable | **Voice notes and iPhone Live Photos never arrive.** TikTok's messaging API has no audio message type at all, and it cannot hand over a Live Photo even though it records that one was sent. Both reach us empty, with no file to download, so you will not see them in the Inbox and neither will your assistant. The customer sees the message as delivered, so they may think you have it. Ask them to type the question or send a normal photo, or open the TikTok app yourself to look. This applies to every tool built on TikTok messaging, not only Invent. Write links as plain addresses like `https://example.com`. TikTok shows the raw text, so a formatted link would reach the customer as unreadable markup. Referrals are captured as well, so you can see when a conversation started from an ad, a shared video, or a `tiktok.me` link. ## The 48-Hour Reply Window TikTok lets you reply for **48 hours** after the customer's last message, and every reply from them opens a fresh window. Once 48 hours pass with no reply, you get three more messages before sends are blocked until they write again. This is twice as long as WhatsApp, Messenger, and Instagram allow, but it still means a conversation left alone over a long weekend can close. Use [Auto Follow-ups](/guides/auto-follow-ups) to re-engage while the window is open. ## Reusing a Connection Across Assistants Once a TikTok connection exists in your workspace, any assistant can pick it from the **Connection** dropdown without signing in again. Manage every connection from [Settings → Connections](/assistants/connections): * **Rename** a connection to keep the list readable as you add more. * **Reconnect** with **Edit** then **Reconnect** if TikTok's session expires or someone removes Invent from the account's authorized apps. * **Disconnect** to remove the link. Any assistant still using it stops sending and receiving. ## Troubleshooting Check the four entry rules in [Before You Start](#before-you-start), in this order. First, confirm the account is a Business Account, not Personal or Creator. Second, confirm the messaging suite is set to **Professional** under **Settings and privacy → Inbox & Messaging**. Third, confirm direct messages are open to **Everyone** in the TikTok app, since messages from strangers otherwise wait in a request folder. Fourth, check where the account was registered, because accounts signed up in the EEA, Switzerland, or the UK cannot use TikTok messaging through any third-party tool. The most common cause is the account's messaging suite. In the TikTok app, go to **Settings and privacy → Inbox & Messaging** and, under **Select a messaging suite**, choose **Professional · Engage followers**, then try connecting again. If it still fails, confirm the account is a Business Account and is registered outside the EEA, Switzerland, and the UK. The customer's TikTok account is registered in the European Economic Area, Switzerland, or the United Kingdom. TikTok removes the message text for those regions before it reaches any third-party tool. You will see that a conversation started, but there is nothing to answer. Reply from the TikTok app directly if you need to reach that customer. Three limits apply. The file has to be a JPG, PNG, GIF or BMP, it has to be under 3 MB, and both you and the customer have to be in regions where TikTok allows image messages. Text still goes through when an image is rejected, so the customer receives the reply without the picture. TikTok only allows replies to customers who messaged you first, and only within 48 hours of their last message. There is no template or paid message to reopen a conversation the way WhatsApp allows. Run campaigns that invite people to message you, for example a Click-to-Message ad or a `tiktok.me` link, rather than trying to message first. TikTok's access expired or was revoked. Common reasons are a password change, or someone removing Invent from the account's authorized apps. Open [Settings → Connections](/assistants/connections), find the TikTok connection, click **Fix** or **Edit**, then **Reconnect**. They should not. Welcome messages, suggested questions, and keyword replies configured in TikTok Business Suite are filtered out before your assistant sees them, so it never answers your own automation. If you do see one, report it to support with the conversation link. ## Next Steps See the universal connection flow that every channel uses Manage every authenticated link, including TikTok, in one place See everything your assistant can send and receive Capture referrals from TikTok ads, shared posts, and short links on every conversation # WhatsApp Business Source: https://docs.useinvent.com/assistants/channels/whatsapp Connect a WhatsApp Business phone number to your assistant and reply to chats automatically, with or without keeping your existing WhatsApp Business app New to channels? Start with the [Channels Overview](/assistants/channels) to see the universal connect flow that every channel shares. This guide walks through the WhatsApp-specific screens on top of that flow. Connecting WhatsApp puts your assistant on the most important messaging channel for most businesses. Anyone who taps a WhatsApp click-to-chat ad, opens a `wa.me` link, scans a QR code on your storefront, or just messages your number directly lands in a conversation that your assistant answers instantly, 24/7. Everything appears in the same [Inbox](/guides/inbox) as your other channels, with the same assistant, the same [Knowledge](/guides/knowledge), and the same [Memory](/guides/memory). This guide is longer than the other channel guides on purpose. WhatsApp is the only channel where you have to make a structural decision (Coexistence vs API-only) before Meta's signup flow opens, and the rest of the steps look completely different from there. If you have not connected WhatsApp before, read [How a WhatsApp connection is structured](#how-a-whatsapp-connection-is-structured) and [Pick your connection path](#pick-your-connection-path) first, then jump into the steps. ## How a WhatsApp connection is structured Before you click anywhere, four Meta concepts you will see throughout the flow: * **Meta Business Portfolio** (formerly Business Manager). The top-level container for your company on Meta. It owns Pages, ad accounts, and WhatsApp accounts. Think of it as your company's main folder. * **WhatsApp Business Account (WABA)**. The cloud container that holds one or more phone numbers connected to the WhatsApp Cloud API. This is the "engine" that lets your assistant send and receive on a number. One Business Portfolio can hold multiple WABAs. * **Phone Number**. The actual line customers message. One WABA can hold multiple phone numbers, each with its own display name and profile. * **WhatsApp Business app**. Meta's mobile app for small businesses, separate from the personal WhatsApp app. Coexistence requires a number that is already active on this app, not the personal app. The nesting is always **Business Portfolio → WhatsApp Business Account → Phone Number**. When you see a dropdown labeled "Business portfolio" pre-filled with something like *Acme Primary*, that is your existing portfolio (Meta detected it from your Facebook account). You can pick it, or create a new one in the same dropdown. ## Pick your connection path There are two ways to connect a number. You pick one in the WhatsApp connect dialog, and Invent opens Meta's Embedded Signup on that path: ### Coexistence: Keep using the WhatsApp Business app `Recommended for most businesses` Keep using the **WhatsApp Business app** on your phone alongside Invent. Your team can still reply manually from the app, and your assistant answers automatically through the API. Up to 6 months of past chat history syncs to Invent so the assistant has context from day one. Pick this when: * The number is already in active use on the WhatsApp Business app and you want to keep that workflow. * You want manual replies (from the app) and automated replies (from the assistant) on the same number. * You want existing chat history available to the assistant immediately. ### API-only: Connect a new number A dedicated, "bot-only" line that lives entirely on the WhatsApp Cloud API. No mobile app, no manual replies through the app. All conversations happen in the Invent Inbox. Pick this when: * You are setting up a brand-new number purely for automation. * You do not need the WhatsApp Business app at all. * You want a high-volume support or sales line with no per-device dependency. ### What if my number is already on another tool? If the number is already registered somewhere else, on a personal WhatsApp account, on the WhatsApp Business app, or with another BSP / Cloud API instance, Meta will block both Coexistence and API-only with a *"this phone number is already registered"* error. The release flow lives outside Invent and depends on where the number currently lives. Skip to [If Meta says "this phone number is already registered"](#if-meta-says-this-phone-number-is-already-registered) below, run the release flow that matches your situation, and then come back to Coexistence or API-only. ### At a glance | | **Coexistence** | **API-only** | | ------------------ | --------------------------------------------------------- | ---------------------------------- | | **Use case** | Keep mobile app, add the assistant alongside | Bot-only / brand-new number | | **Number must be** | Active on the **WhatsApp Business app** | Not in use on any WhatsApp account | | **Chat history** | Last 6 months sync | Starts fresh | | **Manual replies** | Yes (from the WhatsApp Business app and the Invent Inbox) | Yes (from the Invent Inbox only) | | **Verification** | QR code or 6-digit access code from inside the app | SMS or phone call to the number | | **Maintenance** | Open the app at least every **14 days** | None | | **Group chats** | Stay in the app, do not sync | N/A (no app) | | **Status updates** | Stay in the app, do not sync | N/A (no app) | When in doubt, pick **Coexistence**. It is reversible (you can migrate to API-only later from WhatsApp Manager) and it preserves your team's existing manual workflow on day one. ## Before You Start You need: 1. **A Facebook account** that is an admin on (or can create) the Business Portfolio you want to use. The signup flow uses Facebook for authentication; your password is only entered on `facebook.com`. 2. **A phone number**, in one of these states depending on your path: * **Coexistence**: the number must already be registered on the **WhatsApp Business app** on a phone you have access to. Personal-WhatsApp numbers will not work. * **API-only**: the number must **not** be in active use on any WhatsApp account, and it must be able to receive an SMS or a phone call for verification. Landline or toll-free numbers must use the phone-call option. 3. **For coexistence only**: physical access to the phone with the WhatsApp Business app installed, so you can scan the QR code or enter the access code Meta shows during setup. 4. **(If reusing a number that is registered somewhere else)**: admin access wherever the number currently lives. For another BSP or Cloud API instance, that means admin access on the Meta Business Portfolio that owns the WABA. For a number on the WhatsApp Business app or personal WhatsApp, that means physical access to the phone. Covered in [If Meta says "this phone number is already registered"](#if-meta-says-this-phone-number-is-already-registered). **Coexistence does not work on personal WhatsApp.** If your number is on the regular WhatsApp app (the green icon, not the WhatsApp Business app), you have two choices: install the WhatsApp Business app and migrate the number into it first, or use API-only with a different number. ## Step 1: Open the WhatsApp Connect Dialog From your assistant's **Channels** tab, find **WhatsApp Business** in the list and click **Connect**. The WhatsApp connect dialog opens. Empty WhatsApp Business connect dialog with a + Connect WhatsApp button inside the Connection field The dialog has two fields: * **Connection**: the authenticated link to your Meta Business Portfolio and WhatsApp Business Account. If this is your first WhatsApp connection, the dropdown is empty apart from a blue **+ Connect WhatsApp** button you use to start the embedded signup (covered in the next steps). If you have already connected WhatsApp for another assistant, your existing connections are listed here and you can reuse any of them, in which case you can skip to [Step 4](#step-4-name-the-connection-in-invent). * **WhatsApp Phone Number**: the specific number on that connection that this assistant should send and receive on. Disabled with *Requires Connection* until a connection is selected, then populated automatically with every number Invent has access to under that connection. You can attach more than one WhatsApp connection to your workspace. After you add the first one, opening the **Connection** dropdown again shows all existing connections plus a **+ Connect WhatsApp** button at the top to add another. Pick whichever fits this assistant's use case. ## Step 2: Start the Embedded Signup Open the **Connection** dropdown and click **+ Connect WhatsApp**. The dialog asks which path you want, **Keep using the WhatsApp Business app** (Coexistence, selected by default) or **Connect a new number** (API-only). Pick one and click **Continue to WhatsApp**: Meta's Embedded Signup popup opens on that path, beginning with Facebook's standard login. Facebook login screen with email and password fields and a Log in button This is Facebook's standard sign-in, run entirely on `facebook.com`. Sign in with the Facebook account that is an admin on the Business Portfolio you want to use. Sign in with the **business owner's** Facebook account (or a permanent admin account), not a personal employee account that may leave the company later. Access to the connection follows whoever signed in: if that account is removed from the Business Portfolio or revokes the Invent integration, the connection breaks until it is re-authenticated. After login, Meta shows a one-screen onboarding intro that explains what the integration will do. Seamlessly connect your account intro screen explaining that the onboarding will register and connect a business account, with Cancel and Continue buttons Click **Continue** to proceed. ## Step 3: Choose Your Path This is the most important screen in the entire WhatsApp setup. Meta asks you to pick a Business portfolio and a WhatsApp Business account. Select the business assets to share with Invent screen with a Business portfolio dropdown and a WhatsApp Business account dropdown showing two options: Create a WhatsApp Business account and Connect a WhatsApp Business App The first dropdown, **Business portfolio**, is usually pre-filled with your existing portfolio (something like *Acme Primary*). Meta auto-detects it from the Facebook account you signed in with. Pick it, or open the dropdown to **Create a Business portfolio** if you do not have one yet or want to keep WhatsApp under a different one. The second dropdown, **WhatsApp Business account**, is where the path splits. Open it and you will see two options: * **Connect a WhatsApp Business App** → this is the **Coexistence** path. Pick this to keep your existing mobile-app number and add API access on top of it. Continue with [Path A](#path-a-coexistence-connect-your-whatsapp-business-app) below. * **Create a WhatsApp Business account** → this is the **API-only** path. Pick this to set up a fresh, bot-only number. Continue with [Path B](#path-b-api-only-create-a-new-whatsapp-business-account) below. The two options are different kinds of "account." Picking **Connect a WhatsApp Business App** links your existing app number to a *new* WABA created automatically inside your portfolio. Picking **Create a WhatsApp Business account** creates a fresh WABA from scratch with no app behind it. Either way you end up with a WABA inside your Business Portfolio, just reached two different ways. Pick the option you want, then click **Next**. ## Path A: Coexistence (Connect Your WhatsApp Business App) Use this path if you picked **Connect a WhatsApp Business App** in the previous step. Skip ahead to [Path B](#path-b-api-only-create-a-new-whatsapp-business-account) if you picked the other option. ### Step A1: Confirm or fill in business information Meta asks for the basic business information that will be attached to your assets. If your Business Portfolio already has these fields filled in, they are pre-populated; otherwise enter them now. Enter business information for new assets form with Name (Acme Inc.), Email (business@acme.com), Country (India), and Website (https://acme.com/) fields Click **Next**. ### Step A2: Enter your WhatsApp Business app number Pick your country code, then enter the phone number that is currently active on your WhatsApp Business app. Enter your WhatsApp Business phone number screen with country code IN +91 selected and an empty phone number field Once you enter a valid number, Meta shows an information panel summarizing what coexistence will do: Connect your existing WhatsApp Business App banner explaining sharing access with Invent, account information shared, and that individual chats will be managed using a secure service from Meta The three points are worth reading once: * **Connect your existing WhatsApp Business App**: you keep full access to the app and can continue using it as before. * **Sharing Access**: phone number, contacts, chats, and chat history may be shared with Invent. * **Protecting your data**: 1:1 chats are managed using a secure service from Meta. A short notice is sent to your customers explaining the privacy change the first time they message you. Click **Next**. ### Step A3: Get the QR code or access code Meta now generates a one-time QR code that you will scan from inside the WhatsApp Business app on your phone. Import contacts and chat history screen showing a QR code labeled Use the WhatsApp Business app to scan the QR code, with instructions to look for a message from the official Facebook Business Account and tap Connect Below the QR code (just out of view in the screenshot above) Meta also shows an option to display a **numeric access code** instead of the QR. Use it when scanning is awkward, for example when the camera on your phone is hard to point at your computer screen, you are setting things up over a video call, or you would simply rather type the code into the app. Once switched, you type the same code into the **Enter Access code** field on the phone (covered in [Step A6](#step-a6-scan-the-qr-code-or-paste-the-access-code)). Leave this screen open on your computer. You will scan or paste from the phone in the next step. ### Step A4: On your phone, open the Business Platform connection You have two ways into the connect screen on the WhatsApp Business app side: **Option 1 (recommended): tap the system message from Facebook Business.** When you reach the QR-code step on your computer, the WhatsApp Business app on your phone receives a chat from the verified **Facebook Business** account. Open it and you will see a **Manage messages** card with a **Connect** button. WhatsApp Business app showing a chat from the verified Facebook Business account with a Manage messages card and a Connect to the Business Platform message Tap the **Connect** link inside the message. **Option 2: open it from Settings.** Tap the **three dots** (or **Settings**), then **Account** → **Business Platform**, then **Connect to the Business Platform**. Either route lands you on the same screen, which explains what is about to happen: Connect to the Business Platform screen on the WhatsApp Business app explaining you can keep using the app, share up to 6 months of chat history, and that group chat history cannot be shared Tap **Connect to the Business Platform**. ### Step A5: Choose what chat history to share The app asks whether to share existing chat history with the assistant. Share chat history sheet with two options: Share all chats (continue chat with current customers) and Don't share chats (start a new chat thread with current customers) | Option | What it does | | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Share all chats** | The last 6 months of 1:1 chats sync to Invent and the assistant continues the same threads with your existing customers. Recommended for most businesses. | | **Don't share chats** | Existing customers start a fresh thread with the assistant. Older history stays only in the WhatsApp Business app and is invisible to Invent. Pick this if your previous conversations contain sensitive information you do not want surfaced to the assistant. | This decision is **permanent**. You cannot change which option you picked later without disconnecting and re-running the entire flow. Tap **Confirm**. ### Step A6: Scan the QR code (or paste the access code) The phone now opens its scanner. Hold the phone up to your computer screen and scan the QR code from [Step A3](#step-a3-get-the-qr-code-or-access-code). Scan QR code screen on the phone with a Connecting your account dialog overlay reading This could take up to 45 seconds, and an Enter Access Code Instead link at the bottom If scanning is awkward (low-light setup, two phones, accessibility), tap **Enter Access Code Instead** and type the 6-digit code shown next to the QR code on the computer. Enter Access code screen on the phone with a single text field and a Scan QR instead link The phone shows *Connecting your account. This could take up to 45 seconds.* When it succeeds, you see a confirmation screen with **Connected platform** and the partner's name (Zydeer, the underlying platform that powers Invent's WhatsApp integration): Connected platform page on the phone showing Zydeer with Meta account and WhatsApp account labels, a Tap to disconnect link, a note about being limited to one Business Platform at a time, and a reminder to open the app every 14 days to keep the connection active You can leave this page on the phone. The setup now continues on the computer side automatically. If your computer screen never advances after the phone shows **Connected platform**, you have hit the most common WhatsApp setup glitch. Solution: on the phone, tap **Tap to disconnect** on this exact screen, then re-run the connect flow in Invent from [Step 1](#step-1-open-the-whatsapp-connect-dialog). The second attempt almost always completes cleanly. Full details in [Troubleshooting](#troubleshooting). ### Step A7: Confirm the WhatsApp Business account name and timezone Back on the computer, Meta confirms the WhatsApp Business Account it just created or linked, and asks for a timezone. Confirm or edit your WhatsApp Business account screen with a WhatsApp Business account name field and a Timezone dropdown set to GMT+05:30 Asia/Calcutta The WABA name is internal-only (it does not show to customers; the customer-facing label is the **display name** on the number itself). Pick the right timezone for the team that owns this number, then click **Next**. ### Step A8: Review permissions and confirm Meta lists what Invent will be able to do on the WABA. Review what you'll share with Invent screen listing access to the WhatsApp Business account named Arshad Business and the permissions Manage your WhatsApp accounts, Manage and access conversations in WhatsApp, and Log events on your WhatsApp business account's behalf Invent requests the minimum set of permissions required to run a WhatsApp assistant: * **Manage your WhatsApp accounts**: list and bind the WABAs and phone numbers in your portfolio so the right one shows up in Invent's dropdown. * **Manage and access conversations in WhatsApp**: receive incoming messages and send replies on behalf of the number. This is the core capability that powers the assistant. * **Log events on your WhatsApp business account's behalf**: send Meta the analytics events (delivery, read receipts, broadcast metrics) that drive the [Inbox](/guides/inbox) and [Broadcasts](/guides/broadcasts/introduction) reports. Click **Confirm** to grant access. ### Step A9: Wait for the connection to finalize Meta shows a short *Connecting your account* spinner while it finalizes the binding. Connecting your account screen with a spinner and the text This may take a few moments When it finishes, you see the success screen. Your account is connected to Zydeer success screen with an Add payment method button and a Finish button Click **Finish**. Coexistence numbers do not require a payment method to start receiving and sending messages, so you can ignore **Add payment method** for now and revisit it from WhatsApp Manager when you start sending volume. Now skip ahead to [Step 4: Name the Connection in Invent](#step-4-name-the-connection-in-invent). ## Path B: API-only (Create a New WhatsApp Business Account) Use this path if you picked **Create a WhatsApp Business account** at [Step 3](#step-3-choose-your-path). Skip back to [Path A](#path-a-coexistence-connect-your-whatsapp-business-app) if you picked the other option. ### Step B1: Enter business information Meta asks for business details that will be attached to the new WhatsApp Business Account. Compared to coexistence, this form has an extra **Category** field because you are creating a fresh WABA. Enter business information for new assets form with Name (Acme Business), Email (business@acme.com), Category (Beauty, Spa and Salon), Country (India), Website (https://acme.com/), and Time zone (GMT+05:30 Asia/Kolkata) fields Pick the category that best describes the business that owns the number. The category is used by Meta for moderation and discovery; it does not affect what the assistant can do. Click **Next**. ### Step B2: Add the phone number, display name, and verification method This is the screen where you commit a brand-new number to the API. Add your WhatsApp phone number form with Phone number country code IN +91 and empty number field, WhatsApp Business display name set to Acme Business, and a Choose how you would like to verify your number radio with Text message and Phone call options Three things to fill in: | Field | Notes | | ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Phone number** | The number you want customers to message. It must **not** be in active use on any WhatsApp account (personal or Business app). If it is, Meta blocks this step with the *already registered* error; jump to [If Meta says "this phone number is already registered"](#if-meta-says-this-phone-number-is-already-registered) for the fix. | | **WhatsApp Business display name** | The name that appears at the top of the chat for customers. Meta moderates display names for accuracy and brand misuse. Use your real business name, no all-caps, no emojis. See Meta's [display name guidelines](https://www.facebook.com/business/help/757569725593362). | | **Verification method** | **Text message** for any mobile number that can receive SMS. **Phone call** for landlines, toll-free numbers, or any number where SMS is unreliable. | Picking a number that is in use on the standard WhatsApp app or the WhatsApp Business app on this path will **wipe** that account from the device when verification completes. If you want to keep the mobile app, do not use API-only for that number; use [Coexistence](#path-a-coexistence-connect-your-whatsapp-business-app) instead. Click **Next**. ### Step B3: Verify with the 6-digit code Meta sends a 6-digit code to the number using the method you picked. Verify your phone number screen with six empty digit boxes for the verification code and a countdown showing Did not receive a code? You can request a new one and change your verification method in 56 seconds Enter the code and click **Next**. If it never arrives, wait for the countdown to finish, then use the option Meta shows to request a new code or switch delivery method (SMS to call, or call to SMS). ### Step B4: Review permissions and confirm Meta shows the same permissions screen as coexistence, listing what Invent will be able to do on the new WABA. Review what you'll share with Invent screen with the same WhatsApp account permissions list Click **Confirm**. ### Step B5: Wait for the connection to finalize You see the same *Connecting your account* spinner. Connecting your account spinner screen When it finishes, the success screen lists the assets that were created. Your account is connected to Zydeer screen listing Acme Business as the Business asset and Acme Business as the WhatsApp Account, plus an Improve your experience section and Add payment method and Finish buttons Click **Finish**. **API-only numbers may show as Pending until business verification completes.** Meta requires Business Verification on the parent Business Portfolio before a brand-new WABA can send marketing templates at scale. Inbound messages and 1:1 customer service replies still work during the Pending period; only [Broadcasts](/guides/broadcasts/introduction) and high-volume outbound are gated. Complete verification from [WhatsApp Manager](https://business.facebook.com/wa/manage/) when prompted. ## Step 4: Name the Connection in Invent Whichever path you took, Meta now redirects you back to Invent and prompts you to label the new connection (for example, *Acme Business* or *EU Sales WhatsApp*). WhatsApp connection name dialog inside Invent with the optional Connection Name field filled in as Acme Business and a Create Connection button This is the name you will see inside Invent. It does not change anything on Meta's side. Click **Create Connection** and Invent stores the connection in [Settings → Connections](/workspace-management/connections), where you can rename it or disconnect it at any time. Pick a name that describes *which numbers this connection covers*, not who signed in. *Acme WhatsApp* or *EU Sales WhatsApp* reads better in the channel list a year from now than *Alice's Facebook*. ## Step 5: Pick the Number and Connect Channel Back on the WhatsApp connect dialog, your new connection is already selected. The **WhatsApp Phone Number** dropdown now lists every number that connection has access to. WhatsApp Business dialog with the Acme Business connection selected, the WhatsApp Phone Number dropdown open and showing +91 89446 54177 (Acme Business) with Status: Connected Each option shows the phone number, a label, and its current status: * **Connected**: ready to send and receive immediately. This is the normal state for coexistence numbers and for verified API-only numbers. * **Pending**: Meta is still finalizing the WABA. Inbound messages still work; high-volume outbound (Broadcasts) is gated until Meta clears it. This is normal for new API-only numbers in the first hour or two. Pick the number this assistant should own. **One number, one assistant.** A WhatsApp number can only be bound to **one** assistant at a time inside Invent. If two assistants need to share the same number, [AI routing](/assistants/routing) is usually a better pattern than splitting the number. Binding a number that is already attached to another Invent assistant overrides the previous binding and the new assistant takes over from the next message onwards. Click **Connect Channel**. Behind the scenes Invent subscribes its webhook to the number, validates that the messaging permissions are healthy, and turns the channel on. WhatsApp now shows up in the assistant's Channels tab with an **Enabled** toggle, a **Manage** button, and the connected phone number as its identifier. ## Step 6: Send a Test Message Open WhatsApp on your personal device, message the connected number directly (or open `wa.me/` from a browser to deep-link into the chat), and send a message. You should see your assistant reply within a few seconds. The conversation also appears in your [Inbox](/guides/inbox) immediately, with the originating number and the WhatsApp channel shown on the conversation. That is it, the assistant is live on WhatsApp. ## The 14-Day Rule (Coexistence Only) **For coexistence numbers, you must open the WhatsApp Business app on the registered phone at least once every 14 days.** If 14 days pass without the app opening on the phone, Meta automatically severs the API connection and your assistant stops replying until you re-link. This is a Meta platform rule, not an Invent limitation. The reason is straightforward: coexistence is a shared-control mode, and Meta uses the periodic app open as a signal that the number is still legitimately operated by the original owner. Without that signal, the API binding is treated as orphaned and revoked. In practice, for any business with active staff using the app, this is invisible. The risk shows up when: * The phone the number is registered on is sitting in a drawer. * The original owner left the company and nobody is opening the app anymore. * The number is purely receiving and the team replies exclusively from the Invent Inbox, never from the app. Two ways to handle it: * **Have someone open the app every couple of weeks.** Even briefly counts. Set a recurring calendar reminder if your team is light. * **Migrate to API-only.** If nobody actually needs the mobile app, the 14-day rule is pure overhead. Open [WhatsApp Manager](https://business.facebook.com/wa/manage/), find the number, and migrate it from coexistence to API-only. After migration the number stops requiring the periodic app open. If the rule has already triggered and your assistant has stopped replying, just rerun the connect flow from [Step 1](#step-1-open-the-whatsapp-connect-dialog). Meta will issue a fresh QR code and the previous binding is replaced. ## What Syncs and What Stays in the App (Coexistence) When a number is on coexistence, Meta splits message types between the app and the API. Knowing which is which avoids surprises in the [Inbox](/guides/inbox). | Message type | Where it lives | Visible in Invent Inbox? | | -------------------------------------------------------------- | ------------------------ | ----------------------------------------------------------------------------- | | **1:1 chats with customers** | Both the app and the API | Yes. Manual replies sent from the app appear in the Inbox after a short delay | | **Up to 6 months of past 1:1 history** (if you opted to share) | Backfilled into the API | Yes, on first sync | | **Group chats** | App only | No. Group conversations stay in the app and are not surfaced to the assistant | | **Status (Stories) replies** | App only | No. Status replies are not part of the API surface | | **Broadcasts and outbound templates** | API only | Yes, sent from [Broadcasts](/guides/broadcasts/introduction) | If you need group-chat support, transfer those conversations to a 1:1 thread with the relevant customer, or handle them manually in the app. ## If Meta says "this phone number is already registered" This error fires whenever the number you typed in is **already in use somewhere else on WhatsApp**. It can show up on either path: Coexistence and API-only both go through Meta's number verification, and Meta blocks both with the same inline message: Inline error reading This phone number is already registered to a WhatsApp account. To continue, migrate this phone number or disconnect it from the existing account. Then return to this page and try again. It can take up to 3 minutes for the number to refresh. There are three places a phone number can already live. Pick the one that matches yours, run the release flow, then come back and re-run [Path A](#path-a-coexistence-connect-your-whatsapp-business-app) or [Path B](#path-b-api-only-create-a-new-whatsapp-business-account) in Invent. ### A. The number is on a regular WhatsApp account (the green app) The number is in active use on the personal WhatsApp app on someone's phone. Coexistence does not work for personal WhatsApp, so the only way to reuse the number is to delete the personal account first, then run [Path B](#path-b-api-only-create-a-new-whatsapp-business-account). On the phone, open WhatsApp → Settings → **Chats** → **Chat backup**, and back up to iCloud or Google Drive. Deletion is irreversible and the backup is your only path to retrieve the chats later. Open the WhatsApp app → **Settings** → **Account** → **Delete my account**. Enter the country code and the full phone number to confirm, then follow the prompts. Meta caches the registration for up to **3 minutes** after deletion. Until that cache expires, retrying the Invent flow can still resurface the *already registered* error. Go back to your assistant's **Channels** tab and run [Path B](#path-b-api-only-create-a-new-whatsapp-business-account). Personal-WhatsApp numbers cannot use Coexistence; they only work on API-only. ### B. The number is on the WhatsApp Business app The number is registered on the **WhatsApp Business** app (the dark-green icon, not the personal one). You have two ways forward: * **Best option for most teams: switch to Coexistence.** If you originally picked *Create a WhatsApp Business account* at [Step 3](#step-3-choose-your-path) and hit this error, the cleanest fix is usually to go back and pick *Connect a WhatsApp Business App* instead. Coexistence is built exactly for this case: it links your existing WhatsApp Business app number to a WABA without you having to delete anything, and it preserves the last 6 months of chat history. Run [Path A](#path-a-coexistence-connect-your-whatsapp-business-app) instead of Path B. * **API-only by deletion.** If you genuinely do not want the WhatsApp Business app on this number anymore (purely automated, no manual mobile replies), open the **WhatsApp Business** app on the registered phone, go to **Settings → Account → Delete my account**, enter the number to confirm, and follow the prompts. Wait up to **3 minutes**, then re-run [Path B](#path-b-api-only-create-a-new-whatsapp-business-account). **Deleting the WhatsApp Business app account erases all chats, media, and backups on that device permanently.** If you have history you care about, choose Coexistence instead and let Meta sync up to 6 months of past chats into Invent automatically. Backing up from inside the app (Settings → Chats → Chat backup) preserves a copy you can restore later, but only into the same WhatsApp Business app on the same number. ### C. The number is on another BSP or Cloud API instance The number is currently bound to a different platform's webhook (Twilio, Wati, 360dialog, MessageBird, an old in-house integration, or another Invent workspace). Only one BSP can hold the active webhook on a number at a time, so you have to release it from that platform first. Go to [business.facebook.com](https://business.facebook.com) and sign in with the Facebook account that has admin access on the Business Portfolio that owns the WABA. If you do not have admin access, ask whoever does to run this flow. In the left sidebar open **Settings → Accounts → WhatsApp accounts**, then click the WhatsApp Business Account that holds the number you want to move. Switch to the **Partners** tab. You will see every Business Solution Provider that currently has access to this WABA (sometimes labeled by the vendor's product name, sometimes by their parent company). Click **Manage** next to the BSP you want to remove, then click **Remove access** in the dialog Meta opens. If the partner is unfamiliar (you inherited the WABA, the previous vendor was renamed, or the original setup is undocumented), the master list of business integrations attached to your portfolio is at [facebook.com/settings/business\_integrations](https://www.facebook.com/settings/business_integrations); revoke any extra entries from there too. If the previous BSP was running on **Coexistence**, the connection also has a phone-side half. On the registered phone, open the **WhatsApp Business** app → **Settings → Account → Business platform**, tap the partner you just removed, and tap **Disconnect**. Numbers that were on a pure API-only BSP have no app-side connection to remove and you can skip this step. Meta will not let you re-register a number with 2FA still active. Open [WhatsApp Manager](https://business.facebook.com/wa/manage/), pick the WABA, go to **Account tools → Phone numbers**, click the **gear icon** next to the row, switch to the **Two-step verification** tab, and turn it off. If your previous BSP set the PIN and you do not know it, you may need to contact them to disable 2FA on their side first. If the previous BSP charged a monthly fee for the number (360dialog, Wati, Twilio, and similar), cancel that subscription on their side. Removing access in Meta Business Suite stops the webhook routing but does not always cancel the billing relationship; that has to happen in the BSP's own dashboard. Meta caches the BSP binding for up to **3 minutes** after revocation. Click **+ Connect WhatsApp** too quickly and you can still see the same error even though the release went through. Wait three minutes, then run [Path A](#path-a-coexistence-connect-your-whatsapp-business-app) or [Path B](#path-b-api-only-create-a-new-whatsapp-business-account) as appropriate. **Migration is also an option, but it is more complex.** Meta supports a formal phone-number migration flow that preserves display name, quality rating, message templates, Official Business Account status, and messaging limits across BSPs, but only when both source and destination WABAs sit under the same Meta Business Portfolio. See Meta's [migration documentation](https://developers.facebook.com/docs/whatsapp/cloud-api/get-started/migrate-existing-whatsapp-number-to-a-business-account/) for the full prerequisites. Most teams just release-and-re-register, which is the flow above. If the previous platform stored chat history that you want preserved, export it from that platform **before** revoking access. Once the binding is severed, the API-side history on the previous BSP becomes inaccessible. Coexistence on the Invent side will sync any 1:1 history that is still on the WhatsApp Business app, but the API-side archive on the previous BSP will not transfer. ## Connecting More Numbers You can add additional WhatsApp numbers to the same assistant at any time. From the Channels tab, click **+ Add another** under the WhatsApp section and either: * **Pick another number from the same connection** (when your existing connection's WABA already has more than one number registered), or * **Connect a new number** by opening the Connection dropdown and choosing **+ Connect WhatsApp** again. Run [Path A](#path-a-coexistence-connect-your-whatsapp-business-app) or [Path B](#path-b-api-only-create-a-new-whatsapp-business-account) for the new number, or [release it](#if-meta-says-this-phone-number-is-already-registered) first if it is already registered somewhere else. Each number runs in parallel under the same assistant, sharing the same Instructions, Knowledge, Memory, and Actions. Conversations are tagged with the originating number in the Inbox so your team always knows which brand or region a message belongs to. See [Multiple Connections Per Channel](/assistants/channels#multiple-connections-per-channel) for common patterns. ## Reusing a Connection Across Assistants Once a WhatsApp connection exists in your workspace, any assistant can pick it up from the **Connection** dropdown without going through Meta's Embedded Signup again. Authenticate once, reuse everywhere. Manage every connection centrally from [Settings → Connections](/workspace-management/connections): * **Rename** a connection to keep the list readable as you add more. * **Reconnect** if Meta's session expires, an admin removes the integration from `facebook.com/settings/business_integrations`, or the underlying Business Portfolio is reorganized. * **Disconnect** to remove the link entirely. Any assistant still using that connection stops sending and receiving until it is pointed at a new one. ## Troubleshooting Hit a numeric error code when sending (something like `130497` or `131047`)? See the [WhatsApp error codes reference](/assistants/channels/whatsapp-error-codes) for every Cloud API code explained with its fix. This is the most common WhatsApp setup glitch. The phone-side binding completed, but the web-side handshake silently dropped (often because the popup lost focus, the browser tab was switched, or the network blipped during the 45-second window). **Fix:** 1. On the phone, open the WhatsApp Business app, go to **Settings → Account → Business Platform**. 2. You will see the **Connected platform** card with **Tap to disconnect** at the bottom. 3. Tap **Tap to disconnect** and confirm. 4. Close the Invent setup popup if it is still open. 5. Re-run the connect flow in Invent from [Step 1](#step-1-open-the-whatsapp-connect-dialog). The second attempt almost always completes cleanly because the previous half-bound state is now cleared. The number is registered somewhere else: on a personal WhatsApp account, on the WhatsApp Business app, or with another BSP. The fix depends on which one. Jump to [If Meta says "this phone number is already registered"](#if-meta-says-this-phone-number-is-already-registered) and run the sub-flow that matches your case (A, B, or C). The same error also fires when you pick API-only for a number that is currently on the WhatsApp Business app, in which case [Coexistence](#path-a-coexistence-connect-your-whatsapp-business-app) is usually the better fix because it does not delete your app history. This is a Meta-side restriction on **cross-country messaging**, not a problem with your connection or your number. Meta blocks business-initiated messages that cross a border into **Brazil (BR)** or **Indonesia (ID)**. Your message fails to send and the API returns error code **130497**. The rule, in one line: a business can only message recipients in Brazil or Indonesia if its own WhatsApp Business account is registered in that same country. | Your WhatsApp Business account is in | You message a user in | Result | | ----------------------------------------------- | -------------------------------- | ------------------ | | Any country (for example the US, Spain, Mexico) | Brazil | ❌ Blocked (130497) | | Any country (for example the US, Spain, Mexico) | Indonesia | ❌ Blocked (130497) | | Brazil | Brazil | ✅ Works | | Brazil | Any country other than Brazil | ❌ Blocked (130497) | | Indonesia | Indonesia | ✅ Works | | Indonesia | Any country other than Indonesia | ❌ Blocked (130497) | | Any other country | Any other country | ✅ Works | Receiving messages is never affected. Users in Brazil and Indonesia can still message your business, and you can reply within the [customer service window](/assistants/channels/whatsapp). Only business-initiated sends (the first message, and template / broadcast sends) hit this restriction. **What you can do:** * **Confirm it is the cross-country rule.** If the recipient is in Brazil or Indonesia and your account is registered elsewhere, this is expected and there is no override. * **Register a local WhatsApp Business account.** To message users inside Brazil or Indonesia, the only reliable path is a separate WABA whose business is registered in that country. Run [Path B (API-only)](#path-b-api-only-create-a-new-whatsapp-business-account) for a locally-registered business. * **Keep your Business Manager profile complete.** A missing business address or incomplete profile on the Business Portfolio, WABA, or linked Facebook Page can widen the restriction. Fill these in at [WhatsApp Manager](https://business.facebook.com/wa/manage/). * **Watch for policy changes.** Meta has described this as a temporary measure. The affected-country list can change, so check Meta's announcements before assuming it is permanent. Two common causes: 1. The Embedded Signup popup closed before the success screen. Nothing is saved until Meta shows *Your account is connected to Zydeer*. Re-run [Step 1](#step-1-open-the-whatsapp-connect-dialog). 2. The number is in a different WABA on the same Business Portfolio that Invent did not pick up. Open [Settings → Connections](/workspace-management/connections), click **Reconnect** on the WhatsApp connection, and finish the prompt. The dropdown refreshes with every visible number. Three things to check: 1. **Wait for the 60-second countdown to finish**, then use the option Meta shows on the verify-code screen to request a new code or switch delivery method (SMS to call, or call to SMS). Some carriers silently drop SMS from short codes; voice calls usually go through. 2. **Use Phone call for landlines and toll-free numbers.** SMS does not exist for landlines. 3. **Check the number you typed has the right country code**, including for numbers that locally drop the leading zero. Meta uses the international format. If a third attempt fails, the number may be ineligible (some virtual or premium-rate numbers cannot host WABAs). Try a different number, or contact Meta support from [WhatsApp Manager](https://business.facebook.com/wa/manage/). Meta moderates display names to prevent brand impersonation, generic names, and misleading branding. Common rejection reasons: * All caps (use *Acme Support*, not *ACME SUPPORT*). * Emojis or special characters. * Generic terms like *Support*, *Sales*, *Customer Service* without the business name attached. * A brand the Facebook account is not authorized to represent. Read Meta's [display name guidelines](https://www.facebook.com/business/help/757569725593362), pick a name that matches your real business name closely, and resubmit from [WhatsApp Manager → Phone numbers](https://business.facebook.com/wa/manage/phone-numbers/). Because Meta auto-detected an existing Business Portfolio you are an admin on, based on your Facebook account. *Acme Primary* (or whatever name yours has) is your **portfolio**, not a WABA yet. The portfolio is the parent container; the WABA gets created or linked inside it on the next screen. If the pre-selected portfolio is the right one, leave it. If you want a separate portfolio for this WhatsApp setup, open the dropdown and pick **Create a Business portfolio**. The two options in the *WhatsApp Business account* dropdown below (*Create a WhatsApp Business account* and *Connect a WhatsApp Business App*) operate within whichever portfolio is selected here. They produce two structurally different setups, even though both end up with a WABA inside your portfolio. Quick recap: | | **Connect a WhatsApp Business App** | **Create a WhatsApp Business account** | | ----------------------- | ------------------------------------ | -------------------------------------- | | Path name | Coexistence | API-only | | Number must be | Active on the WhatsApp Business app | Not on any WhatsApp account | | Verification | QR / access code from inside the app | SMS or phone call | | Mobile app stays usable | Yes | No | | Existing chat history | Up to 6 months sync | Starts fresh | | Maintenance | Open the app every 14 days | None | See [Pick your connection path](#pick-your-connection-path) for the full comparison. The 14-day rule has triggered. The WhatsApp Business app on the registered phone has not been opened recently, and Meta severed the API binding as a result. Re-run the connect flow from [Step 1](#step-1-open-the-whatsapp-connect-dialog); Meta will issue a fresh QR code and you will be back in service in about a minute. To prevent it from happening again, set a recurring reminder for someone on your team to open the app at least every two weeks, or migrate the number to API-only from [WhatsApp Manager](https://business.facebook.com/wa/manage/). Full context in [The 14-Day Rule](#the-14-day-rule-coexistence-only). Expected behavior on coexistence. Meta's API only surfaces 1:1 chats; group conversations and Status replies stay inside the WhatsApp Business app and are not visible to the assistant. Handle group conversations manually in the app, or invite the relevant customer into a 1:1 thread that the assistant can see. Full breakdown in [What Syncs and What Stays in the App](#what-syncs-and-what-stays-in-the-app-coexistence). No. Meta only allows one BSP webhook per number at a time. The most recent platform to bind the number wins, and the previous one immediately stops receiving messages. If you need redundancy or a parallel setup, use a second WhatsApp number; if you are evaluating Invent against another platform, use a sandbox number for the comparison and keep production on the existing platform until you decide. WhatsApp blocks free-form business-initiated messages outside the 24-hour customer-service window. To re-engage a customer who went quiet for longer than that, your message must use an **approved WhatsApp Template**. Send tagged outbound at scale through [Broadcasts → WhatsApp](/guides/broadcasts/channels/whatsapp), and rely on [Auto Follow-ups](/guides/auto-follow-ups) for in-window re-engagement. Open [WhatsApp Manager](https://business.facebook.com/wa/manage/phone-numbers/), find the number, and start the migration to Cloud API. Meta walks you through detaching the WhatsApp Business app from the number; the app will stop working on that number once migration completes. After migration finishes, run the Invent connect flow again as if the number were brand-new (it now matches [Path B](#path-b-api-only-create-a-new-whatsapp-business-account)). Existing 1:1 history that already synced through coexistence stays available in the Inbox; new history begins immediately on the API side. ## Next Steps See the universal connection flow that every channel uses Manage every authenticated link, including WhatsApp, in one place See everything your assistant can send and receive on WhatsApp Send approved Template messages to your audience at scale # WhatsApp error codes Source: https://docs.useinvent.com/assistants/channels/whatsapp-error-codes Every WhatsApp Cloud API error code explained in plain language, with what it means and how to fix it. Covers send failures, rate limits, template rejections, the 130497 country restriction, and more. When a WhatsApp message, template, or broadcast fails, Meta returns a numeric **error code**. The same codes show up across the whole WhatsApp Business Platform, so they look identical whether the message was sent by Invent, by another tool, or directly through Meta's Cloud API. This page explains what each code means and what to do about it, framed for what you actually see inside Invent. You almost never need to handle these codes by hand. Invent surfaces the failure reason on the affected chat or broadcast recipient. This page is for understanding *why* a send failed and what to change so the next one succeeds. ## How WhatsApp reports errors Meta's Cloud API is built on the Graph API, so every error follows the same shape: ```json theme={"system"} { "error": { "message": "(#130429) Rate limit hit", "type": "OAuthException", "code": 130429, "error_data": { "messaging_product": "whatsapp", "details": "Cloud API message throughput has been reached." }, "fbtrace_id": "Az8or2yhqkZfEZ-_4Qn_Bam" } } ``` A few things worth knowing: * **The `code` is what matters.** Build your understanding around the numeric `code` and the `details` text. The human-readable title inside `message` (for example *Rate limit hit*) is informational and Meta plans to deprecate titles eventually. * **Errors arrive two ways.** Some come back immediately as the API response when a send is rejected outright. Others arrive later through a webhook, when a message was accepted but then failed to deliver (the recipient blocked you, their number is not on WhatsApp, and so on). Invent listens to both and attaches the reason to the chat or broadcast recipient. * **`fbtrace_id` is your support ticket key.** If you ever escalate to Meta Direct Support, include this value. It lets them find the exact request. ## Codes you'll most likely see These are the handful that come up in normal day-to-day use of WhatsApp in Invent. A Meta-side restriction on **cross-country messaging**, not a problem with your connection. Business-initiated messages that cross a border into **Brazil (BR)** or **Indonesia (ID)** are blocked. Same-country messaging (Brazil to Brazil, Indonesia to Indonesia) still works, and **inbound messages are never affected**. The only reliable way to message users inside those countries is a WhatsApp Business account whose business is registered locally there. Full table and details in the channel guide: [Business account is restricted from messaging users in this country](/assistants/channels/whatsapp#troubleshooting). WhatsApp only lets you send free-form messages inside a **24-hour customer service window** that opens each time the user messages you. Once 24 hours pass with no reply from them, free-form text is blocked and you must use an **approved template message** to re-open the conversation. In Invent this is the most common reason an assistant reply silently fails on an older chat. Send a template, or wait for the user to message again. The message could not be delivered. Common reasons: the recipient's number is **not a WhatsApp number**, they have not accepted WhatsApp's latest Terms of Service, or they are on a very old WhatsApp version. Confirm the number is correct and actually on WhatsApp. There is nothing to fix on your side if the recipient simply does not use WhatsApp. This user chose to stop receiving **marketing** template messages from your business on WhatsApp. **Do not retry**, the message will never be delivered. You can still send utility and authentication templates, and you can still reply inside the 24-hour window. Respect the opt-out. Meta throttled a marketing template to this specific user to protect engagement quality (the per-user marketing limit). Wait at least 24 hours before resending. Retrying sooner just produces the same error. You sent too many messages from your number to the **same** recipient in a short window. Wait and retry for that contact. You can keep messaging *other* numbers normally, so this rarely affects a broadcast as a whole. The template name or language locale is wrong, or the template has not been approved yet. Check the exact template name and language in WhatsApp Manager, and confirm its status is **Approved** before sending. Newly created templates can take a few minutes to become sendable. The template was rejected on review for a policy reason. Read Meta's template review guidance, edit the content to comply, and resubmit. Until it is approved again it cannot be sent. `132015` means the template was **paused** because recipients reacted poorly (blocks, reports, low read rates). Improve the content and it can be re-enabled once approved. `132016` means it was paused too many times and is now **permanently disabled**. Create a fresh template with better content. These all mean *slow down or improve quality*, but for different reasons: * **80007**: your WhatsApp Business account hit its messaging rate limit. Retry later or send less frequently. * **130429**: Cloud API throughput limit reached. Same fix: spread sends out over time. * **131048**: sends are restricted because too many earlier messages were blocked or flagged as spam. Check your quality rating in WhatsApp Manager. * **131064**: messaging limit reached due to template classification violations. Make sure your templates are categorized correctly (marketing vs utility vs authentication). **190** means the access token behind the connection has expired. In Invent, reconnect the WhatsApp connection from [Settings → Connections](/workspace-management/connections) to refresh it. **368** means the whole WhatsApp Business Account has been **restricted or disabled for a policy violation**. This is serious: review Meta's Policy Enforcement page and resolve the violation in WhatsApp Manager. No message will send until the account is reinstated. Something is wrong with billing on the WhatsApp Business account: no payment method attached, credit line over its limit or inactive, currency or timezone not set, or the account is suspended. Fix billing in WhatsApp Manager and try again. On a **prepaid** account (India, funded with UPI top-ups) the send can be accepted first and fail with this code a moment later, once the balance check runs. The recipient then shows as failed instead of rejected up front. Top up the balance in WhatsApp Manager and resend. Your business blocked this WhatsApp user, so the message cannot be delivered. **Do not retry.** Unblock them first if you want to resume messaging. ## Full error code reference Every code from Meta's [Cloud API error reference](https://developers.facebook.com/docs/whatsapp/cloud-api/support/error-codes/), grouped the way Meta groups them. The common ones above are repeated here for completeness. ### Authorization errors These mean the request was not allowed to run at all, usually a token or permission problem. In Invent the fix is almost always to **reconnect** the WhatsApp connection. | Code | What it means | What to do | | ----------- | ----------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------- | | `0` | Could not authenticate the app user. The access token expired, was invalidated, or a setting blocks access. | Reconnect WhatsApp to get a fresh token. | | `3` | A capability or permission is missing for this request. | Confirm the connection was authorized with all required permissions; reconnect if needed. | | `10` | A required permission was never granted or has been removed. | Re-run the connect flow and grant all requested permissions. Check you are eligible for the endpoint being used. | | `190` | The access token has expired. | Reconnect WhatsApp from [Settings → Connections](/workspace-management/connections). | | `200` | No access token was provided on a request that requires one. | Reconnect WhatsApp. (Distinct from `190`, which is an expired token.) | | `200`–`299` | A permission is not granted or was removed. | Re-authorize the connection with the required permissions. | ### Integrity errors Account-level enforcement. These block sending until the underlying issue is resolved with Meta. | Code | What it means | What to do | | -------- | -------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `368` | The WhatsApp Business Account was restricted or disabled for violating a platform policy. | Review Meta's Policy Enforcement page, resolve the violation in WhatsApp Manager. | | `130497` | The account is restricted from messaging users in certain countries (the Brazil / Indonesia cross-country restriction). | See [the full explanation and country table](/assistants/channels/whatsapp#troubleshooting). No override; use a locally-registered account to reach those users. | | `131031` | The account was restricted or disabled for a policy violation, or request data (such as the two-step PIN) could not be verified. | Check Policy Enforcement and the Health Status API. Verify any PIN or credentials in the request. | ### Throttling and rate limits Everything here means *send slower or improve quality*. None require a structural fix, only pacing. | Code | What it means | What to do | | -------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------- | | `4` | The app hit its overall API call rate limit. | Retry later or reduce request frequency. | | `80007` | The WhatsApp Business Account hit its rate limit. | Retry later or send less frequently. | | `130429` | Cloud API message throughput limit reached. | Spread sends out over time. | | `131048` | Sends are restricted because too many earlier messages were blocked or flagged as spam. | Check quality status in WhatsApp Manager; improve template quality. | | `131056` | Too many messages to the **same** recipient in a short period. | Wait and retry that contact; other numbers are unaffected. | | `131064` | Messaging limit reached due to template classification violations. | Ensure templates are categorized correctly; the limit lifts after the enforcement period. | | `133016` | Too many register / deregister attempts for this number in a short period. | Wait until the number is unblocked, then retry. | ### Sending and delivery errors The most common day-to-day failures when a specific message cannot be delivered. | Code | What it means | What to do | | -------- | ---------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ | | `130403` | You blocked this user, so the message cannot be delivered. | Do not retry; unblock the user to resume. | | `130472` | Message was not sent as part of a marketing experiment. | Expected for the Marketing Message Experiment; no action. | | `131021` | Sender and recipient phone numbers are the same. | Send to a number different from the sender. | | `131026` | Undeliverable: recipient is not on WhatsApp, has not accepted the latest Terms, or is on a very old app version. | Confirm the number is correct and on WhatsApp; nothing to fix if they do not use WhatsApp. | | `131045` | Send failed due to a phone number registration error. | Ensure the number is registered before sending. | | `131047` | More than 24 hours since the recipient last replied. | Send an approved template to re-open the conversation. | | `131049` | Held back to maintain healthy ecosystem engagement (per-user marketing limit). | Wait at least 24 hours before resending. | | `131050` | Recipient opted out of marketing messages from your business. | Do not retry; you may still send utility / authentication templates. | | `131051` | Unsupported message type. | Use a supported message type. | | `131052` | Could not download media the user sent. | Ask the user to resend the file by another method; check `error_data.details`. | | `131053` | Could not upload the media in your message (often an unsupported type). | Verify the file's MIME type is supported; inspect with `file -I`. | | `131057` | The account is in maintenance mode (for example a throughput upgrade). | Wait and retry. | | `131063` | Template is Marketing, but marketing templates are disabled for this Cloud API config. | Re-enable marketing on Cloud API, or use the Marketing Messages API. | | `134011` | Send blocked: WhatsApp Payments Terms of Service acceptance is pending. | Accept the Payments ToS via the link in the error, then retry. | ### Template errors Creating, sending, and quality issues with message templates. | Code | What it means | What to do | | --------- | -------------------------------------------------------------------- | ------------------------------------------------------------ | | `2388040` | A template field exceeded its character limit. | Shorten the field named in the error. | | `2388047` | Message header format is invalid. | Fix the header formatting per the error detail. | | `2388072` | Message body format is invalid. | Fix the body formatting per the error detail. | | `2388073` | Message footer format is invalid. | Fix the footer formatting per the error detail. | | `2388293` | Too many variables for the template's length. | Reduce variables or lengthen the message. | | `2388299` | A variable sits at the very start or end of the template. | Move variables away from the leading / trailing position. | | `2388019` | Reached the maximum number of templates for this account. | A WABA allows up to 250 templates; delete unused ones. | | `132000` | Variable count in the request did not match the template definition. | Send a value for every variable the template defines. | | `132001` | Template does not exist in that language, or is not approved. | Check the name and locale; confirm the template is approved. | | `132005` | Translated text is too long. | Shorten the translation; verify it in WhatsApp Manager. | | `132007` | Template content violates a WhatsApp policy. | Edit to comply and resubmit for review. | | `132012` | Variable values formatted incorrectly. | Match the format the template specifies. | | `132015` | Template paused for low quality. | Improve the content; it can return once re-approved. | | `132016` | Template permanently disabled after being paused too many times. | Create a new template with better content. | | `132068` | Flow is in a blocked state. | Correct the Flow. | | `132069` | Flow is throttled (10 messages already sent in the last hour). | Correct the Flow and wait. | ### Template insights errors Niche; only relevant if you toggle template analytics directly. | Code | What it means | What to do | | -------- | ----------------------------------------------------- | ---------------------------------------------- | | `200005` | Template insights not available yet for this account. | Cannot be enabled at the moment. | | `200006` | Template insights cannot be disabled once enabled. | No action; this is by design. | | `200007` | Template insights are not enabled for this account. | Enable them via Confirming template analytics. | ### Phone number registration and migration errors These appear during number setup and migration between accounts, not during normal messaging. | Code | What it means | What to do | | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | `33` | The business phone number has been deleted. | Verify the number is correct. | | `133000` | A previous deregistration attempt failed. | Deregister the number again before registering. | | `133004` | Server temporarily unavailable. | Check the Platform Status page and retry. | | `133005` | Two-step verification PIN incorrect. | Verify the PIN; reset it by disabling and re-enabling two-step verification. | | `133006` | Number must be verified before registering. | Verify and register the number. | | `133008` | Too many two-step PIN guesses. | Wait the period stated in `details`. | | `133009` | Two-step PIN entered too quickly. | Check `details` and slow down. | | `133010` | Number is not registered on the platform. | Register the number first. | | `133015` | The number was recently deleted and deletion has not finished. | Wait 5 minutes and retry. | | `2388012` | The number already exists in your account. | Use a number not already present. | | `2388091` / `2388093` | Number not eligible to receive / verify a registration code (not being migrated). | Register and verify the number normally. | | `2388103` | A migration failure with several possible causes (webhooks not set up, display name not approved, no payment account, wrong Business Manager, account not approved, "Messaging For" not approved, or a generic error). | Read the `details` text; it names the exact cause and fix. Some cases require contacting Meta support. | | `2494100` | The number is in maintenance mode. | Try again in a few minutes. | ### WhatsApp Business Account and ownership errors Rare; tied to the deprecated On-Behalf-Of (OBO) ownership model. | Code | What it means | What to do | | --------- | ---------------------------------------------------------------------------------------------- | ---------------------------------------- | | `2593079` | WABA already marked for migration to a different solution ID. | OBO is deprecated; contact Meta support. | | `2593085` | WABA not eligible for OBO ownership transfer (already owned, or the request was not accepted). | OBO is deprecated; contact Meta support. | ### Onboarding synchronization errors Only relevant during Coexistence onboarding, when contacts and history sync. | Code | What it means | What to do | | --------- | --------------------------------------------------------------------- | ---------------------------------------------- | | `2593107` | Exceeded the allowed number of synchronization calls for this number. | Offboard and re-onboard the business customer. | | `2593108` | Synchronization can only run within 24 hours of onboarding. | Offboard and re-onboard the user. | ### General and server errors Catch-alls for malformed requests and platform outages. | Code | What it means | What to do | | -------- | ------------------------------------------------- | ---------------------------------------------------------- | | `1` | Invalid request or possible server error. | Check the Platform Status page; verify request formatting. | | `2` | Temporary issue from downtime or overload. | Check Platform Status before retrying. | | `100` | One or more unsupported or misspelled parameters. | Check parameter names, values, and length limits. | | `131000` | Unknown error. | Retry; if it persists, open a Meta Direct Support ticket. | | `131005` | Permission not granted or removed. | Re-authorize the connection. | | `131008` | A required parameter is missing. | Add the required parameter. | | `131009` | One or more parameter values are invalid. | Use supported values for each parameter. | | `131016` | A service is temporarily unavailable. | Check Platform Status and retry. | | `131037` | The sending number has no approved display name. | Get the display name approved in WhatsApp Manager. | | `135000` | Unknown error with your request parameters. | Verify request syntax; contact support if it persists. | ### Marketing Messages API errors Only relevant if you use Meta's Marketing Messages (MM) API, which reuses Cloud API codes plus these additions. | Code | What it means | What to do | | --------- | -------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | | `100` | The message must be a template message. | Send a marketing **template**, not a free-form message. | | `131009` | Parameter value is not valid (or ad sync incomplete). | Verify parameters; if ad syncing, wait 10 minutes and retry. | | `131055` | Only marketing template messages are supported here. | Send a marketing template, not utility / authentication or free-form. | | `134100` | Only marketing messages are supported on this API. | Use a template categorized as Marketing. | | `134101` | Your template is still syncing (up to 10 minutes after creation). | Wait a few minutes and resend. | | `134102` | Template unavailable; ad sync failed or you are not onboarded. | Check eligibility; if `marketing_messages_lite_api_status` is `ONBOARDED` and it persists, contact support. | | `132018` | Template validation error in the parameters. | Fix the parameters and resend. | | `1752041` | Duplicate onboarding request; the client was already invited by a partner. | No action; all eligible WABAs onboard automatically. | ## Still stuck? * For send failures, the fastest signal is usually your **quality rating and messaging limits** in [WhatsApp Manager](https://business.facebook.com/wa/manage/). * For account-level restrictions (`368`, `130497`, `131031`), the resolution lives with Meta, not inside Invent. * When escalating to Meta, include the `fbtrace_id` from the error so Direct Support can trace the exact request. * For connection or token issues (`0`, `190`, `200`, `131005`), reconnect WhatsApp from [Settings → Connections](/workspace-management/connections). # WhatsApp Manager Source: https://docs.useinvent.com/assistants/channels/whatsapp-manager Manage your WhatsApp Business account from inside Invent, including account health, phone numbers, business profile, and message templates, without opening Meta's Business Manager This guide covers managing a WhatsApp connection you already have. To connect a number first, see [WhatsApp Business](/assistants/channels/whatsapp). Once a WhatsApp number is connected, everything you would normally do in Meta's WhatsApp Manager is available under **Channels → WhatsApp** in the sidebar. The data always reflects the live state of your Meta account: Invent reads it straight from the WhatsApp Cloud API and updates in real time when Meta sends a change, so there is nothing to sync or refresh manually. If your organization has more than one WhatsApp connection, every page has a connection selector at the top. Pages that operate on a single number (Profile) also have a phone number selector next to it. ## Overview The Overview page is the health dashboard for the whole account. ### Account health Shows whether the account can currently send **business-initiated messages** (template messages, like broadcasts), as reported by Meta. * **Healthy**. Everything can send. * **Limited**. Sending works but is restricted. The reason appears below. * **Blocked**. Business-initiated messages are blocked. Account health only governs business-initiated (template) messages. Replies inside the 24-hour customer service window are unaffected, so your assistant keeps answering incoming chats even while the account shows Blocked. Under the summary, each part of the messaging chain is listed with its own status: every **phone number**, the **WhatsApp account** (WABA), and the **business** portfolio. When something is Limited or Blocked, the row shows Meta's reason and, where the fix is known, a direct link to the right place in Meta to resolve it (for example, setting up a payment method or starting business verification). ### Business verification Whether your Meta business portfolio is verified. Unverified businesses face lower messaging limits and cannot request an official business account. The card links straight to Meta's Security Center to start verification. ### Messaging limit How many unique customers you can open business-initiated conversations with in a rolling 24-hour period. The tiers are 250, 2K, 10K, 100K, and unlimited, and the current tier is highlighted on the scale. Meta raises the tier automatically as you message more people with good quality. ### Quality rating Meta's quality rating across your phone numbers, on Meta's own scale: **Green** (high), **Yellow** (medium), **Red** (low). The rating is based on recent customer feedback like blocks and reports. A low rating can lead to Meta lowering your messaging limit, so if you see Yellow or Red, slow down campaigns and review what you are sending. The page also lists the account details (name, ID, status, currency) and billing, which is managed by Meta and linked from the page. ### Activity A live feed of the latest changes Meta reports on the account: account updates, account review updates, messaging capability updates, and payment configuration changes. Entries appear as they happen, so you can see the reason behind a health or limit change without leaving the Overview. ## Profile The public business profile customers see when they open your number in WhatsApp, editable per phone number: profile picture, about line, description, address, email, websites, and business category. Changes save directly to WhatsApp and are visible to customers immediately. ## Phone numbers Every number in the account, with its display name, quality rating, and messaging limit tier. A number with its own health problem shows a **Limited** or **Blocked** badge next to it, with Meta's reason on hover; a healthy number stays unmarked even if the account has issues elsewhere. * **Display name**. Request a name change. Meta reviews name changes, so the number shows a pending state until the review resolves. Approved names with an official business account show the blue checkmark next to the name. * **Deregister**. Removes the number from the Cloud API. Use with care: assistants, workflows, and broadcasts using the number stop sending and receiving until it is registered again. Numbers from Meta's free test pool (the fictional `+1 555` numbers you get while developing) are marked with a small badge so you never confuse them with production lines. ## Templates Create and manage the pre-approved message templates required for broadcasts and any business-initiated message. Template management has its own full guide: [WhatsApp for Broadcasts](/guides/broadcasts/channels/whatsapp). ## Who can do what Viewing and editing follow your organization roles: | | Admin | Developer | Manager | Agent | | :--------------------------------------------------------------- | :---: | :-------: | :-----: | :---: | | See the WhatsApp pages | ✓ | ✓ | ✓ | — | | Templates (create, edit, delete) | ✓ | ✓ | ✓ | — | | Channel settings (profile, display name, deregister, connection) | ✓ | ✓ | — | — | The split is intentional: templates are campaign content, so anyone who can send broadcasts can manage them; changes that can take the channel down stay with technical roles. Custom roles follow the same rule via their granted permissions. In sub-organizations, the whole Channels section can also be hidden with the module toggles in organization settings. ## Next Steps * [Connect another number](/assistants/channels/whatsapp#connecting-more-numbers) * [WhatsApp for Broadcasts](/guides/broadcasts/channels/whatsapp) * [WhatsApp error codes](/assistants/channels/whatsapp-error-codes) * [Inbox](/guides/inbox) # Introduction Source: https://docs.useinvent.com/assistants/introduction Learn about AI assistants and how to create powerful customer service agents Assistants are the heart of Invent. Each assistant is an AI-powered agent that can answer questions, perform tasks, and interact with your customers across multiple channels, all automatically. Assistants Overview ## What is an Assistant? An assistant is your AI customer service agent. It can: * **Answer questions** using your knowledge base * **Perform actions** like booking appointments or sending emails * **Connect to channels** like WhatsApp, Instagram, and your website * **Remember customers** across all conversations * **Hand off to humans** when needed Think of it as a team member who works 24/7, never takes breaks, and can handle hundreds of conversations simultaneously. ## Creating an Assistant From your dashboard, click **Assistants** in the sidebar, then **Create Assistant**. You'll initially provide: 1. **Name**: The name your assistant will display (customers see this) 2. **Template**: A starting template to help you get started (optional) Create Assistant ## Assistant Configuration Each assistant has five configuration tabs: **Settings**, **Knowledge**, **Actions**, **Channels**, and **Widget**. **Instructions**, **Contact Properties**, **Capabilities**, and **AI Routing** are sections inside the **Settings** tab. ### Settings Configuration for your assistant: **General** * **Name and Avatar**: Your assistant's identity * **Model**: Choose between multiple AI models. Each model shows an estimated cost per message right in the selector. **Auto** is the recommended default, automatically selecting the best model for each message. [How pricing works →](/guides/pricing-and-plans#how-message-pricing-works) * **Timezone**: Set the timezone for your assistant. Defaults to the timezone of the user who created the assistant. This makes messages date-time aware, giving your assistant better context for returning users. Expect natural responses like "Good morning! How was the game yesterday?" * **Language**: Primary language for responses (Auto detects automatically) Assistant General Settings **When a model is retired:** assistant will automatically switch to the most recent model in the same family for new messages. If no newer model exists in that family, the assistant will fallback to **Auto**. For existing chats the same behavior applies. ### Instructions Instructions define your assistant's behavior, personality, and rules. This is where you tell the assistant *how* to act, not what information it knows (that goes in [Knowledge](/guides/knowledge)). Good instructions make the difference between a helpful assistant and a frustrating one. Be specific about personality, responsibilities, and boundaries. Below the instructions field, you'll find a template dropdown with pre-built starting points for common use cases. Assistant Instructions Define *behavior* in instructions, not factual information. Class schedules, pricing, and policies belong in Knowledge, where they're easier to update and the assistant can search through them more effectively. **Conversation Flow** * **Thread Mode**: Determine whether new messages from users continue the existing conversation or start a completely new conversation each time * **Enable Private Conversations**: Hide conversations from the inbox and auto-delete them after 24 hours of inactivity ### Capabilities Capabilities * **AI Replies**: The master switch for the assistant. When off, the assistant becomes human-only: incoming messages are still received and stored, but the AI never responds and new conversations are auto-assigned to an available member so your team can answer. [How routing works →](/assistants/routing) * **Auto-resolve** `Recommended`: Closes stale conversations after inactivity. Without Auto Follow-ups, conversations close silently. Conversations auto-close after 20 minutes of inactivity. * **Auto Follow-ups** `Recommended` `Uses AI credits`: AI analyzes idle conversations and decides to re-engage, schedule a follow-up, or close. Replaces silent auto-resolve with smart management. Not available on Web Widget channel. [Learn more](/guides/auto-follow-ups) * **Auto CSAT** `Recommended` `Uses AI credits`: Automatically scores customer satisfaction (1-5) after conversations close. Scores appear in the Inbox alongside each conversation. * **Memories** `Recommended` `Uses AI credits`: Let your assistant store user details for future conversations. [Learn more](/guides/memory) * **Spam Protection**: Let the assistant block contacts when detecting bad behavior or potential bad actors ### Contact Properties Control what the assistant can do with your custom [contact properties](/guides/audience/properties). The section contains the **Update Contact Info** toggle and, below it, a visibility setting for each property: * **Hidden**: The assistant cannot see the property * **Visible**: The assistant can see the property during conversations * **AI Controlled**: The assistant can see and update the property Assistant Contact Properties Set a property to **AI Controlled** and the assistant keeps it up to date as it learns things in conversation, like a customer's size or their marketing preferences. Visibility is per assistant, so different assistants can have different access to the same property. [Learn more about Properties →](/guides/audience/properties) ### AI Routing Turn on **Transfer to Member** here to let the assistant decide when to hand a conversation to one of your members, and choose which members each assistant can route to. [Learn more about AI Routing →](/assistants/routing) ### Knowledge What your assistant knows. You can: * Upload files, text, or website URLs * Link existing global knowledge * Set knowledge scope (restricted to this assistant or shared) [Learn more about Knowledge →](/guides/knowledge) ### Actions What your assistant can do. Add integrations like: * Google Calendar (book appointments) * Stripe (process payments) * Gmail (send emails) * And 20+ more integrations [Learn more about Actions →](/assistants/actions) ### Channels Where your assistant lives. Connect to: * WhatsApp Business * Instagram Direct Messages * Facebook Messenger * Telegram * Web Widget * And more [Learn more about Channels →](/assistants/channels) ### Widget Customize the chat widget for your website: * Colors and branding * **Greeting**: the greeting text shown when users start a new chat * **Suggested Messages**: quick action buttons (up to 5) that users can tap to send common messages * Position and behavior ## The Playground Every assistant has a Playground, a testing environment where you can chat with your assistant before going live. Use it to: * Test new knowledge * Verify actions work correctly * Refine instructions * Debug issues The Playground appears on the right side of the assistant page. Click "Create Conversation" to start testing. ## Writing Great Instructions Instructions are the single most important factor in how well your assistant performs. For a complete guide with templates, real examples, and best practices, see the dedicated guides: Understand what goes in Instructions vs the Knowledge Base Templates, 11 building blocks, and real-world examples ## Multiple Assistants You can create multiple assistants for different purposes: * **Sales Assistant**: Handles pre-purchase questions * **Support Assistant**: Helps existing customers * **Booking Assistant**: Focuses on scheduling Each assistant can have different knowledge, actions, and channels. ## Next Steps Explore what your assistant can understand and respond with Connect your assistant to WhatsApp, Instagram, and more Give your assistant the ability to perform real tasks Train your assistant with your business data and documentation # AI Routing Source: https://docs.useinvent.com/assistants/routing Let your assistant hand conversations to the right teammate, using plain-language descriptions of who handles what When a customer needs a person, your assistant hands the conversation to the right teammate on its own. It chooses who from each member's role and a short, plain-language description of what they handle. No rules, no decision trees. Manage routing at [useinvent.com/o/settings/routing](https://www.useinvent.com/o/settings/routing), or per assistant in the assistant's **AI Routing** section. AI Routing ## How It Works The customer asks for a person, or the assistant reaches something it shouldn't answer on its own. From the available members, it picks the best fit — a specific person, or anyone on a matching role or team — using their roles and descriptions. If nothing clearly matches, it assigns by availability and current workload. It lands in the Inbox under **Waiting for Human**, assigned to that teammate so they're notified. The conversation stays **Unassigned** and anyone permitted can claim it with **Take Over**. When **AI Replies** is off, new conversations are auto-assigned to an available member straight away, so your team is notified even before the AI weighs in. ## Turn On Routing Routing runs through the **Transfer to Member** capability. Open an assistant, scroll to the **AI Routing** section, and enable **Transfer to Member**. This lets the assistant decide when to hand a conversation to one of your members. The same **AI Routing** section has an optional **Routing instructions** field — free-text guidance that steers how this assistant chooses between members (which person or team to prefer, when to escalate). Leave it empty to route purely on roles and descriptions. Transfers are disabled inside private chats. ## Choose Who an Assistant Routes To By default, every organization member is eligible to take over. Add specific members to limit an assistant to a chosen group: In the assistant's **AI Routing** section, or from **Settings → AI Routing**, find the assistant. Click **Add Member** and pick who should be eligible. The assistant now routes only among them. Remove someone with the trash icon, or toggle their availability without removing them. Managers can only add members they're allowed to see. On white-label workspaces that excludes Admins and Developers. Add Member **Example:** put your support team on the Support assistant and your sales team on the Sales assistant, so each conversation reaches the right group. ## Describe What Each Member Handles This is what makes routing accurate. Give each member a short, plain-language description of what they cover: > Billing disputes and refunds. English and Spanish. The assistant reads the description alongside the member's roles to choose the right person or team. Descriptions are **visible to the AI** and edited by managers, from **Settings → Members** or the **AI Routing** section. If you haven't added specific members, the assistant only routes to members who have a description. Writing one is how a member opts in to being routed to. Once you add explicit members, every available one is eligible, description or not. Descriptions are optional. Skip them when everyone handles the same things, when you route by role, or when a member's role already says what they do. ## Availability Every member has an availability status that controls whether the assistant assigns them work: **Available**: the assistant can assign conversations to them. **Unavailable**: skipped for new assignments (for example, while away), but keeps full access and can still take over conversations manually. Members set their own status from the account menu. Managers can set anyone's from **Settings → Members**. ## Roles and Access Any member can be added. Admins and Developers always have access to every assistant's conversations, so you rarely need to add them explicitly. On white-label workspaces, Managers and Agents don't see Admin or Developer members. ## Manual Assignment You're never locked into automatic routing. From the Inbox you can: * Assign a conversation to any teammate from the member dropdown. * Click **Take Over** to claim a conversation yourself. * Click **Resolve** when it's handled, or **Hand Over to AI** to return it to the assistant. Resolved conversations reopen automatically if the customer replies. ## Best Practices Steer routing with the **Routing instructions** field (in the assistant's AI Routing section). Routing itself just matches on roles and descriptions — any preference beyond that ("send payment issues to the Billing team first", "only involve a manager if the customer asks for one") goes there, where it can be as specific as you like. There's no fixed seniority order baked in. * **Write descriptions the way customers describe their problem**, not in internal jargon. "Refunds, billing, and payment disputes" routes better than "AR/AP specialist." * **Keep them short and specific.** Include specialties, languages, and coverage — "Onboarding and setup. Spanish. EMEA hours." One or two lines is plenty. * **Use roles for interchangeable teams, descriptions for specifics.** If anyone on a team can take the question, a shared role does the job; reach for descriptions when people cover different things. * **Keep availability current.** Flip to Unavailable when you step away — the assistant never routes to someone marked unavailable, so stale statuses send work to the wrong place. * **Scope assistants with explicit members.** Leaving an assistant open means anyone with a description is eligible; adding members restricts it to that group. For large teams, assign the specific people who should handle each assistant so routing stays focused. * **You don't have to describe everyone.** If a conversation doesn't clearly match anyone, the assistant assigns by availability and workload — so describe the people whose specialty actually matters. ## Use Cases **Specialized teams**: route billing to finance and bugs to engineering by describing what each person handles. **Language or region**: add "English and Spanish" or "EMEA hours" to a description and the assistant matches accordingly. **Tiered support**: add only senior members to a high-touch assistant. **Time away**: flip to Unavailable at capacity or off-shift, and the assistant stops assigning you new conversations. ## Next Steps Manage conversations and monitor handoffs in the Inbox Invite team members and assign roles for routing access # Web Widget Source: https://docs.useinvent.com/assistants/widget Customize and embed the chat widget on your website The Widget tab is where you customize your assistant's on-site experience and get the code to add it to your website. Share a link, embed a chat bubble, or add an inline frame. A live preview on the right shows every change as you make it, and you can switch it between the **Chat**, **Omnibar**, **Teaser**, and **Channels** views. Widget settings with a live preview of the chat ## Embed Methods The Widget tab has three ways to deploy your assistant: ### Hosted Link A shareable URL that opens your assistant in a standalone page. No code or integration required. ``` https://www.useinvent.com/e/YOUR_ASSISTANT_ID ``` Copy the link and share it anywhere: send it to customers, embed it in emails, use it for testing, or share it with team members. Anyone with the link can start chatting with your assistant. Add a `q` parameter to prefill the message box, for example `.../e/YOUR_ASSISTANT_ID?q=I%20need%20help%20with%20billing`. The text is filled in for the visitor, not sent, so they can edit it before starting the chat. This works on the iframe `src` too. ### Embed Script An HTML snippet you paste into your website. By default it adds a floating chat bubble in the corner of your page that customers can click to open a conversation — the shape, colors and behavior all come from your saved widget settings, so you never touch the snippet again. Embed Script Code ```html theme={"system"} ``` Copy the snippet and paste it before the closing `` tag on your website. The bubble appears immediately. Click **Copy prompt for AI agent** to copy an integration prompt you can paste into AI coding tools like Cursor, Claude Code, etc. It includes the full snippet and instructions for adding the widget to your project. For platform-specific setup guides (WordPress, Shopify, Next.js, Webflow, and more), see the [install guides](#install-guides) below. ### Omnibar The same embed script can wear a different shape: a centered "Ask anything" bar at the bottom of your page. Visitors type right into it, and the chat expands around their question. Pick **Omnibar** as the **Default Mode** under **Appearance** to switch existing embeds without touching any code, or force it per page with a `mode="omnibar"` attribute on the element. ```html theme={"system"} ``` Omnibar focused with suggested messages and channels Focusing the bar raises your **Suggested Messages** and channel shortcuts above it. Sending a message expands the bar into the full chat panel; the minimize button folds it back down. Omnibar expanded into the chat panel * The bar is transparent around its edges and never blocks the page: clicks pass through everywhere the widget is not visible. * The resting bar types out your suggested messages as its placeholder, so the invitation does the selling. * Scrolling down folds the bar into a compact centered button (the same bar, morphed smaller); scrolling back up brings it back. Tapping the button reopens the bar, focused and ready to type, and if a reply arrives while folded, the button shows an unread dot. On mobile this is always on; the **Minimize on Scroll** setting extends it to desktop. * While the suggestions are raised, a grabber handle above them expands the full panel; pressing Escape folds everything back down. * The `?q=` parameter prefills the bar the same way it prefills the hosted link. * On desktop, the chat header includes a shape toggle, so visitors can switch between the omnibar and the bubble button themselves; the widget remembers their pick. Mobile keeps the UI lean: no toggle, the configured mode always applies. Set `mode="auto"` (or the **Auto** Default Mode) to let the widget decide: new visitors get the omnibar, and once they have a conversation, later visits show the familiar bubble button instead. ### IFrame An inline embed that displays your assistant directly within a page, rather than as a floating bubble. Use this when you want the assistant to appear as part of your page layout. IFrame Code ```html theme={"system"} ``` This is useful for dedicated support pages, help centers, or any layout where you want the assistant embedded inline. ## Customization All embed methods share the same settings, grouped into **Appearance**, **Conversation**, **Teaser**, **Channels**, and **Advanced**. Every change shows up in the live preview and is not applied until you click **Save**. ### Appearance Controls how the widget looks on your site. * **Default Mode**: the shape the widget starts in, the **Bubble Button** in the corner or the centered **Omnibar**. **Auto** shows the Omnibar until a visitor has a conversation. The resolution order is: the visitor's own header-toggle pick wins (desktop only — mobile has no toggle), then a `mode` attribute on the embed element, then this setting. * **Bubble Button Position**: the corner for the bubble launcher, **Bottom right** or **Bottom left**. The Omnibar is always centered. A `position` attribute on the embed element overrides it per page. * **Minimize on Scroll**: folds the Omnibar into its compact button while visitors scroll down on desktop (off by default). On mobile the bar always folds. Scrolling back up brings the bar back; a visitor who dismissed it stays folded until they tap. * **Theme Appearance**: the color scheme of the chat. **Auto** matches the visitor's system preference, or force **Light** or **Dark**. * **Accent Color**: used across the widget for the chat button, buttons, links, and your visitors' messages. Click the circle to pick a color or enter a hex value. * **Bubble Button**: the floating button follows your accent color by default. Set a custom color if you want the button to stand out. The icon color adapts automatically for contrast, so you never set it yourself. ### Conversation Shapes the first thing visitors see when they open the chat. * **Greeting**: the welcome message shown at the top of a new conversation. * **Suggested Messages**: quick replies visitors can tap to start. These also appear alongside the teaser. * **Dictation**: let visitors dictate messages with their microphone. * **File Uploads**: let visitors attach files and images to their messages. ### Teaser A short, proactive invitation that appears next to the closed button to nudge visitors into a conversation. It is on by default and only appears when there is something to show: a greeting or suggested messages. Teaser Preview * **Show Teaser**: turn the teaser on. By default it shows your **Greeting**; use **Greeting Override** to show different text just in the teaser. * **Show on**: which widget modes show the teaser, the Bubble Button, the Omnibar, or both. In omnibar mode the teaser appears as a message right above the bar. * **Show Suggested Messages**: the suggested messages from the **Conversation** section appear as tappable chips beside the teaser. Tapping one opens the chat and sends it. Choose which modes show them, or turn them off. Defaults to **Bubble Button**: the Omnibar already shows them when focused, independent of this setting. * **Devices**: where it shows, **Desktop only**, **Mobile only**, or **Desktop and mobile**. * **Delay**: how long to wait after the page loads before the teaser appears. * **Frequency**: how often it can show again. **Once per visitor**, **Once per session**, or **Every visit**. Visitors who dismiss it will not see it again (except with **Every visit**). * **Reset Dismissals**: **Show again to all visitors** brings the teaser back for everyone who dismissed it, starting on their next visit. ### Channels Offer visitors other ways to reach you from a menu on the widget button. When any channels are configured, tapping the button opens this menu first, with a button to start the chat. Channels Preview * **Connected channels**: any messaging channels you have connected (WhatsApp, Messenger, Instagram, Telegram) are included automatically and keep their links up to date. Remove one to hide it from the menu. * **Custom channels**: add a **Link**, **Email**, or **Phone** entry to point visitors anywhere else. * **Menu Heading**: the text shown above the channels in the menu. * **Chat Button**: the label for the button that opens the chat. Connect messaging channels first under the [Channels](/assistants/channels) tab, then reorder or hide them here. ### Advanced * **Hide Powered By**: remove the "Powered by Invent" branding from the widget. Removing "Powered by" branding requires a [Business or Enterprise plan](/guides/pricing-and-plans). * **Reset to Defaults**: restore every widget setting, including colors, teaser, and channels, to its default. Nothing changes until you save. ## User Authentication (Optional) By default, every visitor gets an anonymous session. To identify users and enable personalized experiences, conversation history across sessions, and contact management, add authentication attributes to the widget. ### Authentication Attributes | Attribute | Description | | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `user-hash` | **Required for authentication.** HMAC-SHA256 hash of the `user-id` using your assistant's secret key. Must be generated on your backend | | `user-id` | The unique user identifier from your application. Used for session management, analytics, and maintaining conversation history across sessions | | `user-name` | Display name for the user (full name, first name, username, etc.). Used for personalization in chat messages and [contacts](/guides/audience). URL-encode special characters | `user-hash` and `user-id` are required together. `user-name` is optional. ### Setting Up Authentication Scroll to the **Secret Key** section at the bottom of the Widget tab and click **Generate Secret Key**. This creates a unique key for your assistant. Secret Key Copy the key and store it securely on your backend. Never expose it in client-side code. Use the secret key to create an HMAC-SHA256 hash of the user's ID. Here is an example in Node.js: ```javascript theme={"system"} import crypto from 'crypto'; const secretKey = 'YOUR_SECRET_KEY'; const userId = 'user_123'; function generateUserHash(userId, secretKey) { return crypto .createHmac('sha256', secretKey) .update(userId) .digest('hex'); } const userHash = generateUserHash(userId, secretKey); ``` Always generate the hash on your server. Never include the secret key in client-side JavaScript. Pass the authentication attributes to the widget element: ```html theme={"system"} ``` For more authentication examples in other languages (PHP, Python, Ruby, Go) and framework-specific guides, see the [install guides](#install-guides) below. ## Element Attributes The `` element reads a fixed set of attributes. Anything else is ignored. | Attribute | Values | Description | | ----------------------------------- | --------------------------- | --------------------------------------------------------------------------------------- | | `assistant-id` | your assistant ID | **Required.** Identifies which assistant to load | | `mode` | `button`, `omnibar`, `auto` | Overrides the **Default Mode** for this page | | `position` | `right`, `left` | Overrides the **Bubble Button Position** for this page | | `theme-appearance` | `auto`, `light`, `dark` | Overrides the **Theme Appearance** for this page | | `theme-button-background-color` | hex color | Overrides the bubble button color. The icon color is derived automatically for contrast | | `hide-powered-by` | `true` | Hides the "Powered by Invent" branding (Business or Enterprise plan) | | `user-id`, `user-hash`, `user-name` | strings | Authentication attributes (see above) | The button icon color is always computed for contrast, so there is no `theme-button-color` attribute. The widget also has no inbound page-context API, so `window.inventContext` and similar globals have no effect. ## Install Guides Step-by-step setup guides for popular platforms and frameworks. ### Frameworks ### Content Management ### Website Builders ### E-commerce ## Next Steps Connect your assistant to WhatsApp, Instagram, Messenger, and other messaging platforms Hand off conversations to human teammates when needed # Astro Source: https://docs.useinvent.com/assistants/widget/install/astro Add your Invent assistant to Astro sites ## Overview Add your Invent AI assistant to any Astro site. Perfect for content-focused websites with islands architecture and multi-framework support. ## Installation Astro supports multiple frameworks. Choose your preferred approach: #### Pure Astro Component ```astro theme={"system"} --- // src/components/InventAssistant.astro export interface Props { assistantId: string; themeAppearance?: 'auto' | 'light' | 'dark'; themeButtonBackgroundColor?: string; userId?: string; userName?: string; userHash?: string; } const { assistantId, themeAppearance = 'auto', themeButtonBackgroundColor, userId, userName, userHash, } = Astro.props; --- ``` #### React Component (with React integration) ```tsx theme={"system"} // src/components/InventAssistant.tsx interface Props { assistantId: string; themeAppearance?: 'auto' | 'light' | 'dark'; themeButtonBackgroundColor?: string; userId?: string; userName?: string; userHash?: string; } export default function InventAssistant({ assistantId, themeAppearance = 'auto', themeButtonBackgroundColor, userId, userName, userHash, }: Props) { return ( <> ``` ### Static HTML For static site generators that output HTML: ```html theme={"system"} ``` ## Environment Variables Store your assistant ID in environment variables: ```bash theme={"system"} # .env.local NEXT_PUBLIC_INVENT_ASSISTANT_ID=ast_YOUR_ASSISTANT_ID ``` ```jsx theme={"system"} ``` ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client or generate the hash in frontend code. To authenticate users from your application and provide personalized experiences: 1. Generate a secret key in your assistant settings 2. On your backend, generate an HMAC-SHA256 hash of the user ID 3. Pass the hash along with user information to the assistant See the [Widget Authentication](/assistants/widget#user-authentication-optional) guide for complete authentication details. ## Framework-Specific Tips Use in \_app.jsx or layout.tsx for global availability Add to gatsby-browser.js for all pages Create as a plugin in plugins/ directory Add to root +layout.svelte ## Troubleshooting **Solutions:** * Ensure script loads after component mounts * Check for hydration issues in SSR * Verify custom element support in your build **Solutions:** * Load script only on client side * Use useEffect or mounted lifecycle * Check for window object availability # Drupal Source: https://docs.useinvent.com/assistants/widget/install/drupal Add your Invent assistant to Drupal sites ## Overview Add your Invent AI assistant to any Drupal website with a floating bubble. Perfect for enterprise websites, government sites, and large-scale content platforms. ## Installation ### Method 1: Using Block System (Recommended) Navigate to **Structure** → **Block layout** → **Custom block library** → **Add custom block** * Give your block a description (e.g., "Invent Assistant") * Set **Text format** to **Full HTML** * Switch to **Source** mode in the editor Paste this code: ```html theme={"system"} ``` Replace `YOUR_ASSISTANT_ID` with your actual assistant ID. Save the block, then place it in a region (usually **Footer** or **Page bottom**) Configure block visibility settings if needed (all pages, specific pages, etc.) ### Method 2: Theme Template Add directly to your theme's template files: ```php theme={"system"} {# in your theme's html.html.twig or page.html.twig #} ``` ### Method 3: Using a Module Create a custom module or use an existing one: ```php theme={"system"} 'html_tag', '#tag' => 'invent-assistant', '#attributes' => [ 'assistant-id' => 'YOUR_ASSISTANT_ID', ], ], 'invent_assistant', ]; $attachments['#attached']['html_head'][] = [ [ '#type' => 'html_tag', '#tag' => 'script', '#attributes' => [ 'src' => 'https://www.useinvent.com/embed.js', 'async' => TRUE, 'defer' => TRUE, ], ], 'invent_assistant_script', ]; } ``` ## Customization ### Match Your Drupal Theme ```html theme={"system"} ``` ### Conditional Display by Content Type Using block visibility settings: 1. Edit your Invent Assistant block 2. Go to **Visibility** tab 3. Add conditions for **Content types**, **Pages**, or **Roles** Or in a custom module: ```php theme={"system"} function invent_assistant_page_attachments(array &$attachments) { $node = \Drupal::routeMatch()->getParameter('node'); // Only show on article nodes if ($node && $node->getType() == 'article') { // Add assistant code } } ``` ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. Pass Drupal user information to your assistant for personalized experiences: ```php theme={"system"} isAuthenticated()) { $secret_key = \Drupal::config('invent_assistant.settings')->get('secret_key'); $user_id = (string) $current_user->id(); $user_name = $current_user->getDisplayName(); $user_hash = hash_hmac('sha256', $user_id, $secret_key); $attachments['#attached']['html_head'][] = [ [ '#type' => 'html_tag', '#tag' => 'invent-assistant', '#attributes' => [ 'assistant-id' => 'YOUR_ASSISTANT_ID', 'user-id' => $user_id, 'user-name' => $user_name, 'user-hash' => $user_hash, ], ], 'invent_assistant', ]; } } ``` ## Drupal Commerce Integration For e-commerce sites: * Product support and questions * Order tracking assistance * Shipping information * Returns and refunds help ## Tips for Drupal Fully compatible with modern Drupal versions Works with Drupal's multilingual system Can be added as a paragraph type Compatible with Layout Builder ## Advanced Configuration ### Add to Specific Regions In your theme: ```yaml theme={"system"} # your_theme.info.yml regions: header: Header content: Content sidebar: Sidebar footer: Footer invent_assistant: 'Invent Assistant' ``` ### Cache Considerations Clear Drupal caches after adding the assistant: ```bash theme={"system"} drush cr # or drush cache-rebuild ``` ### Performance Optimization Use async/defer attributes (already included) and consider using Drupal's aggregation: ```php theme={"system"} $attachments['#attached']['library'][] = 'your_module/invent-assistant'; ``` ## Troubleshooting **Solutions:** * Clear all Drupal caches (Configuration → Performance → Clear all caches) * Verify text format is set to "Full HTML" * Check block placement and region * Ensure block is enabled and visible **Solutions:** * Check for JavaScript conflicts in browser console * Adjust block weight/order * Test with minimal theme/modules **Solutions:** * Check block visibility permissions * Verify "Anonymous user" role can see the block * Check cache settings for anonymous users ## Drupal Version Compatibility * **Drupal 7:** Use Block system or theme templates * **Drupal 8/9/10:** All methods supported * **Drupal 11:** Fully compatible (when released) ## Popular Drupal Distributions Works with: * **Acquia Lightning** * **OpenSocial** * **Commerce Kickstart** * **Panopoly** * **Thunder** * And all other Drupal distributions # Framer Source: https://docs.useinvent.com/assistants/widget/install/framer Add your Invent assistant to Framer sites ## Overview Add your Invent AI assistant to any Framer site with a floating bubble. Perfect for modern, interactive websites built with Framer. ## Installation Open your Framer project in the Framer editor. Click on the **Settings** icon in the top toolbar, then select **General**. Scroll down to **Custom Code** section and find **End of \ tag**. Add this code: ```html theme={"system"} ``` Replace `YOUR_ASSISTANT_ID` with your actual assistant ID from the Invent dashboard. Click **Publish** and your assistant will appear on all pages. ## Customization ### Match Your Framer Design ```html theme={"system"} ``` ### Show Only on Specific Pages For page-specific installation in Framer: 1. Select the specific page in your Framer project 2. Click **Page Settings** (gear icon) 3. Scroll to **Custom Code** 4. Add the code to that page only ## Framer Components You can also add the assistant to specific components: 1. Create a **Code Component** in Framer 2. Add the embed code inside 3. Place the component wherever you want ```jsx theme={"system"} export default function InventAssistant() { return ( <> ) } ``` ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. Pass user data if you have a membership or login system. See the [Widget Authentication](/assistants/widget#user-authentication-optional) guide for complete authentication details. ```html theme={"system"} ``` ## Tips for Framer The bubble works seamlessly with Framer animations Automatically adapts to mobile layouts Async loading won't slow down your site Works with Framer CMS pages ## Troubleshooting **Solutions:** * Verify code is in "End of body tag" section * Check assistant ID is correct * Clear browser cache and reload * Check browser console for errors **Solutions:** * Check z-index if bubble is hidden behind elements * Ensure no other chat widgets are installed * Test with interactions temporarily disabled # Gatsby Source: https://docs.useinvent.com/assistants/widget/install/gatsby Add your Invent assistant to Gatsby sites ## Overview Add your Invent AI assistant to any Gatsby site. Perfect for static websites built with React and GraphQL. ## Installation ```bash theme={"system"} npm install react-helmet gatsby-plugin-react-helmet ``` Add the plugin to your `gatsby-config.js`: ```javascript theme={"system"} module.exports = { plugins: [ 'gatsby-plugin-react-helmet', // ... other plugins ], }; ``` ```tsx theme={"system"} // src/components/InventAssistant.tsx import React from 'react'; interface InventAssistantProps { assistantId: string; themeAppearance?: 'auto' | 'light' | 'dark'; themeButtonBackgroundColor?: string; userId?: string; userName?: string; userHash?: string; } const InventAssistant: React.FC = ({ assistantId, themeAppearance = 'auto', themeButtonBackgroundColor, userId, userName, userHash, }) => { return ( <> ``` Replace `YOUR_ASSISTANT_ID` with your actual assistant ID from the Invent dashboard. Click **Save** and the assistant will appear on all pages of your Ghost site. ## Customization ### Match Your Ghost Theme ```html theme={"system"} ``` ### Show Only on Posts To add the assistant only to blog posts: 1. Go to **Settings** → **Code injection** 2. Use the **Post Footer** section instead of **Site Footer** ### Show Only on Pages For static pages only, add the code to individual page footers: 1. Edit the specific page 2. Click **Settings** (gear icon) 3. Add the code in **Code injection** for that page ## Ghost Membership Integration **User Authentication Not Supported:** Ghost does not provide server-side scripting capabilities needed to securely generate the `user-hash` required for user authentication. For sites with Ghost memberships, use the basic implementation without user-specific attributes. User authentication requires both `user-id` and `user-hash` to be provided together with the hash generated on your backend using HMAC-SHA256. For Ghost sites, use the basic implementation that works for all visitors: ```html theme={"system"} ``` If you need user-specific authentication, you would need to implement custom middleware or a serverless function outside of Ghost to generate the hash securely. See the [Widget Authentication](/assistants/widget#user-authentication-optional) guide for hash generation examples. ## Newsletter Integration Help subscribers with: * Content recommendations * Archive searching * Subscription questions * Member benefits ## Tips for Ghost Works with all official and custom Ghost themes No impact on SEO or page speed Help subscribers find content Assist paid and free members ## Advanced: Custom Theme Integration If you have access to your Ghost theme files, you can add the code directly: ### Via default.hbs Add to your theme's `default.hbs` file before the closing `` tag: ```handlebars theme={"system"} {{!-- Ghost outputs required footer scripts - always include this last --}} {{ghost_foot}} ``` ### Via Helpers Create a custom helper in your theme: ```javascript theme={"system"} // core/server/helpers/invent.js module.exports = function invent(options) { return new SafeString( '' ); }; ``` ## Ghost(Pro) vs Self-Hosted ### Ghost(Pro) * Use Code Injection method (recommended) * No server access needed * Works out of the box ### Self-Hosted Ghost * Can use Code Injection or theme files * Full customization available * Can implement advanced authentication ## Troubleshooting **Solutions:** * Verify code is in Site Footer, not Site Header * Check assistant ID is correct * Clear Ghost cache (Settings → Labs → Delete all content cache) * Test in incognito mode **Solutions:** * Check theme's z-index values * Try adding code to theme files instead of Code Injection * Update to latest Ghost version **Solutions:** * Ensure Code Injection applies to member pages * Check membership settings * Test while logged in as a member ## Popular Ghost Themes Tested and working with: * **Casper** (default theme) * **Headline** * **Edition** * **Solo** * **Journal** * **Massively** * And all other official Ghost themes # Joomla Source: https://docs.useinvent.com/assistants/widget/install/joomla Add your Invent assistant to Joomla sites ## Overview Add your Invent AI assistant to any Joomla website with a floating bubble. Perfect for community sites, corporate websites, and portals. ## Installation ### Method 1: Custom HTML Module (Easiest) Go to **Extensions** → **Modules** → **New** Choose **Custom HTML** as the module type * **Title:** Invent Assistant * **Show Title:** No * **Position:** Choose a position (usually **footer** or **debug**) * **Status:** Published In the **Custom Output** field, switch to editor and paste: ```html theme={"system"} ``` Replace `YOUR_ASSISTANT_ID` with your actual assistant ID. In the **Menu Assignment** tab, select **On all pages** or choose specific menu items Click **Save & Close** ### Method 2: Template Override Add directly to your template: ```php theme={"system"} renderModule('footer'); ?> ``` ### Method 3: Using a Plugin Create a system plugin: ```php theme={"system"} '; $script .= ''; $doc->addCustomTag($script); } } ``` ## Customization ### Match Your Joomla Template ```html theme={"system"} ``` ### Show Only on Specific Components In your Custom HTML module settings: 1. Go to **Menu Assignment** tab 2. Select **Only on the pages selected** 3. Choose specific menu items (e.g., only on Articles, or only on com\_content) ### Component-Specific Display ```php theme={"system"} input->getCmd('option', ''); // Only show on com_content (articles) if ($option == 'com_content') { ?> ``` ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. Pass Joomla user information to provide personalized experiences: ```php theme={"system"} guest) { $secretKey = 'your_secret_key_here'; $userId = (string) $user->id; $userName = $user->name; $userHash = hash_hmac('sha256', $userId, $secretKey); ?> ``` ## Tips for Joomla Compatible with both Joomla 3.x and 4.x Works with Joomla multilingual sites Perfect for e-commerce support Help forum and community members ## Extension Compatibility Works seamlessly with: * **K2** - Advanced content management * **VirtueMart** - E-commerce * **HikaShop** - Online store * **JomSocial** - Social networking * **Community Builder** - User profiles * **JEvents** - Event management ## Module Positions Common positions for the assistant: * **debug** - Bottom of page (recommended) * **footer** - Footer area * **user3** - Various template positions * Custom position in your template ## Troubleshooting **Solutions:** * Verify module is Published * Check module position exists in template * Ensure "Show Title" is set to No * Clear Joomla cache (System → Clear Cache) * Check Menu Assignment settings **Solutions:** * Verify position exists in your template * Try using "debug" position (always available) * Check template's templateDetails.xml for valid positions **Solutions:** * Check for JavaScript conflicts in browser console * Adjust module ordering * Try different module position * Update to latest template version ## Joomla Version Compatibility * **Joomla 3.x:** Fully supported * **Joomla 4.x:** Fully supported * **Joomla 5.x:** Fully compatible (when released) ## Popular Joomla Templates Tested with: * **Helix Ultimate** * **JA Templates** * **Gantry 5** * **T3 Framework** * **Warp Framework** * **RocketTheme** * And most other Joomla templates ## Cache Considerations If using Joomla cache: 1. Go to **System** → **Global Configuration** → **System** tab 2. Clear cache after adding the assistant 3. Consider excluding the module from cache if needed # Next.js Source: https://docs.useinvent.com/assistants/widget/install/nextjs Add your Invent assistant to Next.js apps ## Overview Add your Invent AI assistant to any Next.js application (App Router or Pages Router). Perfect for React-based applications with server-side rendering and static generation. ## Installation ### App Router (Next.js 13+) Create a client component for the assistant: ```tsx theme={"system"} // components/InventAssistant.tsx 'use client'; interface InventAssistantProps { assistantId: string; themeAppearance?: 'auto' | 'light' | 'dark'; themeButtonBackgroundColor?: string; userId?: string; userName?: string; userHash?: string; } export default function InventAssistant({ assistantId, themeAppearance = 'auto', themeButtonBackgroundColor, userId, userName, userHash, }: InventAssistantProps) { return ( <> ``` ```vue theme={"system"} ``` Add to `nuxt.config.ts`: ```typescript theme={"system"} export default defineNuxtConfig({ runtimeConfig: { inventSecretKey: process.env.INVENT_SECRET_KEY, // Private public: { inventAssistantId: process.env.NUXT_PUBLIC_INVENT_ASSISTANT_ID, }, }, }); ``` Add to `.env`: ```bash theme={"system"} NUXT_PUBLIC_INVENT_ASSISTANT_ID=ast_YOUR_ASSISTANT_ID INVENT_SECRET_KEY=your_secret_key_here ``` ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. ### Server-Side Hash Generation Use Nuxt server routes to generate the hash securely: ```typescript theme={"system"} // server/api/user-hash.get.ts import crypto from 'crypto'; export default defineEventHandler(async (event) => { // Get user from your auth system const session = await getUserSession(event); if (!session?.user) { throw createError({ statusCode: 401, message: 'Unauthorized', }); } const config = useRuntimeConfig(); const userId = session.user.id; const userHash = crypto .createHmac('sha256', config.inventSecretKey) .update(userId) .digest('hex'); return { userId, userName: session.user.name, userHash, }; }); ``` ### Using in Component ```vue theme={"system"} ``` ## Integration with Nuxt Auth ### Using @sidebase/nuxt-auth ```vue theme={"system"} ``` ## TypeScript Support Add type declarations: ```typescript theme={"system"} // types/invent-assistant.d.ts declare module 'vue' { export interface GlobalComponents { 'invent-assistant': { 'assistant-id': string; 'theme-appearance'?: 'auto' | 'light' | 'dark'; 'theme-button-background-color'?: string; 'user-id'?: string; 'user-name'?: string; 'user-hash'?: string; }; } } export {}; ``` ## Composable for Authentication Create a reusable composable: ```typescript theme={"system"} // composables/useInventAuth.ts export const useInventAuth = () => { const userData = useState<{ userId: string; userName: string; userHash: string; } | null>('inventUserData', () => null); const fetchUserAuth = async () => { try { const data = await $fetch('/api/user-hash'); userData.value = data; } catch (error) { userData.value = null; } }; return { userData: readonly(userData), fetchUserAuth, }; }; ``` Usage: ```vue theme={"system"} ``` ## Tips for Nuxt Use server routes for secure hash generation Create reusable composables for auth logic Works with SSR, SSG, and SPA modes Full TypeScript support ## Troubleshooting **Solutions:** * Ensure plugin is client-side only (`.client.ts`) * Check that script loads after component mounts * Verify URL is correct * Check browser console for errors **Solutions:** * Use `ClientOnly` component if needed * Ensure script loads client-side only * Check that user data is fetched client-side **Solutions:** * Restart dev server after adding env variables * Check `nuxt.config.ts` runtimeConfig * Use `NUXT_PUBLIC_` prefix for public variables * Keep secret key private (no prefix) ## Best Practices * Use server routes for hash generation * Keep secret key in `.env` (never commit) * Use composables for reusable logic * Test in both SSR and SPA modes * Leverage Nuxt's built-in security features # Remix Source: https://docs.useinvent.com/assistants/widget/install/remix Add your Invent assistant to Remix apps ## Overview Add your Invent AI assistant to any Remix application. Perfect for full-stack React applications with nested routing and progressive enhancement. ## Installation ```tsx theme={"system"} // app/components/InventAssistant.tsx interface InventAssistantProps { assistantId: string; themeAppearance?: 'auto' | 'light' | 'dark'; themeButtonBackgroundColor?: string; userId?: string; userName?: string; userHash?: string; } export default function InventAssistant({ assistantId, themeAppearance = 'auto', themeButtonBackgroundColor, userId, userName, userHash, }: InventAssistantProps) { return ( <> ``` Replace `ast_YOUR_ASSISTANT_ID` with your actual assistant ID from the Invent dashboard. Click **Save** and the bubble will appear on all pages of your store. ## Customization ### Match Your Store Branding ```liquid theme={"system"} ``` ### Show Only on Specific Pages Use Shopify Liquid to control where the bubble appears: ```liquid theme={"system"} {% if template == 'product' or template == 'collection' %} {% endif %} ``` ## Customer Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. Pass Shopify customer data to Invent for personalized shopping assistance. **Important:** Shopify Liquid cannot generate HMAC hashes securely. You'll need to use a Shopify app or custom backend endpoint to generate the `user-hash` before passing it to the frontend. Without proper hash generation, omit all `user-*` attributes and let the assistant create an anonymous session. ```liquid theme={"system"} {% if customer %} {%- comment -%} Note: user-hash must be generated by a Shopify app or backend service. Do not use customer data without a valid hash. {%- endcomment -%} {% else %} {% endif %} ``` ## E-commerce Features Answer product questions in real-time Help customers track their orders Assist with abandoned cart recovery Provide sizing and fit guidance ## Shopify Plus Features For Shopify Plus stores, you can use Scripts or Checkout Extensions: ### Add to Checkout Pages 1. Go to **Settings** → **Checkout** 2. Scroll to **Additional scripts** 3. Add the bubble code ```html theme={"system"} ``` ## Troubleshooting **Solutions:** * Verify code is before closing `` tag in theme.liquid * Clear browser cache and reload * Check for JavaScript errors in browser console * Ensure theme doesn't have conflicting chat apps **Solutions:** * Check if other chat/help apps are installed * Adjust z-index in theme CSS if needed * Contact support for app compatibility ## Popular Shopify App Compatibility ✅ Works with Klaviyo, Yotpo, Judge.me, and other popular Shopify apps # Squarespace Source: https://docs.useinvent.com/assistants/widget/install/squarespace Add your Invent assistant to Squarespace sites ## Overview Add your Invent AI assistant to any Squarespace website with a floating bubble. Perfect for small businesses, portfolios, blogs, and online stores. ## Installation Log in to your Squarespace account and select your site. Go to **Settings** → **Advanced** → **Code Injection**. Scroll to the **Footer** section and paste this code: ```html theme={"system"} ``` Replace `YOUR_ASSISTANT_ID` with your actual assistant ID from the Invent dashboard. Click **Save**, then refresh your site to see the assistant appear. ## Customization ### Match Your Squarespace Design ```html theme={"system"} ``` ### Show Only on Specific Pages For page-specific installation: 1. Navigate to the specific page in Squarespace 2. Click **Settings** (gear icon) for that page 3. Go to **Advanced** → **Page Header Code Injection** 4. Add the code there instead of site-wide footer ## Squarespace Commerce For e-commerce sites on Squarespace: * Help customers with product questions * Provide size guides and fit information * Answer shipping and return policy questions * Assist with order tracking The assistant appears on all pages including product and checkout pages. ## Member Areas **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. For sites with member-only content, Squarespace does not provide built-in server-side scripting for hash generation. You'll need to use an external service (like a serverless function) to generate the hash securely, or use the basic implementation without authentication: ```html theme={"system"} ``` See the [Widget Authentication](/assistants/widget#user-authentication-optional) guide for hash generation examples that you can deploy as serverless functions. ## Tips for Squarespace Works with all Squarespace templates Optimized for mobile layouts Perfect for blog post questions Boost sales with instant support ## Version Compatibility Works with both Squarespace 7.0 and 7.1. Code Injection is available on Business and Commerce plans. ## Advanced: Custom CSS Style the bubble position if needed: ```html theme={"system"} ``` ## Troubleshooting **Solutions:** * Verify you have Business or Commerce plan (required for Code Injection) * Check code is in Footer section, not Header * Clear browser cache and hard refresh (Cmd+Shift+R or Ctrl+Shift+R) * Verify assistant ID is correct **Solutions:** * Check z-index if bubble is hidden * Disable Squarespace's built-in chat if using Invent * Adjust bubble position with custom CSS **Solutions:** * Code Injection applies to all devices by default * Test on actual mobile device, not just browser resize * Check mobile view in Squarespace preview ## Template-Specific Notes ### Brine Family Templates Works perfectly with all Brine family templates (Bedford, Bryant, etc.) ### Avenue Family Templates Compatible with Avenue, Bedford, and all related templates ### Five Family Templates Fully compatible with all Five-based templates ### Skye Family Templates No conflicts with Skye or Pacific templates # SvelteKit Source: https://docs.useinvent.com/assistants/widget/install/sveltekit Add your Invent assistant to SvelteKit apps ## Overview Add your Invent AI assistant to any SvelteKit application. Perfect for Svelte applications with server-side rendering and static generation. ## Installation ```svelte theme={"system"} ``` ```` ```svelte ```` Add to `.env`: ```bash theme={"system"} PUBLIC_INVENT_ASSISTANT_ID=ast_YOUR_ASSISTANT_ID INVENT_SECRET_KEY=your_secret_key_here ``` ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. ### Server-Side Hash Generation Use SvelteKit server endpoints: ```typescript theme={"system"} // src/routes/api/user-hash/+server.ts import { json } from '@sveltejs/kit'; import { createHmac } from 'crypto'; import { INVENT_SECRET_KEY } from '$env/static/private'; import type { RequestHandler } from './$types'; export const GET: RequestHandler = async ({ locals }) => { // Get user from your auth system (e.g., lucia, session) const user = locals.user; if (!user) { return json({ error: 'Unauthorized' }, { status: 401 }); } const userId = user.id; const userHash = createHmac('sha256', INVENT_SECRET_KEY) .update(userId) .digest('hex'); return json({ userId, userName: user.name, userHash, }); }; ``` ### Using Server Load Functions ```typescript theme={"system"} // src/routes/+layout.server.ts import { createHmac } from 'crypto'; import { INVENT_SECRET_KEY } from '$env/static/private'; import type { LayoutServerLoad } from './$types'; export const load: LayoutServerLoad = async ({ locals }) => { const user = locals.user; if (!user) { return { userData: null }; } const userId = user.id; const userHash = createHmac('sha256', INVENT_SECRET_KEY) .update(userId) .digest('hex'); return { userData: { userId, userName: user.name, userHash, }, }; }; ``` Then use in your layout: ```svelte theme={"system"} ``` ## Integration with Lucia Auth ```typescript theme={"system"} // src/routes/+layout.server.ts import { createHmac } from 'crypto'; import { INVENT_SECRET_KEY } from '$env/static/private'; import type { LayoutServerLoad } from './$types'; export const load: LayoutServerLoad = async ({ locals }) => { const session = await locals.auth.validate(); if (!session?.user) { return { userData: null }; } const userId = session.user.userId; const userHash = createHmac('sha256', INVENT_SECRET_KEY) .update(userId) .digest('hex'); return { userData: { userId, userName: session.user.name, userHash, }, }; }; ``` ## TypeScript Support Add type declarations: ```typescript theme={"system"} // src/app.d.ts declare global { namespace App { interface Locals { user?: { id: string; name: string; avatar?: string; }; } } namespace svelteHTML { interface HTMLAttributes { 'assistant-id'?: string; 'theme-appearance'?: 'auto' | 'light' | 'dark'; 'theme-button-background-color'?: string; 'user-id'?: string; 'user-name'?: string; 'user-hash'?: string; } } } export {}; ``` ## Using Stores Create a store for user authentication: ```typescript theme={"system"} // src/lib/stores/inventAuth.ts import { writable } from 'svelte/store'; import { browser } from '$app/environment'; interface UserData { userId: string; userName: string; userHash: string; } function createInventAuthStore() { const { subscribe, set } = writable(null); return { subscribe, fetchUserAuth: async () => { if (!browser) return; try { const response = await fetch('/api/user-hash'); const data = await response.json(); set(data); } catch (error) { set(null); } }, clear: () => set(null), }; } export const inventAuth = createInventAuthStore(); ``` Usage: ```svelte theme={"system"} ``` ## Tips for SvelteKit Use server load for secure hash generation Full TypeScript support with proper types Works with SSR and SPA modes Leverage Svelte's reactivity system ## Troubleshooting **Solutions:** * Check browser guard: `if (browser)` * Ensure script loads in onMount * Verify URL is correct * Check browser console for errors **Solutions:** * Use browser check before accessing window * Load script client-side only * Ensure user data is fetched client-side if needed **Solutions:** * Restart dev server after adding env variables * Use `PUBLIC_` prefix for public variables * Keep secret key without prefix (private) * Check import from correct \$env module ## Best Practices * Use server load functions or endpoints for hash generation * Keep secret key in `.env` (never commit) * Use `PUBLIC_` prefix only for non-sensitive variables * Always check `browser` before accessing window * Leverage SvelteKit's built-in security features # Webflow Source: https://docs.useinvent.com/assistants/widget/install/webflow Add your Invent assistant to Webflow sites ## Overview Add your Invent AI assistant to any Webflow site with a floating bubble. Perfect for providing instant support to your Webflow site visitors. ## Installation In Webflow Designer, click the **Settings** icon (gear) in the left sidebar. Go to the **Custom Code** tab at the top. Scroll down to **Footer Code** and paste this code: ```html theme={"system"} ``` Replace `ast_YOUR_ASSISTANT_ID` with your actual assistant ID from the Invent dashboard. Click **Save Changes** and then **Publish** your site. The bubble will now appear on all pages. ## Customization ### Match Your Brand Colors ```html theme={"system"} ``` ### Show Only on Specific Pages For page-specific installation: 1. Open the page in Webflow Designer 2. Click **Settings** (gear icon) for that page 3. Go to **Custom Code** tab 4. Add the code to **Before closing body tag** ## Using Webflow CMS If you're using Webflow CMS, you can add the bubble to collection templates: 1. Open your **Collection Template** page 2. Add an **Embed** element where you want the assistant 3. Paste the bubble code 4. The assistant will appear on all collection pages ## User Authentication **User Authentication Requires External Service:** Webflow does not provide server-side scripting capabilities to securely generate the `user-hash` required for user authentication. To use user-specific features with Webflow Memberships, you **must** set up an external backend service or serverless function to generate the hash. Both `user-id` and `user-hash` must be provided together, generated using HMAC-SHA256 with your assistant's secret key. For most Webflow sites, use the basic implementation without authentication: ```html theme={"system"} ``` ### Advanced: With External Authentication Service If you've set up an external service to generate user hashes: ```html theme={"system"} ``` See the [Widget Authentication](/assistants/widget#user-authentication-optional) guide for hash generation examples that you can deploy as serverless functions. ## Tips for Webflow The button automatically adapts to mobile and tablet layouts Button floats above all content by default. Adjust if needed. Using async/defer ensures no impact on page speed Works seamlessly with Webflow interactions and animations ## Troubleshooting **Solutions:** * Verify the code is in the Footer Code section * Clear Webflow cache and republish * Check browser console for errors * Ensure assistant ID is correct **Solutions:** * Check for z-index conflicts in custom CSS * Verify no other chat widgets are installed * Test with Webflow Designer interactions disabled # Weebly Source: https://docs.useinvent.com/assistants/widget/install/weebly Add your Invent assistant to Weebly sites ## Overview Add your Invent AI assistant to any Weebly website with a floating bubble. Perfect for small businesses, portfolios, and online stores built on Weebly. ## Installation Log in to your Weebly account and open your site in the Weebly Editor. Click **Settings** in the top left corner, then select **SEO** from the sidebar. Scroll down to **Footer Code** section and paste this code: ```html theme={"system"} ``` Replace `YOUR_ASSISTANT_ID` with your actual assistant ID from the Invent dashboard. Click **Save** at the top, then **Publish** your site. The bubble will now appear on all pages. ## Alternative Method: Embed Element For more control over placement, you can use Weebly's Embed Code element: In the Weebly editor, drag the **Embed Code** element from the **Basic** section to your desired location. Click on the element and select **Edit Custom HTML**. Paste the assistant code: ```html theme={"system"} ``` The bubble will appear on pages where you've added the embed element. ## Customization ### Match Your Weebly Theme ```html theme={"system"} ``` ### Show on Specific Pages Only Instead of adding to Footer Code (all pages), use the Embed Element method and add it only to specific pages where you want the assistant to appear. ## Weebly eCommerce Integration For Weebly stores, the assistant can help customers with: * Product questions and recommendations * Shipping and delivery information * Order status inquiries * Return and refund policies * Size guides and product details The assistant will automatically appear on all store pages when added to Footer Code. ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. Weebly does not provide built-in server-side scripting for hash generation. For sites requiring user authentication, you'll need to use an external service (such as a serverless function) to generate the hash securely. For most Weebly sites, use the basic implementation without authentication: ```html theme={"system"} ``` See the [Widget Authentication](/assistants/widget#user-authentication-optional) guide for hash generation examples that you can deploy as serverless functions. ## Tips for Weebly Works with all Weebly themes and templates Automatically adapts to mobile layouts Perfect for Weebly stores and product support Simple copy-paste installation ## Weebly Plan Requirements The Footer Code feature requires a Weebly Pro, Business, or Performance plan. Free Weebly sites can use the Embed Element method instead. ## Troubleshooting **Solutions:** * Verify you have a Pro, Business, or Performance plan for Footer Code * Check that code is in Footer Code section, not Header Code * Clear browser cache and hard refresh (Cmd+Shift+R or Ctrl+Shift+R) * Verify assistant ID is correct * Try using Embed Element method instead **Solutions:** * Check if code is added in both Footer Code and Embed Elements * Remove duplicate code from either location * Only use one installation method **Solutions:** * Test on actual mobile device, not just browser resize * Check that code is in Footer Code (applies to all devices) * Clear mobile browser cache * Verify site is published after changes **Solutions:** * Check z-index if bubble is hidden behind elements * Adjust bubble position if needed * Ensure no other chat widgets are installed * Try different theme if conflicts persist ## Weebly App Center Currently, Invent is not available as a native Weebly App. Use the manual code installation method described above. We're working on creating an official Weebly App for easier installation. ## Advanced: Custom Positioning If you need to adjust the bubble position, add custom CSS: ```html theme={"system"} ``` ## Best Practices * Add to Footer Code for site-wide availability * Use Embed Element for page-specific installation * Test on both desktop and mobile devices * Customize colors to match your brand * Monitor visitor interactions in Invent dashboard ## Popular Use Cases ### Small Business Website Help visitors find information about services, hours, pricing, and contact details. ### Online Store Assist customers with product selection, shipping questions, and order support. ### Portfolio Site Answer questions about your work, availability, and booking inquiries. ### Restaurant Website Help customers with menu questions, reservations, and delivery options. ## Related Guides Looking for other website builder install guides? * [Wix](/assistants/widget/install/wix) - Similar drag-and-drop builder * [Squarespace](/assistants/widget/install/squarespace) - Design-focused platform * [WordPress](/assistants/widget/install/wordpress) - Most flexible CMS option # Wix Source: https://docs.useinvent.com/assistants/widget/install/wix Add your Invent assistant to Wix sites ## Overview Add your Invent AI assistant to any Wix website with a floating bubble. Perfect for small businesses, portfolios, and e-commerce sites built on Wix. ## Installation Log in to your Wix account and open your site in the Wix Editor. Click **Settings** in the left sidebar, then select **Custom Code** under **Advanced**. Click **+ Add Custom Code** and paste this code: ```html theme={"system"} ``` Replace `YOUR_ASSISTANT_ID` with your actual assistant ID. * Name your code snippet (e.g., "Invent Assistant") * Select **Load code once** or **Load code on each new page** * Choose **Body - end** as the placement * Select **All pages** or specific pages Click **Apply**, then **Publish** your site. ## Customization ### Match Your Wix Theme ```html theme={"system"} ``` ### Show on Specific Pages Only In the Custom Code settings: 1. Instead of **All pages**, select **Choose specific pages** 2. Pick the pages where you want the assistant to appear 3. Click **Apply** ## Wix Stores Integration For Wix e-commerce sites, you can help customers with: * Product questions * Shipping information * Order tracking * Size and fit guidance The assistant will appear on all store pages automatically if you selected "All pages". ## Wix Multilingual Sites The bubble automatically works with Wix multilingual sites. If your site supports multiple languages, the assistant will: * Detect the user's language * Respond in the appropriate language * Maintain consistency across language versions ## User Authentication **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. For Wix sites with member login, use Wix Velo (formerly Corvid) to generate the hash securely on the backend: ```javascript theme={"system"} // Backend code (Velo) - backend/getUserHash.jsw import { currentMember } from 'wix-members-backend'; import { createHmac } from 'crypto'; // Store your secret key in Wix Secrets Manager export async function getUserHash() { const member = await currentMember.getMember(); if (!member) { return null; } const secretKey = 'your_secret_key'; // Use Wix Secrets Manager in production const userId = member._id; const hash = createHmac('sha256', secretKey) .update(userId) .digest('hex'); return { userId: member._id, userName: `${member.contactDetails.firstName} ${member.contactDetails.lastName}`, userHash: hash }; } ``` Then call this from your frontend: ```javascript theme={"system"} // Frontend code import { getUserHash } from 'backend/getUserHash'; $w.onReady(async function () { const userAuth = await getUserHash(); if (userAuth) { // Set attributes on your invent-assistant element const assistant = document.querySelector('invent-assistant'); assistant.setAttribute('user-id', userAuth.userId); assistant.setAttribute('user-name', userAuth.userName); assistant.setAttribute('user-hash', userAuth.userHash); } }); ``` ## Tips for Wix Works with both Wix ADI and Editor X Automatically adapts to mobile views Help customers book appointments Answer menu and ordering questions ## Troubleshooting **Solutions:** * Ensure Custom Code is set to "Body - end" * Check that "All pages" or correct pages are selected * Verify assistant ID is correct * Publish your site (preview mode may not show custom code) **Solutions:** * Disable Wix Chat if using Invent * Go to **Settings** → **Chat** → Turn off * Both can coexist but may overlap visually **Solutions:** * Ensure custom code is set to load on mobile * Check mobile view settings in Wix * Test in actual mobile device, not just preview ## Wix Premium Required Custom code functionality requires a Wix Premium plan (not available on free sites). # WordPress Source: https://docs.useinvent.com/assistants/widget/install/wordpress Add your Invent assistant to WordPress sites ## Overview Add your Invent AI assistant to any WordPress site with a simple floating bubble. Your visitors can chat with your assistant without leaving your website. ## Quick Installation The easiest way to add Invent to your WordPress site is by adding the bubble code to your theme. ### Method 1: Invent WordPress Plugin (Recommended) The official Invent plugin requires no code. In your WordPress admin, go to **Plugins** → **Add New**, search for **Invent**, then install and activate the plugin. Go to **Settings** → **Invent** and paste your Assistant ID from the Invent dashboard. The bubble appears on all pages of your site. ### Method 2: Using a Code Snippets Plugin Install the free **Code Snippets** plugin from the WordPress plugin directory, or use any custom code plugin you prefer. Create a new snippet and paste this code: ```php theme={"system"} function add_invent_assistant() { ?> Save the snippet and activate it. The bubble will now appear on all pages of your site. ### Method 3: Edit Theme Files Directly Make sure to use a child theme to prevent losing your changes when the theme updates. Navigate to **Appearance** → **Theme File Editor** and open your theme's `functions.php` file. Add this code at the end of the file: ```php theme={"system"} function add_invent_assistant() { ?> Click **Update File** to save your changes. ### Method 4: Using a Page Builder If you're using Elementor, Divi, or another page builder: 1. Add a **Custom HTML** or **Code** widget to your header/footer template 2. Paste the bubble code: ```html theme={"system"} ``` ## Customization ### Change Button Colors Match the bubble to your WordPress theme: ```php theme={"system"} function add_invent_assistant() { ?> **Security Requirement:** When using any `user-*` attributes (`user-id`, `user-name`), you **must** also provide `user-hash`. Both `user-id` and `user-hash` must be provided together, or neither should be provided. The `user-hash` must be generated on your backend using HMAC-SHA256 with your assistant's secret key. Never expose the secret key to the client. Pass WordPress user information to Invent for personalized experiences: ```php theme={"system"} function add_invent_assistant() { $secret_key = 'your_secret_key_here'; // Get from Invent dashboard if (is_user_logged_in()) { $current_user = wp_get_current_user(); $user_id = (string) $current_user->ID; $user_name = $current_user->display_name; // Generate secure hash $user_hash = hash_hmac('sha256', $user_id, $secret_key); ?> **Possible causes:** * Code not added correctly * JavaScript conflicts * Theme compatibility issues **Solutions:** * Check browser console for JavaScript errors * Temporarily disable other plugins to check for conflicts * Verify the code is in the `wp_footer` hook * Clear WordPress cache if using a caching plugin **Possible causes:** * Code added in multiple places * Theme already includes footer scripts **Solutions:** * Remove duplicate code snippets * Use only one integration method **Possible causes:** * Theme CSS interfering with button * Z-index conflicts **Solutions:** * Add custom CSS to your theme * Adjust button positioning if needed ## Popular Plugin Compatibility The bubble works seamlessly with popular WordPress plugins: Perfect for e-commerce support and product questions Add via Custom HTML widget in header/footer templates Works with multilingual sites automatically No impact on SEO or page speed ## Best Practices * Store your secret key in `wp-config.php` using `define()` for security * Use a child theme to prevent losing changes during theme updates * Test on staging environment before deploying to production * Consider page load times when adding authentication logic # Contacts Source: https://docs.useinvent.com/guides/audience Manage your contacts, organize them into segments, and build targeted audiences for broadcasts Every customer who has ever messaged your assistant through WhatsApp, Instagram, web chat, or any other channel is already part of your audience. The **Audience** page is where you manage these contacts, organize them into segments, and build the foundation for powerful broadcasts. *Think about it: every person who reaches out to your business through any channel becomes a contact you can re-engage later. Send them product updates via WhatsApp, promotions via email, or announcements across multiple channels at once.* Your audience is the foundation for [Broadcasts](/guides/broadcasts/introduction). Organize contacts into segments here, then use those segments to send targeted messages at scale. Audience Overview The Audience section in the sidebar has four pages: **Contacts**, **[Segments](/guides/audience/segments)**, **[Properties](/guides/audience/properties)**, and the **[Suppression List](/guides/audience/suppression)**. ## Contacts The Contacts page shows every person in your audience. Each contact displays: * **Name and identifier**: The contact's name along with their email or phone number * **Status**: The contact's subscription state (Subscribed / Unsubscribed / Blocked, plus an AI-replies-off indicator) * **Segments**: Any segments they belong to (shown as badges) * **Channels**: Icons showing which channels they've interacted through (web chat, WhatsApp, Telegram, etc.) * **Created date**: When the contact was first added You can search for any contact by name using the search bar, filter your list by segment using the **Filter by segment** dropdown, or filter by subscription status using the status dropdown (All Contacts, Subscribed, Unsubscribed, Blocked, AI replies off). ### Adding Contacts Click **+ Add Contacts** in the top-right corner to see two options: * **Add manually**: Create a single contact by entering their details * **Import Contacts**: Bulk import contacts from a CSV, Excel, Numbers or OpenDocument file #### Add Manually To add a single contact: A dialog opens with fields for the contact's information. Fill in the following fields: * **Full Name** (Optional): The contact's display name * **Email** (Optional): Their email address * **Phone** (Optional): Their phone number with country code selector At least one of Email or Phone is required. Use the **Segments** dropdown to assign this contact to one or more segments. You can search and select from your existing segments. The contact is created and appears in your contacts list immediately. Add Contact Manually Button Add Contact Manually #### Import Contacts Import Contacts Button To import contacts in bulk from a spreadsheet: The import page opens with a file upload area. Drag and drop a **.csv**, **.xlsx**, **.xls**, **.numbers**, or **.ods** file into the upload area, or click to browse. The first row of your file should contain column headers (like "Full Name", "Email", "Phone"). Click **Download sample CSV** at the bottom to get a template file with the correct format. Import Contacts Below the upload area, you can optionally assign all imported contacts to a specific segment using the **Segment** dropdown. After uploading, Invent shows a mapping table with three columns: | Column | Description | | ---------------- | ------------------------------------ | | **CSV Column** | The column name from your file | | **Sample Data** | A preview of the data in that column | | **Map to Field** | The Invent field to map it to | For each column, choose a mapping: * **Do not import**: Skip this column entirely * **Full Name**: Map to the contact's full name * **First Name**: Map to the contact's first name * **Last Name**: Map to the contact's last name * **Email**: Map to the contact's email address * **Phone**: Map to the contact's phone number At least one of **Email** or **Phone** must be mapped to continue. Name is optional. Map Columns Click **Review** to see a preview table of all the contacts that will be imported. Verify the data looks correct before proceeding. Rows are tagged so you can see what will happen to each one. Use the chips above the table to filter to **Valid**, **Merged**, or **Invalid**. If the same email or phone appears on more than one row, those rows are merged into a single contact and tagged **Merged**. The first row for that person wins, so put the values you want to keep on its first occurrence. Review and Import Click **Import**. A confirmation dialog appears asking you to confirm that you have obtained appropriate consent to send messages to these contacts in compliance with applicable laws and regulations. Click **Import** to confirm, and your contacts are added to the audience. Once the import completes, you'll see a success message confirming how many contacts were imported (e.g., "3 contacts imported successfully"). ### Contact Profile Click on any contact in the list to open their profile panel on the right side. The panel is organized into three tabs across the top: **Contact**, **Files**, and **Activity**. #### Contact tab The Contact tab shows everything Invent knows about this person, in order: **Segments** The segments this contact belongs to. You can add or remove segments directly from here by clicking the segment dropdown. Remove a segment by clicking the **x** next to its name. **Profile** Detailed contact information including: * **Name**: The contact's display name (click the pencil icon to edit) * **Username**: The contact's handle on channels that provide one (e.g. Telegram, Instagram), shown as @handle * **Country**: Detected country with flag * **Phone**: Phone number with channel icon (e.g., WhatsApp) * **Link**: Direct link to message them (e.g., a `wa.me` link for WhatsApp contacts) **Properties** The values of your custom [contact properties](/guides/audience/properties) (e.g., a loyalty tier or a marketing opt-in), editable inline. **Memories** Facts your assistants have remembered about this contact from their conversations. When there are none, Invent shows "Generated memories will appear here." **Files** A preview of files shared in this contact's chats and notes. The full list lives in the **Files** tab. **Conversations** A history of all conversations this contact has had with your assistants. Each row shows a status icon, the conversation title, and the time it was last updated. **Broadcasts** A list of all broadcasts this contact has received, along with their engagement status (e.g., "Opened") and the broadcast name. #### Files tab The **Files** tab aggregates every file shared with this contact across chats and notes. When there are none, it shows "Files from chats and notes will appear here." #### Activity tab The **Activity** tab is a chronological timeline of what has happened to this contact: segment assignments and moves, comments, file uploads, property edits, and moderation events such as block/unblock, unsubscribe/resubscribe, and AI replies being turned on or off. #### Contact actions Click the three-dot menu at the top of the contact profile for additional actions: * **Turn AI replies on/off**: Stop or resume your assistants replying to this contact automatically. * **Unsubscribe / Resubscribe**: Unsubscribing stops marketing emails and broadcasts; the contact can still message you and get replies. Resubscribing resumes them. * **Block / Unblock**: Blocking stops new messages from this contact being stored. This does not block them on external channels like WhatsApp or Instagram. Unblocking starts accepting their messages again. * **Delete**: Permanently remove the contact. Turning AI replies on/off, unsubscribing, and blocking are available to contacts managers. These moderation and consent controls matter for GDPR and marketing-consent workflows. ## Segments Segments let you group contacts together for easy targeting. Instead of broadcasting to your entire audience, you can send messages to specific groups, like "VIP Customers", "Newsletter Subscribers", or "Beta Testers". Segments List See the [Segments guide](/guides/audience/segments) for creating, managing, and filling segments. ## Properties Properties are custom fields stored on every contact: a size preference, a loyalty tier, a renewal date. Define them once and they appear on every contact profile, ready to be filled manually, via the API, or automatically by your assistants. See the [Properties guide](/guides/audience/properties) for the available types and how to manage them. ## Suppression List The suppression list is your workspace's do-not-contact list, keyed by email address and phone number. Bounces, spam complaints and unsubscribes land there automatically, and nothing on it receives a broadcast or an automated message again. See the [Suppression List guide](/guides/audience/suppression) for what it blocks, how to add entries, and how to import a list from another tool. ## Best Practices 1. **Create segments early**: Set up segments like "Promotions", "Product Updates", and "VIP" before you start broadcasting. This makes targeting much easier later 2. **Capture data with properties**: Define properties for the contact data your business cares about, and let assistants keep them up to date 3. **Keep your audience clean**: Regularly review and remove contacts who are no longer relevant 4. **Combine with broadcasts**: Segments are most powerful when used with broadcasts to send targeted messages to the right people at the right time ## Next Steps Group contacts for targeted broadcasts Store custom data on every contact Send targeted messages to your audience via WhatsApp and more Manage all customer conversations in one unified space # Properties Source: https://docs.useinvent.com/guides/audience/properties Define custom fields that store extra information on every contact Properties are custom fields stored on every contact. Out of the box, a contact has a name, email, and phone. Properties let you capture everything else your business cares about: a size preference, a loyalty tier, a renewal date, a marketing opt-in. Open **Audience → Properties** in the sidebar to manage them. Properties List Each property shows its name, its type, and details like the options of a Select property. Only admins and developers can create or edit contact properties. Other members see the values on contacts but cannot change the property definitions. ## Property Types | Type | Best for | | ---------------- | --------------------------------------------------- | | **Text** | Short free-form values (e.g. a referral source) | | **Long text** | Notes and multi-line values | | **URL** | Links (e.g. a LinkedIn profile) | | **Email** | Additional email addresses | | **Phone** | Additional phone numbers | | **Number** | Quantities and scores (e.g. loyalty points) | | **Currency** | Money amounts (e.g. lifetime spend) | | **Checkbox** | Yes/no flags (e.g. marketing opt-in) | | **Date** | Dates without a time (e.g. birthday) | | **Date & time** | Timestamps (e.g. last purchase) | | **Select** | One option from a fixed list (e.g. loyalty tier) | | **Multi-select** | Multiple options from a fixed list (e.g. interests) | ## Adding a Property A menu opens where you can search and pick the property type. Choose the type that matches the data you want to store. For Select and Multi-select, you define the list of options, each with its own color. Give the property a clear name (e.g., "Loyalty Tier"). The property immediately appears on every contact profile. Each assistant can have up to 32 contact properties. Once you reach the limit, remove an existing property before adding another. Add Property ## Managing Properties From the Properties page you can: * **Rename a property** by clicking its name * **Reorder properties** by dragging the handle that appears on hover. The order here is the order shown on contact profiles * **Edit options** via the three-dot menu: change the option list of a Select property, tweak formatting, or delete the property Deleting a property permanently removes its values from all contacts. ## Properties on the Contact Profile Every property appears in the **Properties** section of the contact profile panel, where you can view and edit values inline. Contact Properties ## Let Your Assistant Fill Properties Properties become really powerful combined with your AI assistants. With the **Update Contact Info** capability enabled, an assistant saves contact details (name, email, phone, and any custom properties) directly to the contact profile as it learns them in conversation. For example, when a customer mentions they usually wear a size M, the assistant can set the "Size" property on their contact, no manual data entry needed. To enable it: Go to **Assistants**, pick your assistant, and scroll to the **Contact Properties** section of the Settings tab. This lets the assistant save contact details directly to the contact profile. Each property starts as **Hidden**. Choose what the assistant may do with it: * **Hidden**: The assistant cannot see the property * **Visible**: The assistant can see the property during conversations * **AI Controlled**: The assistant can see and update the property Click **Save Changes**. The assistant applies the new access on its next conversation. Assistant Contact Properties Configuration Visibility is per assistant, so a support assistant can update a "Size" property while a billing assistant cannot even see it. See [Assistant Configuration](/assistants/introduction#assistant-configuration) for the rest of the assistant settings. ## Setting Values via the API Developers can set property values programmatically when creating or updating contacts through the [API](/api-reference/getting-started/introduction), using the property keys defined on this page. ## Best Practices 1. **Start small**: A handful of properties your team actually fills beats a long list of empty fields 2. **Prefer Select over Text** for anything with known values: options keep data consistent and filterable 3. **Name properties for humans**: "Loyalty Tier" is better than "tier\_lvl" 4. **Pair with assistants**: Let the AI keep properties up to date automatically with the Update Contact Info capability ## Next Steps Group contacts for targeted broadcasts Enable Update Contact Info and other assistant powers # Segments Source: https://docs.useinvent.com/guides/audience/segments Group contacts into segments to target the right people with broadcasts Segments let you group contacts together for easy targeting. Instead of broadcasting to your entire audience, you can send messages to specific groups, like "VIP Customers", "Newsletter Subscribers", or "Beta Testers". Open **Audience → Segments** in the sidebar to see all your segments. Segments List Each segment shows: * **Color and Name**: The segment's color dot and name * **Contacts**: How many contacts are in this segment * **Created At**: When the segment was created * **Updated At**: When the segment was last modified Use the search bar to find a segment by name. Segments are the foundation for [Broadcasts](/guides/broadcasts/introduction). When you create a broadcast, you pick the segments to send it to, so a well-organized audience makes targeting effortless. ## Creating a Segment A dialog appears with fields for the segment name and color. Give your segment a descriptive name (e.g., "VIP Customers", "Product Updates", "Beta Users"). Choose a color from the palette. The color appears as a dot next to the segment badge throughout the app, making it easy to visually distinguish segments in the contacts list, contact panel, and filters. Your new segment is created. It starts with 0 contacts. Add Segment ## Managing a Segment Click on any segment to see the contacts within it. Segment Detail From this view, you can: * **Search contacts** within the segment * **Add contacts** to the segment (manually or via import) * **Rename the segment** by clicking its name in the header * **Change the color** by clicking the color dot next to the name Back in the segments list, use the three-dot menu next to each segment to rename or delete it. Deleting a segment does not delete its contacts; they simply leave the group. ## How Contacts Get Added to Segments Contacts can be added to segments in several ways: 1. **When adding a contact manually**: Select segments during creation 2. **When importing contacts**: Assign all imported contacts to a segment 3. **From the contact profile**: Add or remove segments from the profile panel 4. **From within a segment**: Click **+ Add Contacts** while viewing a segment A contact can belong to multiple segments at once. ## Best Practices 1. **Create segments early**: Set up segments like "Promotions", "Product Updates", and "VIP" before you start broadcasting. This makes targeting much easier later 2. **Use descriptive names**: "Beta Users - iOS App" is better than "Group 1" 3. **Keep segments clean**: Regularly review and remove contacts who are no longer relevant 4. **Combine with broadcasts**: Segments are most powerful when used with broadcasts to send targeted messages to the right people at the right time ## Next Steps Send targeted messages to your segments via WhatsApp and more Store custom data on every contact with properties # Suppression List Source: https://docs.useinvent.com/guides/audience/suppression One do-not-contact list for your workspace, covering email addresses and phone numbers The suppression list is your workspace's do-not-contact list. Anything on it never receives a broadcast or an automated message again, on any channel, from any assistant. Open **Audience → Suppression List** in the sidebar. Suppression List The list is keyed by the **email address or phone number itself**, not by contact. That has three consequences worth knowing: * If two contacts share the same address, suppressing it stops both. * Deleting a contact does not bring the address back into circulation. * You can suppress an address that has no contact record at all, for example one a customer gave you by phone. ## What lands on the list automatically You rarely have to add anything by hand. Invent adds entries as it learns about them: | Reason | Added when | | :----------------- | :----------------------------------------------------------------------------- | | **Bounced** | The address hard-bounced, so the mailbox does not exist or refused the message | | **Marked as spam** | The recipient reported one of your emails as spam | | **Unsubscribed** | The recipient used the unsubscribe link in an email | | **Added manually** | Someone on your team added it in the app, imported it, or the API did | | **Legal request** | You added it to satisfy an erasure or do-not-contact request | The **Source** of each entry (visible in the detail panel) tells you how it arrived: a delivery event, an unsubscribe link, someone in the app, an import, or the API. ## What suppression blocks Suppression stops **outbound, automated messaging**. It never stops a conversation. | Message | Blocked | | :-------------------------------------------------------------- | :---------------------------------------------------------------- | | Marketing broadcasts | ✅ Always | | Transactional broadcasts (order confirmations, codes, receipts) | ⚠️ Only for **Bounced**, **Marked as spam** and **Legal request** | | An agent replying in the Inbox | ❌ Never | | Account emails (sign-in, password reset, invites) | ❌ Never | The middle row is the important one. "Stop sending me your newsletter" is not "never send me my one-time code", so an **Unsubscribed** or **Added manually** entry leaves transactional sends alone. An address that bounced, complained, or is under a legal request is blocked everywhere, because a message to it either cannot arrive or must not be sent. A suppressed recipient is not silently dropped from a broadcast. The send is skipped at delivery time and recorded as skipped in the broadcast's recipients, so you can see exactly who was left out and why. ## Finding an entry Use the search box to look up an exact address or number, and the two filters to narrow by **channel** (email or phone) or by **reason**. Click any row to open its details. Suppression entry details The panel shows the type, source, who added it, when, and any diagnostic detail the provider returned (the bounce code, the complaint type, or the feedback a recipient left when unsubscribing). You can change the **reason**, leave a **note** for your team, or **remove the entry from the list**. ## Adding an address or number Pick **Email** or **Phone** at the top of the dialog. Emails are lowercased and numbers are stored in international format, so the entry matches however it was written elsewhere. The reason decides how strictly the entry is enforced (see the table above). The note is free text for your team, for example a ticket number. Suppress an email or number ## Importing a list Migrating from another tool? Bring its suppression list with you before your first broadcast, so you never email an address that already opted out elsewhere. Click **Import**, then upload a `.csv`, `.xlsx`, `.xls`, `.numbers`, or `.ods` file with one email or phone number per row, and map the column. Upload a suppression file The review step tells you exactly what will happen before anything is written: how many rows are valid, which ones are not a usable email or number, and which are already on the list and will be skipped. Review a suppression import Importing never creates or changes contacts. It only adds entries to this list. ## Removing an entry Open the entry and click **Remove from list**. Broadcasts and automated messages can reach that address or number again from that moment on. Remove an entry only when you know the person asked to hear from you again. Sending to an address that bounced or complained hurts the deliverability of every email your workspace sends. ## Suppression and a contact's subscribed status These are two different things and both apply: * **Suppression** is about an address or number. It is workspace-wide and survives the contact. * A contact's **subscribed status** is about that one contact record. When you open a contact whose email or phone is suppressed, the contact card shows an alert saying so, so you are never surprised when they are missing from a send. ## Next Steps See how suppression is applied to marketing and transactional sends Mirror bounces, complaints and opt-outs into your own systems # Auto Follow-ups Source: https://docs.useinvent.com/guides/auto-follow-ups Let your AI assistant automatically re-engage idle conversations and follow up with customers at the right time Every abandoned conversation is a missed opportunity. A customer asks about pricing, gets distracted, and never comes back. A lead starts a product inquiry, disappears mid-sentence, and you never hear from them again. With Auto Follow-ups, your AI assistant takes care of this for you, re-engaging customers at just the right moment and turning silent drop-offs into closed deals. Auto Follow-ups Overview ## What Auto Follow-ups Does Without Auto Follow-ups, idle conversations are silently closed after a period of inactivity. The customer vanishes, and that's the end of it. With Auto Follow-ups enabled, your assistant gets smart about idle conversations. Instead of quietly closing them, it: 1. **Analyzes the conversation context** to understand where things left off 2. **Decides whether to re-engage** the customer with a helpful follow-up message 3. **Schedules follow-ups at intelligent intervals**, spacing them out naturally 4. **Closes the conversation gracefully** if the customer never responds, complete with a summary and optional CSAT rating Your assistant doesn't just nudge blindly. It understands *why* the conversation went idle and crafts a follow-up that makes sense. For example, if a customer asked about a product but never provided their size, the assistant will follow up specifically about that. Auto Follow-ups is one of the most impactful capabilities you can enable. Businesses that follow up with idle conversations recover significantly more leads than those that let them slip away. ## How to Enable Auto Follow-ups Navigate to the assistant you want to configure and click **Settings**. Scroll down to the **Capabilities** section. You'll see a list of toggles for features like Auto-resolve, Auto CSAT, Memories, and Spam Protection. Toggle on **Auto Follow-ups**. You'll notice it's tagged as **Recommended** because of how effective it is at recovering conversations. Enable Auto Follow-ups in Capabilities Auto Follow-ups uses AI credits each time your assistant analyzes an idle conversation or sends a follow-up message. The cost is minimal compared to the value of recovering a lost lead. ## How It Works in Practice ### AI-Initiated Follow-ups Here's what happens when a conversation goes idle: **1. The customer stops responding** Your assistant detects the inactivity and analyzes the conversation to understand the current state. **2. The assistant decides what to do** Based on the context, it picks one of three actions: * **Re-engage**: Send a follow-up message to bring the customer back * **Schedule a follow-up**: Wait and check in later at a better time * **Close the conversation**: If the topic is resolved or follow-ups have been exhausted **3. Follow-ups are scheduled intelligently** The assistant picks intervals that feel natural. You might see something like "Follow-up in 23 hours" rather than an immediate ping. Each follow-up includes a reason, so you always know what the assistant is thinking. Follow-up scheduled in Inbox **4. If the customer never responds** After multiple unanswered follow-ups, the assistant will gracefully close the conversation. It generates a summary of what was discussed and can prompt the customer with a CSAT rating so you still get feedback. Conversation closed with CSAT ### Customer-Requested Follow-ups Your customers can also ask for follow-ups directly. If someone says "Can you check in with me tomorrow?" or "Talk to me in 24 hours," the assistant understands the request and schedules accordingly. > Customer: "I need to think about this. Can you talk to me in 24 hours?" > Assistant: "Of course! I'll check back in with you tomorrow. Take your time." The assistant then schedules the follow-up for 24 hours later and re-engages the customer right on time. Customer-requested follow-up with scheduled time ## What You'll See in the Inbox When Auto Follow-ups is active, your [Inbox](/guides/inbox) gives you full visibility into scheduled follow-ups: * **Scheduled follow-ups** appear in the conversation with the planned time (e.g., "Follow-up in 23 hours") * **A Cancel button** lets you stop any scheduled follow-up if you want to handle it yourself * **The contact panel** on the right shows "Follow-up scheduled in X hours" for quick reference * **AI reasoning** is visible for each follow-up, so you can see exactly why the assistant decided to re-engage This means you're never in the dark. You can let the AI handle things automatically, or step in and take over whenever you want. ## Example Scenarios ### Scenario 1: Abandoned Product Inquiry A customer asks about your premium plan, then goes silent. * **Without Auto Follow-ups**: The conversation closes silently after the inactivity timeout. The lead is gone. * **With Auto Follow-ups**: The assistant waits a reasonable interval, then sends a message like "Hi! You were asking about our premium plan earlier. Would you like me to walk you through the pricing?" If the customer responds, the conversation picks right back up. ### Scenario 2: Missing Information A customer starts a booking request but never provides their preferred time. * The assistant's reasoning: *"The user started a booking request but hasn't provided their preferred time."* * It follows up: "Hey! I'd love to finish getting your appointment set up. What time works best for you?" ### Scenario 3: Multi-day Follow-up Sequence A customer asks a question, then disappears for a full day. 1. After a few hours, the assistant schedules a follow-up for the next morning 2. The next day, it sends a friendly check-in 3. If there's still no response, it schedules one more follow-up 4. After that final attempt, it closes the conversation with a summary and CSAT prompt The assistant provides reasoning at each step, such as *"User has not responded to the morning follow-up. Scheduling next check-in."* ## Auto Follow-ups vs. Auto-resolve These two features are related but work very differently: | | Auto-resolve | Auto Follow-ups | | ---------------------------------------------- | ---------------------------- | ------------------------------------------------- | | **What happens when a conversation goes idle** | Silently closed | AI analyzes and decides whether to follow up | | **Customer experience** | Conversation just disappears | Customer gets a helpful nudge or a graceful close | | **Lead recovery** | None | High, the AI actively tries to re-engage | | **Conversation close** | Abrupt | Includes summary and optional CSAT rating | When Auto Follow-ups is enabled, it takes over the idle conversation handling that Auto-resolve normally does. Think of it as a smarter replacement. ## Inactivity Timers Understanding when conversations are considered idle: * **AI-handled conversations** auto-close after **20 minutes** of inactivity (when Auto Follow-ups is disabled) * **Human-handled conversations** auto-close after **20 minutes** of inactivity When Auto Follow-ups is enabled, the AI intercepts the closure process and decides whether to follow up instead of closing immediately. Auto Follow-ups works on WhatsApp, Instagram, Messenger, TikTok, Telegram, Slack, Gmail, and SMS through Twilio or Telnyx. It is not available on the Web Widget, on the email channel, or on SMPP. ## Customizing Follow-up Behavior Auto Follow-ups works great out of the box, but you can shape how your assistant handles follow-ups with the dedicated **Follow-up instructions** field on the capability. Click **Add follow-up instructions** under Auto Follow-ups in the assistant's Capabilities to tell the AI how often to follow up, what hours to use, when to stop, and the tone to take. These rules **override the default follow-up behavior**, and they are kept separate from your assistant's main [Instructions](/assistants/introduction#instructions). Add rules like this to the Follow-up instructions field: ``` - After 2 tries with no response, schedule the next follow-up for the nearest morning (9 AM) or evening (6 PM), whichever comes first. - On the final follow-up, offer a 10% discount code to re-engage the customer. - Never follow up more than 3 times total. - Keep follow-up messages short and friendly, no more than 2 sentences. ``` Here are some other ideas you can customize with follow-up instructions: * **Timing rules**: "Space follow-ups at least 12 hours apart" or "Only follow up during business hours (9 AM to 6 PM)" * **Tone adjustments**: "Use a casual, friendly tone for follow-ups" or "Keep follow-ups professional and brief" * **Escalation paths**: "If the customer mentioned a complaint, transfer to a human instead of following up" * **Incentives**: "On the second follow-up, mention our free trial" or "Offer free shipping if the customer abandoned a purchase" * **Limits**: "Never send more than 2 follow-ups" or "Close immediately if the customer said goodbye" Your instructions give you full control over follow-up strategy without touching any code. Experiment with different approaches and monitor the results in your [Inbox](/guides/inbox). ## Best Practices 1. **Enable it alongside [Memory](/guides/memory)** so your follow-ups reference what the assistant already knows about the customer. A personalized follow-up is far more effective than a generic one. 2. **Trust the AI's timing.** The assistant picks follow-up intervals based on conversation context. Resist the urge to manually override unless you have a specific reason. 3. **Monitor the first few days.** Check your Inbox to see how the assistant is handling follow-ups. Review the reasoning it provides to make sure it aligns with your brand. 4. **Let it close conversations gracefully.** If a customer truly isn't coming back, a clean close with a CSAT prompt is better than an open conversation sitting in your queue forever. 5. **Combine with Auto CSAT.** When the assistant closes a conversation after follow-ups, the CSAT prompt gives you data on customer satisfaction even for conversations that didn't fully convert. 6. **Don't worry about AI credits.** The cost of a few follow-up analyses is trivial compared to the revenue from a recovered lead. # WhatsApp Source: https://docs.useinvent.com/guides/broadcasts/channels/whatsapp Send broadcast messages at scale through approved WhatsApp Templates New to broadcasts? Start with the [Broadcasts Overview](/guides/broadcasts/introduction) for the audience, properties, scheduling, and analytics flow that every channel shares. This guide focuses on the WhatsApp-specific setup. **Read the [WhatsApp Best Practices](/guides/broadcasts/whatsapp-best-practices) page before you send your first broadcast.** WhatsApp is the highest-impact channel we support and also the easiest to lose: a single campaign to an unsolicited audience can pause a template, ban a number, or take down an entire Business Portfolio. Customers who follow the playbook send hundreds of thousands of messages without incident; those who skip it can lose the channel on day one. WhatsApp broadcasts let you message your audience at scale using **WhatsApp Templates**, pre-approved message templates that comply with Meta's policies. Once configured, a single broadcast can deliver a personalised template to thousands of recipients in seconds. ## Prerequisites Three things need to be in place before you can configure a WhatsApp broadcast channel: 1. **A connected WhatsApp Business number in Invent.** Connections live at the workspace level, so the same number you set up for an assistant is automatically available for broadcasts. If you have not connected WhatsApp yet, follow the [WhatsApp channel guide](/assistants/channels/whatsapp), it walks through Coexistence vs API-only, Meta's Embedded Signup, and how to attach a number. You can also manage every connection (rename, reconnect, disconnect) from [Settings → Connections](/workspace-management/connections). 2. **At least one approved template.** You can build and submit templates natively in Invent under **Channels → WhatsApp → Templates**, or create them in your [WhatsApp Manager](https://business.facebook.com/wa/manage/message-templates/). Either way Meta reviews and approves each template before it can be sent. See [WhatsApp Templates](#whatsapp-templates) below. 3. **A broadcast in Draft state with an Audience configured.** Open the [Broadcasts](https://www.useinvent.com/o/broadcasts) page, click **+ Create Broadcast**, and pick the segments or contacts you want to reach. ## WhatsApp Templates Outbound, business-initiated WhatsApp messages must use **templates**. A template is a pre-approved message structure with optional variables, buttons, and media. Meta reviews and approves each template before it can be sent. ### Template Categories Every template is created in one of three categories. Picking the right one is essential, sending marketing content under a non-marketing category is one of the most common reasons for template rejection or pausing. | Category | Use it for | Examples | | ------------------ | ------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | | **Marketing** | Promotional content, offers, product launches, re-engagement, newsletters | "20% off this weekend", "New collection just dropped" | | **Utility** | Updates and notifications tied to an action the customer already took | Order confirmations, shipping updates, appointment reminders, password resets | | **Authentication** | One-time passcodes (OTP) and verification codes | Login codes, two-factor authentication codes | Utility and Authentication templates have **significantly lower ban risk** than Marketing templates because the recipient is always expecting them. Use them whenever the content qualifies. See [WhatsApp Best Practices](/guides/broadcasts/whatsapp-best-practices#3-match-the-template-category-to-the-content) for why this matters. ### Creating a Template You can build templates two ways: natively in Invent's template builder, or in Meta's WhatsApp Manager. Either way Meta reviews and approves each template before it can be sent, and once approved it appears in Invent's template dropdown automatically. #### In Invent Invent has a full template builder under **Channels → WhatsApp → Templates**. See [Managing templates in Invent](#managing-templates-in-invent) for the complete list, library, edit, duplicate, and delete flow. Go to **Channels → WhatsApp → Templates** and click **New template**. Start from a blank template, or click **Browse library** to pick a pre-approved template and customize it. Choose **Marketing**, **Utility**, or **Authentication**, and the language the body is written in. If you support multiple languages, create one template per language with the same name; Invent and WhatsApp deliver the version that matches the recipient's locale. Use lowercase letters, numbers, and underscores only (e.g. `order_confirmation`, `weekend_sale_2026`). The name is how you and Invent identify the template; it is never shown to the recipient. Write the body text. Use variables — numbered (`{{1}}`, `{{2}}`) or named (`{{order_id}}`) — for values that change per recipient, and add a **variable sample** for each so Meta can review it. Do not include real customer data in samples. Everything else is optional and added with the **+** chips under the body. Each one appears where it will show in the message, so the editor reads top to bottom like the preview beside it: * **Header**: text, image, video, document, or location. A text header takes one variable. * **Footer**: a single line of static text (e.g. "Reply STOP to opt out"). * **Buttons**: quick reply, URL, call, copy offer code, and flow, within WhatsApp's per-type limits (2 URL, 1 call, 1 copy code, 1 flow, 10 in total). WhatsApp groups quick replies together, so they always render beside each other whatever order you add them in. * **Flow**: a shortcut that adds a flow button and lets you pick the flow and its entry screen. Flows themselves are built in Meta's Flow Builder, linked from the field. Three of the chips change what kind of message you are building, so they replace the plain buttons and take the sections WhatsApp does not allow alongside them: * **Carousel**: an intro message followed by 2 to 10 swipeable cards. Every card carries its own image or video, its own text, and up to two buttons; WhatsApp requires the same media type and button layout on all of them, so the editor keeps them in step. Cards carry the buttons, so the message itself has none. * **Catalog**: one button that opens the product catalog connected to this WhatsApp account — the whole catalog, or products picked when the template is sent. WhatsApp labels this button itself ("View catalog" / "View items"), so there is nothing to write. Products are managed in Meta's Commerce Manager. * **Offer**: a limited-time offer banner above the body, with an optional countdown. Marketing only, needs an image or video header, takes no footer, and needs a URL button so the offer can be redeemed; an offer code button is optional beside it. You set the end time when you send the template, not here. Click **Submit for review**. The template is sent to Meta and shows **Template submitted for review**. Most reviews finish within minutes but can take up to 24 hours. Track the status in the templates list. | Status | Meaning | | ------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Approved** | Ready to use. Available immediately in Invent's template dropdown. | | **Pending** | Under Meta review. The template does not yet appear in Invent. | | **Rejected** | Meta declined the template. Open it to see the rejection reason and resubmit a corrected version. | | **Paused** | A live template that Meta has paused due to quality signals. Sending stops until Meta reinstates it. See [Best Practices](/guides/broadcasts/whatsapp-best-practices#types-of-meta-sanctions). | #### In WhatsApp Manager Prefer to work on Meta's side, or already manage templates there? You can still create them in WhatsApp Manager and they sync back to Invent. Go to [business.facebook.com/wa/manage/message-templates](https://business.facebook.com/wa/manage/message-templates/) and select the WhatsApp Business Account that owns the number you want to send from. If you have multiple WABAs, double-check you are on the correct one before creating. Click **Create template**, pick the category and language, name it, compose the body with variables and any optional header, footer, or buttons, and submit. Once Meta approves it, the template appears automatically in Invent's template dropdown. Templates are reviewed against Meta's [WhatsApp Business Messaging Policy](https://business.whatsapp.com/policy). Common rejection reasons: prohibited content (alcohol, gambling in restricted regions, regulated services), misleading copy, marketing language inside a Utility template, missing example values for variables, or formatting issues. ### Managing templates in Invent The **Channels → WhatsApp → Templates** page is a full management surface for every template on the connected WhatsApp account: * **List and search** all templates with their category and Meta review status, filterable by status. * **New template** opens the builder described above. * **Browse library** starts from a pre-approved template — usually ready to send within minutes — that you name and fill in with your own details. * **Edit** an approved or rejected template (its name and language can never change); saving resubmits it to Meta for review. * **Duplicate** a template into the same or another connected WhatsApp account as a prefilled copy. * **Delete** a template, which permanently removes it from WhatsApp too — this cannot be undone. * **Open in Meta Manager** jumps to the same template in WhatsApp Manager. You need a connected WhatsApp account to create or manage templates. If none is connected, the page prompts you to **Connect WhatsApp account** first. ### Where Templates Live Templates live on the WhatsApp Business Account (WABA) that owns the phone number, not on the assistant or on Invent. This means: * Templates created on WABA A are not visible from a number on WABA B. * Deleting a template removes it from Invent's dropdown immediately. You can delete it directly from Invent's [Templates](#managing-templates-in-invent) list — which deletes it on Meta too — or on Meta's side. * Editing an approved template may return it to **Pending** until re-approved (Meta now allows in-place edits for some categories). ## Adding the WhatsApp Channel to a Broadcast Once you have a template approved and a [WhatsApp connection](/assistants/channels/whatsapp) wired up, you can add the channel to any broadcast in Draft state. From inside a broadcast, scroll to the **Channels** section and click **WhatsApp**. The configuration dialog opens. WhatsApp Channel Button Pick the WhatsApp Business connection to send from. Connections are workspace-level and shared with your assistants, you do not need to authenticate again here. If your workspace has more than one WhatsApp connection, choose the one whose WABA owns the template you plan to use. Manage every WhatsApp connection (rename, reconnect, disconnect) from [Settings → Connections](/workspace-management/connections). Choose which phone number on that connection sends the broadcast. The dropdown shows each number with its connection name. Click the external-link icon to manage the number directly in WhatsApp Manager. WhatsApp Channel Setup Templates are scoped to the WABA, not to a specific phone number. Every approved template on the parent WABA shows up here regardless of which number you pick. Pick a template from the searchable dropdown. Each row shows: * The template name (e.g. `weekend_sale_2026`) * A preview of the body * An icon for the category (Marketing, Utility, Authentication) Once selected, a full **Template Preview** renders below, exactly how recipients will see it, including media headers, body, footer, and any buttons. Click the link icon next to the template dropdown to jump straight into Meta Business Suite to edit, pause, or delete the template. WhatsApp Template Selection If the template contains `{{1}}`, `{{2}}`, header media, or button URLs, map each one. For every variable you can choose: * **Contact Name**: the recipient's name from their contact record. * **Phone**: the recipient's phone number. * **Custom property**: any [property](/guides/broadcasts/introduction#properties) you added to this broadcast (for example `coupon_code`, `order_id`). * **Static value**: a fixed string used for every recipient. The variable dropdown is searchable. Custom properties are the right pick whenever the value differs per recipient (unique discount code, account balance, last-order ID). WhatsApp Template Variables Bulk-import per-recipient values from a spreadsheet using [Import values](/guides/broadcasts/introduction#importing-property-values). This is the cleanest way to handle thousands of unique coupon codes or order IDs without filling them in by hand. A template with a **limited-time offer countdown** asks for the offer's end time here as well. It is part of the send, not the template, so the same template can run a different deadline every campaign — but it has to be filled in, or the send fails. The WhatsApp channel is saved and shows up in the broadcast's Channels section with the template name, recipient count, and **Edit** / **x** controls. ## Test Before You Send Always test the broadcast before scheduling it to your real audience. Click **Send Test** in the top-right of the broadcast editor and enter your own phone number. The template renders with the variables mapped to a single test recipient, exactly the way customers will see it. [See the full testing flow →](/guides/broadcasts/marketing#test-your-broadcast) Testing sends a real message billed at the regular per-message rate. Use your own number, not a customer's. ## Costs Two costs combine on every WhatsApp broadcast message: * **Invent fee**: about **\$0.004 per message**, drawn from your Invent credit balance. [Full pricing breakdown →](/guides/pricing-and-plans#broadcasts) * **Meta conversation fee**: charged by Meta directly based on the conversation category (Marketing, Utility, Authentication) and the destination country. Meta bills this on your WABA's payment method, not through Invent. Country-by-country rates live on Meta's [WhatsApp Business Pricing](https://developers.facebook.com/docs/whatsapp/pricing) page. ## Tracking Delivery and Engagement Once a broadcast is sent, the editor turns into an analytics dashboard: * **Sent / Delivered / Read** percentages at the top. * A per-recipient table with delivery status and timestamps for each event. A high read rate (typically **70%+** for WhatsApp) is healthy. A high block rate, low read rate, or high opt-out rate is a signal to slow down and review your audience. See [Best Practices → Red Flags Meta Is Watching For](/guides/broadcasts/whatsapp-best-practices#red-flags-meta-is-watching-for) for what each signal means and how to react. ## Troubleshooting Three common causes: 1. **The template is still Pending review.** Open WhatsApp Manager and confirm the status is **Approved**. Pending and Rejected templates do not appear in Invent. 2. **Wrong WABA.** A template lives on a specific WhatsApp Business Account. Make sure the connection you picked owns the same WABA as the template. 3. **Template was paused or deleted by Meta.** Open the templates list in WhatsApp Manager and check the status. If paused, wait for Meta to reinstate. If deleted, recreate it. Click the rejected template in WhatsApp Manager to see Meta's specific reason. The most common are: * **Wrong category**: marketing copy submitted as Utility or Authentication. Resubmit under the right category. * **Prohibited content**: regulated industries, misleading promises, or sensitive topics. Rewrite to remove the flagged content. * **Variable example mismatch**: the example values you provided do not match the variable placement. Add realistic examples for every `{{N}}` and resubmit. * **Brand impersonation**: header or body language that suggests you are someone you are not. Resubmit a corrected version with a slightly different name (e.g. `weekend_sale_2026_v2`) so you can track which version is which. Meta enforces per-day messaging limits based on your number's **messaging tier** (visible in WhatsApp Manager). New numbers start at the lowest tier (1,000 unique recipients per 24 hours) and unlock higher tiers automatically as quality stays high. If you are sending a 50,000-recipient broadcast on a Tier 1 number, the queue throttles to fit the daily cap. To raise your tier: maintain a high quality rating for several days and Meta upgrades automatically. There is no manual escalation path. Hover the failure icon for the specific reason. The most common are: * **Invalid phone number** (wrong country code, missing digits). * **Recipient does not have WhatsApp** on that number. * **Recipient blocked your business** previously. * **Recipient is in a country your WABA is not approved to send to.** Failed deliveries do not count toward your messaging tier but do count toward Invent's per-message fee, since the message was attempted. Meta paused it because of recent quality signals (reports, blocks, low read rate). This is the **early-warning** sanction. Follow [What to Do if You Get a Warning](/guides/broadcasts/whatsapp-best-practices#what-to-do-if-you-get-a-warning): stop sending, audit the recent audience, fix the consent or content issue, and resume only with your most-engaged segment. Phone-number bans are issued by automated systems and almost never reversed on appeal. Practically, the affected number is permanently lost on WhatsApp Cloud API. The other numbers on your Business Portfolio remain active. Going forward: * Do not import the same number into another tool. The ban follows the number, not the tool. * For a fresh start, register a new number on the same portfolio and apply the [Best Practices](/guides/broadcasts/whatsapp-best-practices) playbook from day one. * If your entire **portfolio** is banned, contact Meta support and Invent support; recovery is rare but the process exists. ## Next Steps The playbook for keeping your number, templates, and Business Portfolio in good standing Create, schedule, and analyse broadcasts across every channel Connect a WhatsApp Business number through Meta's Embedded Signup Manage your contacts and organise them into segments for targeted broadcasts # Broadcasts Source: https://docs.useinvent.com/guides/broadcasts/introduction Reach your contacts on the channels they already use, in bulk or one event at a time Your customers reached out to you through WhatsApp, Instagram, or your website. Broadcasts let you reach back out on the same channels. Send a product announcement to a whole segment, or fire a one-time passcode the instant someone signs in. Both run on the same templates, channels, and personalization. Broadcasts dashboard listing broadcasts in a table ## Two ways to broadcast Every broadcast is one of two types, chosen when you create it and fixed afterwards. | | Marketing | Transactional | | ------------------- | --------------------------------------------- | -------------------------------------------------------------- | | **Best for** | Announcements, updates, offers, newsletters | OTPs, receipts, confirmations, password resets | | **Who receives it** | A segment or all contacts, chosen up front | One recipient, named on each trigger | | **When it sends** | Now or scheduled for later | The moment your backend calls the endpoint | | **How it is sent** | One send to many people | One API call per message | | **Unsubscribes** | Respected; unsubscribed contacts are excluded | Respected; the trigger is rejected if the contact unsubscribed | | **Lifecycle** | Draft to Scheduled to Sent | Draft to Active, then triggered many times | Send one message to a group at once, immediately or scheduled Trigger a single message through the API when an event happens ## The Broadcasts dashboard The Broadcasts page lists every broadcast in a table: | Column | Description | | ----------------- | -------------------------------------------------------------------------------------- | | **Name** | The name you gave the broadcast, with a type icon and the type below it | | **Channels** | A badge per channel configured, each with its integration icon | | **Status** | Current state (see [Broadcast statuses](#broadcast-statuses)) | | **Recipients** | The total, above a bar split by delivery state. Hover it for the exact count per state | | **Last Activity** | When the broadcast was last sent, or last edited if it has not sent yet | Above the table, a search box filters by name and a set of chips filters by type: **All**, **Marketing**, or **Transactional**. Both are reflected in the URL, so a filtered view can be bookmarked or shared. Each row has a three-dot menu to duplicate or delete the broadcast. Alongside the list, the Broadcasts area has a **WhatsApp Templates** view for building and managing your templates (see [WhatsApp](/guides/broadcasts/channels/whatsapp#whatsapp-templates)) and an **Analytics** view for delivery reporting. Opening a single broadcast gives it its own **Overview** and **Recipients** tabs. ## Creating a broadcast Use the **+ Create Broadcast** button in the top-right corner. Give the broadcast a descriptive name, for example "Black Friday Sale" or "Login OTP". Pick **Marketing** or **Transactional**. This sets how the broadcast sends and cannot be changed later. * **Marketing**: send to a group at once, now or scheduled for later. * **Transactional**: send via API, one message the moment something happens. Create Broadcast dialog with a name field and a choice between Marketing and Transactional types The broadcast opens in **Draft**. The sections you configure depend on the type: marketing broadcasts have an **Audience**, transactional broadcasts have a **Send** section. Both share **Channels** and **Properties**. ## Channels Channels determine how your message is delivered. Every broadcast needs at least one, and you can add several to reach contacts across platforms in a single broadcast. Channels section of a broadcast ### Available channels | Channel | Description | | ------------ | --------------------------------------------- | | **WhatsApp** | Send messages via approved WhatsApp Templates | More broadcast channels are coming soon. Follow the channel guide to set up and configure it: Set up WhatsApp Templates and configure the channel ### Adding multiple channels After your first channel, click **+ Add Channel** to add another. Each channel is configured independently with its own template and settings, so a single broadcast can reach contacts on several platforms at once. A broadcast with multiple channels configured ### Editing a channel After a channel is added you can: * Click **Edit** to change the template, variables, or settings. * Click **x** to remove the channel. Editing reopens the full dialog with your previous settings, a **Remove channel** button, and **Save Changes**. Channels can only be edited while the broadcast is in Draft. ## Properties Properties personalize each message with per-recipient values. Think of them as variables that differ for every contact, such as a coupon code, a product link, or an account balance. Add properties like `coupon_code` or `product_url`, then map them into your templates. ### Adding a property A new row appears with two fields. Type a name, for example `coupon_code` or `order_id`. Enter a default used for any recipient without a specific value. Click the checkmark to save, or the **x** to cancel. The property then appears in a table showing its **Name** and **Default Value**, with edit and delete icons. Broadcast properties table with names and default values ### Importing property values For marketing broadcasts, you can bulk import per-recipient values from a spreadsheet instead of setting them one by one: The import dialog opens with a file upload area. Drag in a **.csv**, **.xlsx**, **.xls**, **.numbers**, or **.ods** file with a column to identify recipients (email or phone) and a column for each property value. Click **Download sample CSV** for a correctly formatted template. Map each column from your file: * **Recipient identifier**: map at least one column to **Email** or **Phone** so Invent knows which contact each row belongs to. * **Property values**: map columns to your broadcast properties. * **Content overrides**: columns named `subject`, `body`, `reply_to`, or `message` carry per-recipient content — they replace the configured template content for that recipient on the channels that expose them (subject, body, and reply\_to for email, message for SMS). These names are reserved, so a property cannot use them. Email and SMS broadcast channels are not yet generally available, so these overrides only apply once those channels ship. * **Skip column**: choose "Skip column" for anything you do not need. Click **Review**, then **Import**. A success message confirms how many values were imported. Import property values dialog with column mapping Transactional broadcasts do not import values up front. Their per-recipient values arrive with each [trigger](/guides/broadcasts/transactional#variables) instead. ### Using properties in templates Once added, properties are available as template variables when you configure a channel. A `coupon_code` property, for example, can be inserted into your WhatsApp template alongside built-in variables like Contact Name and Phone. ## Broadcast statuses | Status | Applies to | Description | | ------------- | ------------- | ------------------------------------------------------------------------------------------------ | | **Draft** | Both | Being configured, not sent yet. All sections are editable. | | **Scheduled** | Marketing | Queued to send at a future time, with a live countdown. | | **Sending** | Marketing | Currently being delivered. Cannot be edited. | | **Sent** | Marketing | Fully sent. Analytics and tracking are available. | | **Active** | Transactional | The endpoint is open and sending when called. | | **Paused** | Transactional | The endpoint is closed and new sends are rejected. Configuration is preserved. | | **Cancelled** | Marketing | A legacy status kept for older broadcasts. Cancelling a send now returns the broadcast to Draft. | | **Failed** | Marketing | Something went wrong during delivery. Fix the issue and re-send. | ## Duplicating a broadcast To reuse a setup, open the three-dot menu on any broadcast and select **Duplicate**. This creates a copy with "(Copy)" appended, preserving the audience or trigger, properties, and channels. ## Next steps Audience, scheduling, and analytics for bulk sends API triggers, variables, and the live endpoint Set up WhatsApp Templates and configure the channel Manage contacts and build segments for targeting # Marketing Broadcasts Source: https://docs.useinvent.com/guides/broadcasts/marketing Send one message to a group of contacts at once, immediately or scheduled for later Marketing broadcasts send a single message to many contacts at once. Use them for announcements, product updates, promotions, and newsletters: anything you want a whole segment to receive at the same time. You choose the audience up front, set up your channels, and either send now or schedule for later. This page covers the marketing-specific flow. For the building blocks every broadcast shares (channels, templates, and properties), start with the [Broadcasts overview](/guides/broadcasts/introduction). For event-driven messages sent one at a time, see [Transactional broadcasts](/guides/broadcasts/transactional). ## Audience The Audience section determines who receives your broadcast. It is the first thing to configure, and it is required before you can send. Marketing broadcast audience selector showing All Contacts, contact import, and segment options Learn how to manage contacts and build segments in the Audience guide. You have three options: ### All contacts Click **All Contacts** to send to every contact in your audience. Once selected, the Audience section shows an "All Contacts" row with its contact count, a **See all** button to browse them, and a **Change** button to pick a different audience. ### Specific segments Click **Add segment** to target specific groups: 1. **Search** for a segment by name. 2. **Select** one or more segments from the list. 3. **Add multiple segments** to widen your reach. Each selected segment appears with its name, its contact count, a **View** button that opens its contacts in a searchable dialog, and an **x** to remove it. You can combine segments freely. Click **Add segment** again to add another. ### Import a file Click **Import contacts** to send to a list from a CSV, Excel, Numbers or OpenDocument file without leaving the broadcast: 1. **Upload** a `.csv`, `.xlsx`, `.xls`, `.numbers`, or `.ods` file. 2. **Map** the columns to contact fields; recognized columns are mapped automatically. Optionally pick a segment to file the contacts under. 3. **Review and import**. The contacts join this broadcast's audience directly and appear as **Imported contacts** in the Audience section, with **See all** to browse them and **Remove** to clear them. Add a channel before importing. The import maps your columns onto the fields your channels use, so **Import contacts** stays disabled until the broadcast has at least one. If the same person appears more than once in your file, the rows are merged into a single contact and the review step marks the extras as **Merged**. The first row for that person wins. Imported contacts belong to the broadcast, not to a segment — nothing is added to your segment list unless you chose one. They are still saved as contacts in your [Audience](/guides/audience), and they are sent to alongside any segments you selected. Your file can also carry per-recipient values for the [properties](/guides/broadcasts/introduction#properties) used in your templates. Download the sample file from the import dialog to get a header row with every property your broadcast expects. An audience uses one source at a time. To switch between all contacts, segments, and an imported file, click **Change** in the Audience section header and confirm. This clears the current selection, including any imported contacts. Marketing broadcasts respect each contact's subscription status. Contacts who have unsubscribed or are blocked are automatically excluded from the audience, so you stay compliant without extra work. ## Test your broadcast Before sending to your whole audience, send yourself a test to confirm everything looks right. Open the broadcast and click **Send Test** in the top-right corner. Provide the contact detail that matches the channel you are testing: * **Full Name** (optional): a name for the test recipient. * **Phone** (optional): the number that receives the test, with a country-code selector. You must provide the detail that matches the channel. A WhatsApp broadcast needs a **Phone** number, and the test fails if the required field is missing. Click **Send test message** and check the device to confirm the message renders correctly with its variables populated. Send a test broadcast dialog with name and phone fields A test sends a real, billable message to the details you enter. Use your own number, not a customer's. ## Send or schedule Once your audience, channels, and content are ready, click **Schedule Broadcast** in the top-right corner to open the delivery dialog. It has two parts: **when** the broadcast starts, and **how quickly** it goes out. Send broadcast dialog with when-to-start chips, a delivery pace slider, and a recipient summary ### When to start Pick when the broadcast begins: * **Send now**: start delivering immediately. * **Quick options**: in 30 minutes, in 1 hour, or tomorrow at 9:00 AM. * **Pick date & time**: choose any future date and time with the picker. ### Delivery pace Delivery pace controls how fast the send goes out once it starts. Instead of firing everything at once, you can **spread the send evenly** over a window so it lands steadily rather than all in the same minute. Drag the slider between **ASAP** (as fast as possible) and up to **7 days**. As you move it, the dialog updates live: * The **rate** — roughly how many messages go out per minute. * The **finish estimate** — when the send is expected to complete. * A small **timeline bar** that fills to show how much of the window the send occupies. The **Recommended** marker (around 3 hours) is a good default for most marketing sends: steadier delivery, stronger open rates, and comfortably within your channel's limits. Click the marker to snap to it. Whatever pace you pick, Invent never exceeds your channel's safe sending limit. If you choose a pace faster than the limit allows, the send simply runs at the limit and the finish estimate adjusts. Delivery pace applies to marketing broadcasts only. ### Confirmation The dialog always shows a recipient summary — "Sending to X recipients via WhatsApp" — with the channel and count. Click **Send Broadcast** to start now, or **Schedule Broadcast** to queue it for the time you picked. ## Scheduled broadcasts When a broadcast is scheduled, the page updates to show: * A banner: "Broadcast is scheduled to send on" the chosen date and time. * A live countdown in the top-right corner. * A **Cancel Schedule** button that returns the broadcast to Draft. To edit a scheduled broadcast, cancel the schedule first, make your changes, then schedule it again. Scheduled marketing broadcast with a banner and a countdown timer ## While it's sending Once a broadcast starts, the header shows a **Sending** status and a banner tracks it live: * **Progress** — how many of the total recipients have been delivered so far, with a percentage. * **Pace** — "Spread evenly over 3 hours" when you set a delivery pace, or "Going out as fast as your channels safely allow" when you didn't. The Deliverability card and the recipients table fill in as the send progresses. Broadcast mid-send: a Sending banner showing delivery progress and pace, with a Cancel Broadcast button ## Cancelling a send in progress A paced broadcast can be delivering for hours, so you can stop one mid-send. Click **Cancel Broadcast** and confirm. Delivery stops and the broadcast returns to Draft, fully editable again — messages already delivered stay delivered and keep counting in your analytics, and the unsent remainder is discarded. A banner tells you how many people already received it. Send it again and everyone who already received it is skipped, so nobody gets it twice. The send dialog counts only the people still to reach, which makes an unedited re-send the way to resume an interrupted broadcast. Messages already handed to the channel may still go out — cancelling stops the queue, not a message mid-delivery. ## Analytics After a broadcast is sent, the page becomes an analytics dashboard. The Audience, Properties, and Channels sections collapse into summaries, and delivery data takes their place. ### Deliverability * **Total Recipients**: how many contacts were targeted. * **Sent**: how many messages were sent, with the percentage. * **Delivered**: how many were confirmed delivered, with the percentage. The large figure at the top is your at-a-glance delivery rate. ### Engagement * **Opened**: how many recipients opened or read the message, with the percentage. ### Recipients table A per-recipient table lists every contact, the channel used, the delivery status, and the send time. Hover a status icon to see exact timestamps for each event. Marketing broadcast analytics with deliverability, engagement, and a recipients table ### Retrying failures A failed recipient shows a **Retry** button on its row, which puts that message back on the send queue. When several failed, **Retry all failed** appears above the table and requeues them in one go. Retrying never re-sends to someone who already received the message. Recipients that never reached anyone — imported, still queued, failed, or skipped — can also be removed from the table through the **⋮** menu on their row. ## Best practices 1. **Always test first.** Send yourself a preview and confirm the template and variables render correctly. 2. **Segment instead of blasting.** Send relevant content to the right group rather than the same message to everyone. 3. **Personalize with properties.** A name and a unique code lift engagement. See [Properties](/guides/broadcasts/introduction#properties). 4. **Schedule for the right moment.** Send when your audience is active, and avoid late nights and weekends. 5. **Watch your numbers.** Low deliverability usually points to bad phone numbers or addresses in your contacts. 6. **Get consent.** Only message contacts who opted in. On WhatsApp this is essential. See [WhatsApp Best Practices](/guides/broadcasts/whatsapp-best-practices). ## Next steps Send event-driven messages one at a time through the API Set up WhatsApp Templates and configure the channel Keep your number and templates in good standing Manage contacts and build segments for targeting # Transactional Broadcasts Source: https://docs.useinvent.com/guides/broadcasts/transactional Trigger a single message through the API the moment an event happens Transactional broadcasts fire one message at a time, triggered by your backend the moment something happens: a sign-up, a purchase, a password reset. Instead of choosing an audience and a send time, you set up the message once, activate it, then call its endpoint whenever you need to send. Each call delivers to a single recipient and fans out across every channel you configured. Use them for one-to-one, event-driven messages such as one-time passcodes, receipts, order confirmations, and password resets. This page covers the transactional-specific flow. For the building blocks every broadcast shares (channels, templates, and properties), start with the [Broadcasts overview](/guides/broadcasts/introduction). To send one message to a whole segment at once, see [Marketing broadcasts](/guides/broadcasts/marketing). **No audience, no schedule.** A transactional broadcast sends one message each time you trigger it, so there is no list to send to and no moment to schedule. Each recipient is messaged on every channel they are reachable on: someone with both an email and a WhatsApp number gets both. It is not a fallback chain. A transactional broadcast showing its deliverability stats and the Send panel ## How it works Click **+ Create Broadcast**, name it, and choose **Transactional** as the type. The type cannot be changed after creation. Add one or more channels and complete a [template](/guides/broadcasts/introduction#channels) for each. This is the same editor that marketing broadcasts use. Add any [properties](/guides/broadcasts/introduction#properties) your templates need, such as `otp` or `order_id`. For transactional broadcasts, the values arrive with each trigger rather than from a contact list. Click **Activate Broadcast** to open the endpoint. The broadcast moves to **Active** and starts sending immediately when called. Call the send endpoint whenever the event happens. Each call delivers to one recipient. ## Setting up the send The **Send** section has two tabs: **API** and **Manual**. ### API The API tab shows the exact endpoint for this broadcast, a ready-to-copy cURL example, and a link to manage your API keys. Send panel API tab showing the POST endpoint, a cURL example, and a Manage API keys button The endpoint is: ```bash theme={"system"} POST https://api.useinvent.com/orgs//broadcasts//send ``` The trigger panel renders this URL with `orgs/c/` — a key-scoped alias that stands in for your org ID. Both forms work: copy the one shown in the panel, or substitute your own ``. A complete request looks like this: ```bash theme={"system"} curl -X POST 'https://api.useinvent.com/orgs//broadcasts//send' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com", "variables": { "otp": "123456" } }' ``` Authenticate with an organization API key, sent as a bearer token in the `Authorization` header. Create and manage keys in [Settings, API keys](/workspace-management/api-keys). #### Identifying the recipient Every trigger names exactly one recipient. Provide at least one identifier, in order of precedence: | Field | Tier | Use it when | | -------------------- | ------------- | ------------------------------------------------------------------------------------------------------------ | | `contact_channel_id` | Most specific | You already know the exact channel to send on. Skips contact resolution and the channel-availability filter. | | `contact_id` | Known contact | You have the contact's ID. The channel is inferred per template at send time. | | `phone` or `email` | Raw | You only have a raw identifier. Invent finds or creates the contact. You can pass either or both. | #### Overriding the recipient details `phone`, `email`, and `name` double as per-send overrides. When you also pass a `contact_id` or `contact_channel_id`, any of these you include replaces the resolved channel and contact value for that send only. The contact and its stored channels are never modified. | Field | Overrides | | ------- | ------------------------------------- | | `phone` | The phone the message is delivered to | | `email` | The email the message is delivered to | | `name` | The display name used in the message | `name` is an override, not an identifier. It cannot resolve a recipient on its own, so a trigger still needs one of `contact_channel_id`, `contact_id`, `phone`, or `email`. #### Overriding the content `subject`, `body`, `reply_to`, and `message` replace the configured template content for a single send. Each key applies to every template whose channel exposes it: `subject`, `body`, and `reply_to` to email templates, `message` to SMS templates. Overrides support the same `{{variable}}` placeholders as template content, and the templates themselves are never modified. ```bash theme={"system"} curl -X POST 'https://api.useinvent.com/orgs//broadcasts//send' \ -H 'Authorization: Bearer ' \ -H 'Content-Type: application/json' \ -d '{ "email": "user@example.com", "subject": "Your order shipped", "body": "

Hi {{name}}, it is on the way.

", "reply_to": "support@acme.com", "message": "{{name}}, your order shipped!" }' ``` Omit them and the configured template content sends as-is. A key no channel on the broadcast exposes is simply ignored. WhatsApp is currently the only generally available broadcast channel. The email (`subject`, `body`, `reply_to`) and SMS (`message`) overrides are documented for when those channels ship; on a WhatsApp-only broadcast they are ignored. #### Request body | Field | Required | Description | | ---------------------------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------- | | `contact_channel_id`, `contact_id`, `phone`, `email` | At least one | Recipient identifiers, sent at the top level of the body. See [Identifying the recipient](#identifying-the-recipient) for precedence. | | `name` | No | Display-name override for this send. See [Overriding the recipient details](#overriding-the-recipient-details). | | `subject`, `body`, `reply_to`, `message` | No | Content overrides for this send only. See [Overriding the content](#overriding-the-content). | | `variables` | No | Values for your broadcast fields. They override the contact's stored values, and any field you omit falls back to its configured default. | | `template_ids` | No | A subset of templates to fire. Omit to fire every template on the broadcast. | | `background` | No | When `false` (default), the call waits for the send and returns an `external_message_id` per template. When `true`, it enqueues and returns immediately. | The response returns one recipient record per template fired, so you can confirm exactly what was sent. The send endpoint is rate limited to **500 requests per 60 seconds**. Queue or batch on your side if you expect bursts above that. ### Manual The Manual tab fires the same endpoint from the dashboard: enter a recipient, adjust variables, and click **Send message**. Handy for one-off sends and spot checks without leaving the UI. Only the identifiers your channels can deliver to are asked for, so a WhatsApp or SMS broadcast asks for a phone and an email-only broadcast asks for an email. Under **Content**, the tab also exposes whichever content fields your channels support (`subject`, `body`, `reply_to`, `message`). Filling one replaces the configured template content for that send only; leave a field blank to keep the template's. Your saved template is never modified. After sending, the tab switches to a delivery timeline for that message and updates live as the channel reports back, so you can watch it go from sent to delivered without reloading. ## Variables Transactional templates use the same [properties](/guides/broadcasts/introduction#properties) as marketing broadcasts, with one difference in where the values come from: * **Defaults** are set on the broadcast and used when a trigger omits a value. * **Per-trigger values** are passed in the `variables` object and override the defaults for that send. This lets one broadcast serve many cases. A single `order_confirmation` broadcast can carry a different `order_id` and `total` on every call. ## Activating, pausing, and resuming With at least one complete template, click **Activate Broadcast**. Activating opens the endpoint, and the broadcast starts sending immediately when called. Status: **Active**. Click **Pause** to close the endpoint. New sends are rejected while paused, and your configuration is preserved. Status: **Paused**. Click **Resume** to reopen the endpoint. The broadcast returns to **Active** with the same setup. You can pause and resume as often as you need without losing templates, variables, or settings. A transactional broadcast stays live until you pause it. ## Monitoring An active broadcast shows a live status banner with the date it was activated and how many messages have been sent across how many channels. A paused broadcast shows the paused state and the same totals. Above it, **Deliverability** and **Engagement** report the rates for this endpoint. Because a transactional broadcast sends repeatedly to the same people, these are measured against total sends rather than distinct recipients, so the figure shown is **Total Sends**. The Recipients table lists every triggered message with its channel, delivery status, and a **Source** column showing whether the trigger came from the API or a manual send. Because each trigger fans out across templates, one call can produce several rows, one per template. ## Consent and compliance Transactional broadcasts respect each contact's subscription status, just like marketing broadcasts. If the recipient has unsubscribed or is blocked, the trigger is **rejected**: the API returns an error and no message is sent, so you do not need to filter these contacts yourself. Even so, use transactional broadcasts only for genuinely transactional messages the recipient is expecting, such as one-time passcodes, receipts, and confirmations. For promotional content, use a [marketing broadcast](/guides/broadcasts/marketing). On WhatsApp, match the template category to the content: send these under **Utility** or **Authentication** templates, not **Marketing**. See [Template categories](/guides/broadcasts/channels/whatsapp#template-categories) and [WhatsApp Best Practices](/guides/broadcasts/whatsapp-best-practices). ## Next steps Send one message to a whole segment at once Create and manage the keys that authenticate your triggers Configure WhatsApp Templates for transactional sends Channels, properties, and statuses shared by every broadcast # WhatsApp Best Practices Source: https://docs.useinvent.com/guides/broadcasts/whatsapp-best-practices How to send WhatsApp broadcasts the right way, avoid Meta sanctions, and keep your number, templates, and Business Portfolio in good standing WhatsApp is by far the most effective channel for direct customer outreach we support. Read rates regularly sit above **70%**, compared to roughly **10%** on email. That same effectiveness is what makes WhatsApp ruthlessly intolerant of anything that looks like spam: when a recipient does not recognise your business and taps **Block** or **Report**, Meta records it, and a small handful of those reports is enough to trigger sanctions that range from a paused template all the way to a full Business Portfolio ban. This page is the playbook we hand to every customer before they hit **Send Broadcast**. Read it once, follow the rules, and your broadcasts will work for years. Skip it and the first miscalibrated campaign can cost you the channel. **Appeals to Meta rarely succeed.** Once a phone number, template, or portfolio is sanctioned, recovery is almost never an option. Prevention is the entire game. If you take one thing from this page, take that. ## Why This Matters WhatsApp's report rate cuts both ways. Because read rates are so high, almost every recipient sees your message. That is the upside. The downside is that the same audience can also report you in seconds, and WhatsApp's spam-detection thresholds are far stricter than email's. Two real customer examples illustrate the gap: * **Customer A** sent \~300 broadcast messages to an unsolicited list, recipients who had never opted in for WhatsApp marketing. A handful reported it as spam. Within a day, Meta banned the entire account. * **Customer B** sent **over 150,000** broadcast messages combining marketing and OTP traffic over many months, all to an opted-in audience with relevant content. Result: **one template paused** for quality review, then reinstated. No account-level action. Same channel, completely different outcomes. The difference is **who you message** and **what you send them**, not how many. ## Types of Meta Sanctions When Meta detects spammy behaviour or receives reports, it applies one of four progressively heavier sanctions. Knowing which is which helps you read the warning signs early. | Sanction | Scope | Reversible? | Typical trigger | | -------------------------- | ---------------------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Paused Template** | One specific template | Yes, usually within hours to a day | A small number of recipients reported the template as spam, or low-quality content was flagged. The template stops sending until Meta reviews and reinstates it. | | **Banned Template** | One specific template | No, you must rewrite and re-submit | The template repeatedly attracted reports or violated policy (misleading copy, prohibited categories, sensitive content). It is permanently removed. | | **Phone Number Ban** | One phone number | No, the number is permanently lost on WhatsApp Cloud API | Sustained spam reports on that specific number, sending to large numbers of unsolicited contacts, or a high block rate. Other numbers under the same Business Portfolio are unaffected. | | **Business Portfolio Ban** | The entire Meta Business Portfolio | Effectively no, appeals almost never succeed | Severe or repeated violations, fraud, or aggregated spam signals across multiple numbers and templates. You lose every number, every template, and every WhatsApp Business Account on the portfolio. | A paused template is a **warning**, not a punishment. Treat it as a free, second-chance audit signal. If you see one, pause your sending, audit who you sent the campaign to, fix what triggered it, and only resume once you understand why. A banned WhatsApp number or portfolio also means your **assistants** stop sending and receiving on that number. The damage is not limited to broadcasts. ## The Golden Rules Follow these and you will almost never see a sanction. ### 1. Only message contacts who opted in This is the single biggest factor. Treat WhatsApp consent the same way you treat email consent under GDPR or CAN-SPAM: * The contact actively signed up for WhatsApp updates from your business (a checkbox at signup, a "send me on WhatsApp" toggle on a form, or a click-to-chat action where the customer initiated). * They know your brand and are expecting messages from you. * You can prove the consent if asked (timestamp, source, channel). Importing a CSV of phone numbers you scraped, bought, or pulled from a CRM without explicit WhatsApp opt-in is the fastest way to lose your number. "They are already my customers, so they should expect updates" is **not consent** in WhatsApp's eyes. Customer relationships from email, in-store purchases, or app signups do not automatically authorise WhatsApp marketing. Get explicit opt-in for WhatsApp specifically. ### 2. Send genuinely useful content Every broadcast should be something the recipient would be happy to receive. Real product launches, time-sensitive updates, order notifications, appointment reminders, exclusive offers tied to their relationship with you, that is the bar. Things that get reported fast: * "Hi! Check out our new website." * Generic discount codes with no context. * Multiple campaigns per week to the same audience. * Content unrelated to why they signed up. ### 3. Match the template category to the content When you create a template in Meta Business Suite you pick a category: **Marketing**, **Utility**, or **Authentication**. Send marketing content under a Marketing template, not under a Utility template even if the per-message rate is lower. Meta's classifiers detect category mismatches and treat them as policy violations. [Learn what each template category means →](/guides/broadcasts/channels/whatsapp#template-categories) ### 4. Start small, scale gradually A brand-new WhatsApp Business number does not get to send a 50,000-recipient marketing blast on day one. Meta's quality systems weight new numbers more harshly because they have no history. Build a reputation first: * Week 1: send to your most engaged 100–500 contacts. * Watch the deliverability and engagement numbers in [Broadcast Analytics](/guides/broadcasts/marketing#analytics). * Only scale up to larger segments once your first campaigns show clean delivery and high read rates. ### 5. Make opt-out trivially easy Every Marketing template should give the recipient a clear way to stop receiving them. The standard pattern is a **Stop promotions** quick-reply button on the template; some businesses also include "Reply STOP to opt out" in the body. When a customer replies STOP (or taps the opt-out button), [unsubscribe them from broadcasts](/guides/inbox#three-dot-conversation-actions) in the Inbox. Honour those requests immediately. Continuing to message a contact who asked to stop is the single most reportable behaviour on WhatsApp. ### 6. Segment ruthlessly Generic blasts to your whole audience are the highest-risk shape of campaign. The same message that delights one segment can offend another, and the offended segment is what generates the reports. Use [Segments](/guides/audience/segments) to send the right message to the right audience, every time. Customers who bought a product get the follow-up; customers who only signed up for newsletters do not get product upsell campaigns. ### 7. Respect quiet hours and frequency * Avoid sending late at night or early in the morning in the recipient's timezone. Late-night marketing pings are a common report trigger. * Do not exceed roughly **one Marketing broadcast per week** to the same contact unless they are highly engaged. * Space campaigns out. Three pushes in a single day to the same person is a near-guaranteed report. ### 8. Test every broadcast before sending Use the **Test** button on every broadcast to send the message to your own number first. Verify the template renders correctly, links work, variables populate, and the tone is right. A broken template that confuses customers is a soft form of spam in Meta's eyes. [See the testing flow →](/guides/broadcasts/marketing#test-your-broadcast) ## Red Flags Meta Is Watching For Even when each rule above is technically followed, the **shape** of your sending pattern matters. Meta aggregates these signals and uses them to decide whether to escalate. | Signal | Why it raises risk | | ------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | | **High block rate** | Recipients tapping **Block** is the strongest negative signal Meta tracks. Even a 2–3% block rate across a campaign can trigger a quality drop. | | **Low read rate** | If recipients consistently ignore your messages, Meta interprets it as low-value sending. | | **Sudden spike in volume** | Going from 100 messages a day to 10,000 overnight on a number with no track record looks like spam infrastructure. | | **High variation in message content** | Sending many slightly different versions of the same marketing message in a short window looks like an attempt to evade content filters. | | **Cold audience** | First-touch broadcasts to recipients you have never messaged before carry the highest report risk. | Each campaign affects your number's **quality rating** (visible in WhatsApp Manager → Phone numbers). Watch it. A drop from **High** to **Medium** is your free, early warning to slow down and investigate before Meta escalates. ## What to Do if You Get a Warning Meta sends an email when it pauses a template, downgrades a number's quality, or applies any other action. Do not ignore it. Pause every queued broadcast and turn off any automated sending for that number until you understand what happened. Meta tells you which template, which number, and roughly why. The reason is usually generic ("low quality" or "user reports"), but the affected asset is always specific. Open the broadcast that ran most recently before the warning. Look at the audience segment. Did you message people who did not opt in? People you have not contacted in months? People who never engaged with earlier messages? That is almost always the cause. Remove any contact you cannot prove opted in for WhatsApp specifically. Rewrite the template so the value is obvious and the brand recognisable. Add an explicit opt-out path if you do not have one. When you do start sending again, start with your most-engaged segment, watch the quality rating, and scale only when it stabilises. Do not "appeal" your way out of a sanction by repeating the same campaign to the same audience. Meta's quality systems remember, and the second sanction is much more likely to be permanent. ## Patterns That Work Here are the campaign shapes we see succeed consistently across our customers. ### Order and appointment notifications (Utility) Order shipped, appointment confirmed, password resets, delivery updates. Send these under a **Utility** template. Recipients always opted in (they bought something), the content is always expected, and reports are essentially zero. ### Re-engagement of recent buyers (Marketing) Customers who purchased in the last 30–90 days get a follow-up offer or a related-product nudge under a **Marketing** template. Tight segment, fresh relationship, recognisable brand. This shape regularly gets 80%+ read rates and almost no reports. ### Opt-in newsletter from a click-to-chat ad Customers who tapped a click-to-chat ad and confirmed they want updates become an opted-in marketing segment. Send them periodic, branded content under Marketing templates. The original click-to-chat is your consent record. ### What does **not** work * Cold lists you bought, scraped, or imported from another platform. * Re-engaging customers from 12+ months ago who never opted in for WhatsApp. * "We have your number from the order, so let us send you offers" without an explicit WhatsApp opt-in. * Daily or near-daily marketing pings to the same audience. ## FAQ Meta does not publish exact thresholds, and they vary by sender age, content type, and recent quality history. Across thousands of campaigns we have seen, as little as **2–5%** report or block rate on a single campaign is enough to pause a template, and a sustained pattern at that level can lead to number-level action. Aim for well under 1%. Technically yes, in practice almost never with success. Bans are issued by automated systems that have already weighed the evidence. Plan for prevention, not appeals. Utility templates carry significantly less ban risk because they are tied to a transaction the customer already initiated (an order, an appointment, a password reset). They are still subject to quality review, but the report rate is naturally low. Use them whenever the content qualifies, do not dress up marketing as utility. No. [Auto Follow-ups](/guides/auto-follow-ups) re-engage customers inside the 24-hour customer-service window after they messaged you, using free-form messages, not templates. They do not go through Broadcasts and do not carry the same template-category risk. They are still subject to WhatsApp's general quality signals, but the risk shape is different. Stop all broadcasts immediately. **Low** is the last warning before Meta restricts your messaging limit or pauses the number. Audit the recent campaign that caused it, fix consent and content, and let the rating recover by sending only opt-in utility messages for a few days before resuming marketing. No. The 24-hour customer-service window allows free-form responses to messages the customer already sent you. Reports inside that window are very rare and usually only happen if the assistant misbehaves. The strict rules above apply specifically to **business-initiated** outbound, which on WhatsApp means [template-based broadcasts](/guides/broadcasts/channels/whatsapp). Mostly. A phone-number ban applies only to that number; sister numbers under the same Business Portfolio keep working. But repeated number-level sanctions across the same portfolio aggregate into portfolio-level signals, and a portfolio ban takes everything down at once. One bad campaign rarely escalates that far; a pattern of them will. ## Next Steps Set up the WhatsApp broadcast channel and configure templates and variables Audience, properties, scheduling, and analytics for every broadcast Segment your contacts so the right message reaches the right people Manage replies, opt-outs, and complaints in one place # Inbox Source: https://docs.useinvent.com/guides/inbox View and manage every customer conversation from every channel in one unified space The Inbox is your central hub for every conversation your assistant is having. WhatsApp, Instagram, Messenger, TikTok, Telegram, Slack, Gmail, SMS, the Web Widget, they all land here, in the same view, with the same tools. You can watch the AI work, jump in whenever you want to reply as a human, hand the conversation back, and resolve it when it is done. Inbox overview with the conversation list on the left, message thread in the center, and contact panel on the right ## Layout The Inbox is a three-panel layout: 1. **Conversation list** (left): every conversation, with filters, search, and status indicators. 2. **Message thread** (center): the full chat history plus a reply composer at the bottom. 3. **Contact panel** (right): everything Invent knows about the customer, across three tabs, Contact, Files, and Activity. You can collapse the contact panel with the toggle at the top of the message thread to focus on the conversation. ## Conversation List The left panel lists every conversation across every channel and every assistant in your workspace. Each entry shows: * **Avatar and contact name**. Contacts without a name shared yet appear as *Unnamed*. * **Last message preview**. A one-line snippet of the most recent message. * **Timestamp**. Relative time since the last message (`6h`, `21h`, `1d`, `2d`). * **Channel indicator**. A small channel logo badge on the contact avatar (the green WhatsApp glyph, the Web Widget speech bubble, and so on) so you know at a glance which channel the message came from. * **Status indicator**. A green check means **Resolved**. Other states (unread, waiting for human, follow-up scheduled) have their own icons. * **CSAT badge**. When [Auto CSAT](/assistants/introduction#capabilities) is enabled, the star rating (1–5) appears on resolved entries. * **Follow-up countdown**. If [Auto Follow-ups](/guides/auto-follow-ups) has scheduled a re-engagement, the entry shows the time-until-next-follow-up and a **Cancel** button. ### Filters The filter dropdown at the top of the list narrows the view: * **All**: every conversation. * **Unread**: conversations with new messages you have not opened yet. * **Unresolved**: open conversations (either the AI is handling them or they are waiting for a reply). * **Resolved**: closed conversations. * **Assigned to me**: conversations where you are the assigned [agent](/assistants/routing). * **Unassigned**: conversations with no agent assigned. You can also filter by assistant using the assistant dropdown, and search by contact name with the search field. Additional header filters narrow the list further: by assigned **Agent**, by **Segment**, by **Referral source**, and by **CSAT** rating. Keep a tab on **Unresolved** during the day to make sure no conversation sits too long without progress, and check **Unread** first thing in the morning for anything that came in overnight. ## Message Thread Click any conversation to open the full thread in the center panel. Inside the thread you will see: * **Conversation title**: an AI-generated summary at the top, like *"Open Claw Connection"*. * **Customer and assistant messages**, with date dividers between days. * **Knowledge indicators** under AI replies, such as *"Found 3 results in knowledge base"* or *"Thought for 2 seconds"*. * **System events** in grey italic for everything the AI and your agents do: *AI resolved the conversation*, *AI scored customer satisfaction*, *AI-generated memories from conversation*, *An agent reopened the conversation*, and more. * **Follow-up banners** with the scheduled time and AI reasoning when [Auto Follow-ups](/guides/auto-follow-ups) is active. * **CSAT scores** inside the *Conversation resolved* card when [Auto CSAT](/assistants/introduction#capabilities) is enabled. * ...and more as new capabilities ship. ### Three-Dot Conversation Actions Click the three-dot menu at the top of any conversation for additional actions: * **Mark As Unread**: bring the conversation back to the top of your unread list. * **Mute**: silence the conversation for a preset duration (15 minutes, 1 hour, 3 hours, 24 hours, until tomorrow, 3 days, 1 week, 1 month, or 1 year). Resume it manually at any time. * **AI Replies**: toggle the assistant off for this conversation to make it human-only (see [Human-only mode](#human-only-mode-ai-replies-off) below). * **Unsubscribe Contact**: stop this contact from receiving broadcast messages, without removing them from your audience. * **Transcript**: download or copy the full conversation as Markdown. * **Block Contact**: reject further incoming messages from this contact across every channel. * **Delete Chat**: permanently remove the conversation. The contact stays in your [Audience](/guides/audience). ### Human-only Mode (AI Replies off) Turning **AI Replies** off puts the conversation into human-only mode: incoming messages are still received and stored, but the assistant never responds, so your team answers every reply. A **Human-only** badge appears on the conversation. You can flip AI Replies from the conversation three-dot menu, and the same capability lives in the assistant's Capabilities settings. ## Replying and Handoff The **reply composer** lives at the bottom of every open conversation. It is always there, with the Reply input and attach button ready, whether the AI is handling the conversation or you have already taken over. The composer only disappears once the conversation is **closed**, replaced by a *Conversation ended* card with a **Reopen** button. On WhatsApp, the composer is also replaced by an **Outside 24h window** notice when the 24-hour messaging window has lapsed, and you must wait for the customer to message again or send a template broadcast. **Just type and send.** You do not have to click **Take Over** first. The moment you send a message, Invent hands the conversation off from the AI automatically, delivers your reply to the customer, and from that point the conversation waits for you until you hand it back. It is the fastest way to jump in. ### The Composer The Reply input, the **+** attach button (photos, documents, files, recorded videos), and the send arrow are always present. The rest of the controls swap depending on who is currently handling the conversation. **While the AI is handling the conversation:** * **Model selector**: lock the next reply to a specific model (see [Picking the model for a single reply](#picking-the-model-for-a-single-reply)). * **Take Over** (orange): pause the AI on this conversation without sending a message, so you can scroll, read, or prepare a reply before the AI answers. If you just want to send a message, skip this button and type directly. * **Resolve** (green): close the conversation immediately. **After you have taken over (manual mode):** * **Hand Over to AI** (purple): return the conversation to the assistant so future customer messages trigger the AI again. * **Resolve** (green): close the conversation. A system event is recorded in the thread for every transition (*An agent took over the conversation*, *An agent handed the conversation back to the AI*), so the history is always auditable. ### Writing Assistant The **wand** button on the composer gives you AI writing help on the current draft, plus your saved replies. Open the menu (the chevron next to the wand) for the full set: * **Draft a reply**: writes the next reply for you from the recent conversation, matching the customer's language and following your assistant's instructions. Use it on an empty composer to get a first draft. * **Polish**: fixes grammar, spelling, and punctuation while keeping your wording. * **More formal** / **Friendlier**: shifts the tone without changing the meaning. * **Shorter**: tightens a long draft down to the essentials. Nothing is ever sent automatically. The result drops into the composer for you to review and edit, and you can keep refining it (draft a reply, then shorten it, then polish it). **What it costs.** Each AI writing action (Draft, Polish, More formal, Friendlier, Shorter) uses a small amount of AI credits, the same usage-based way as the rest of the assistant. The exact amount varies with the length of the text and the model, but a single rewrite is minimal. See [Plans & Pricing](/guides/pricing-and-plans) for how usage is billed. #### Canned Replies Save the messages you send over and over (shipping times, return policy, opening hours) and drop them into the composer in one tap from the wand menu. * **Free to use.** Inserting a canned reply pastes your saved text into the composer, so it costs nothing. Only the AI writing actions above use credits. * **Can carry attachments.** A canned reply isn't limited to text: it can include up to 5 file attachments (from files already uploaded to your org). Inserting it drops both the text and its attachments into the composer. * **Private to you.** Canned replies are personal to your account. They are not shared with the rest of your team. * **Editable after inserting.** Once a canned reply is in the composer you can tweak it, or run it through Polish or Shorter like any other draft. Add, edit, or delete your snippets from **Manage replies** at the bottom of the wand menu. You can save up to 20. ### Picking the Model for a Single Reply The model selector on the composer controls which model the assistant will use for its **next response** on this conversation, overriding the assistant's default for one reply only: * **Auto** (default): let Invent pick the best model for the message. * **Specific model** (ChatGPT, Claude, Gemini, Grok, and the full lineup): lock this next reply to that model. Useful when you want to pressure-test a specific model on a tricky customer message, or when you need extra reasoning capacity on a complex question without switching the assistant's default. ### Automatic Agent Assignment When **Transfer to Member** is enabled on the assistant, Invent automatically routes conversations the AI cannot handle, or that the customer explicitly asks a human for, to your team: 1. The AI flags the conversation as **Waiting for Human** and records the reason in the thread. 2. Invent assigns the conversation to an **available** [agent](/assistants/routing) on the assistant, if one is available. 3. If no agent is available, the conversation stays **Unassigned** and any permitted team member can claim it with **Take Over** from the Inbox. You can restrict which team members can be assigned to each assistant from [Settings → AI Routing](/assistants/routing#choose-who-an-assistant-routes-to), so sales conversations always route to the sales team, support to the support team, and so on. A member's **Available/Unavailable** status controls whether they receive auto-assignments. ### Resolving and Reopening Click **Resolve** on any open conversation to mark it complete. The thread shows a **Conversation ended** card at the bottom with a **Reopen** button. If a customer messages again after you resolve, the conversation reopens automatically and goes back to the AI (or to the assigned member). You can also click **Reopen** manually to resume a resolved conversation from your side. ## Contact Panel The right-hand panel summarises everything Invent knows about the customer for the selected conversation. It has three tabs: **Contact**, **Files**, and **Activity**. ### Contact Tab The default view. All key information is grouped into collapsible sections. Contact panel showing info, profile, memories, and files #### Info Top-level details about the current conversation: * **Assistant**: which assistant is handling the conversation. * **Agent**: the assigned human agent. Use the dropdown to assign or reassign a team member, or **Take Over** to claim the conversation yourself. * **Segments**: add or remove [segments](/guides/audience/segments) for this contact. * **CSAT**: the satisfaction score for this conversation (1–5 stars). Shows the auto-generated score if [Auto CSAT](/assistants/introduction#capabilities) is enabled, or lets you score manually. * **Follow-up**: schedule a follow-up with preset intervals (1h, 3h, 12h, 24h) or a custom date. When [Auto Follow-ups](/guides/auto-follow-ups) is enabled, the countdown and a **Cancel** button appear here. #### Referral Shows where this conversation originated from, if the source is known. Contact panel showing referral source and files For ad and product referrals you see the platform, product image, name, price, and description. For web widget conversations you see the full UTM breakdown (source, medium, campaign, term, content, ad, page URL, Google Click ID, Facebook Click ID). [Learn more about Tracking](/guides/tracking). #### Profile Contact details and device info: * **Name**, **Email**, **Phone**: core contact fields, editable inline. * **Country** and **Language**: detected from the channel or device. * **Device**: browser and device for web widget contacts. * **Link**: a one-click link to message the contact on their native channel (for example, a `wa.me` link for WhatsApp). * **+ Add email or phone**: attach an email address or phone number to the contact. #### Memories Everything the assistant remembers about this customer, organised by type (Facts, Preferences, Goals, Experiences). [Memories](/guides/memory) persist across every channel and every conversation, so the assistant can pick up where it left off weeks or months later. You can delete individual memories from here if a customer asks. #### Files A preview of the five most recently shared files, with a **See All** link that switches to the Files tab. You can also upload files from the section header, which then appear inside the conversation. #### Conversations The last ten conversations with this contact across every assistant. Each entry shows resolution status and date, and clicking it jumps you straight there. #### Broadcasts A list of [broadcasts](/guides/broadcasts/introduction) this contact has received, with delivery status (e.g., *Opened*) and the broadcast name. #### Activity Preview A compact view of recent activity on this contact with a **Write a note…** input for quick internal notes. Click **Load More** or switch to the Activity tab for the full timeline. ### Files Tab The full list of files shared in conversations with this contact. You can: * Browse and search every uploaded file. * Upload new files with the **Upload files** button (they are attached to the conversation and to the contact). * Paginate with **Load more**. ### Activity Tab A complete timeline for this contact: conversation events, segment changes, agent actions, and internal notes. Add notes from the top of the timeline to leave context for teammates. Inbox showing the Activity tab with notes and timeline ## Common Flows ### 1. The AI handled it, you just confirm 1. Open the conversation to watch or review. 2. If the AI already closed it, you see the *Conversation resolved* card with an auto-generated summary and (if enabled) a CSAT score. 3. No action needed. ### 2. The customer asks for a human 1. The AI flags the conversation as *Waiting for Human* (if **Transfer to Member** is enabled) and Invent auto-assigns it to an available member on this assistant, or leaves it **Unassigned** if nobody is available. 2. The assigned member (or anyone with access) opens the conversation and replies from the composer. Typing and sending a reply is enough, Invent hands off from the AI automatically. 3. When the issue is resolved, click **Hand Over to AI** to keep the conversation open, or **Resolve** to close it. ### 3. You want to jump in proactively 1. Open any live conversation. 2. Type your reply and send, the AI pauses automatically for this conversation. (Or click **Take Over** first if you want to pause the AI without sending a message yet.) 3. Continue replying manually as many times as you need. 4. Click **Hand Over to AI** to return the conversation to the assistant, or **Resolve** to close it. ### 4. A resolved conversation comes back 1. The customer messages again and the conversation reopens automatically. 2. The AI (or the assigned member) picks it back up where it left off, with full [Memory](/guides/memory) intact. ## Best Practices 1. **Let the AI work first**. Most conversations resolve on their own. Jumping in too early short-circuits the assistant and adds manual load. 2. **Filter ruthlessly**. **Unresolved** and **Waiting for Human** are the only two lists you really need to watch during the day. 3. **Leave notes**. Internal notes on the Activity tab keep context with the contact forever, across every future conversation. 4. **Trust Resolve**. A resolved conversation automatically re-opens if the customer replies, so you do not need to leave things open "just in case". 5. **Just type when you need to jump in**. You do not have to click **Take Over** first. Send a message and the AI pauses on that conversation automatically. 6. **Hand it back**. After a manual take-over, almost always click **Hand Over to AI** so the next message benefits from Knowledge and Memory again. ## Next Steps Set up routing members, assignment, and access scopes for each assistant Automatically re-engage idle conversations instead of letting them close silently See how the assistant remembers customers across every channel and conversation Know where each conversation originated, from ads to UTMs # Knowledge Source: https://docs.useinvent.com/guides/knowledge Train your AI assistant with your business data, documentation, and information Knowledge is how you teach your AI assistant about your business. Upload your documentation, FAQs, product information, and any other content you want your assistant to know. The more relevant knowledge you provide, the better your assistant answers customer questions. Knowledge Overview ## Knowledge Types You can add three types of knowledge. Click **Upload Knowledge** to see the three tabs: **File**, **Text**, and **Website**. ### Files Upload documents directly from your computer. Drag and drop files into the upload area, or click to browse. Upload Files **Common formats include:** * PDF documents (.pdf) * Word documents (.doc, .docx) * Spreadsheets (.xlsx) * Text files (.txt) * Markdown files (.md) * Images (.png, .jpg, .jpeg, .webp) Audio and video files are also supported: Invent transcribes them automatically and indexes the text. More formats work beyond the list above. Each file can be up to **50 MB**. You can upload multiple files at once. ### Text Add content directly with a title and body. This is the fastest way to give your assistant specific information that does not exist in a document or on your website. Upload Text Each text item has two fields: * **Title**: A descriptive name for this content (e.g., "Pricing", "Return Policy", "Class Schedule"). The title helps you organize your knowledge and helps the assistant identify relevant content * **Content**: The actual information you want the assistant to know. Supports up to **2,097,152 characters** per item Click **Add Content** to save. **Best for:** * FAQs and Q\&A pairs * Pricing and plan details * Policy snippets * Product descriptions * Promotional offers or seasonal information * Any information that does not exist in a document or on your website ### Website Connect websites and web pages by URL. Invent extracts the content automatically so your assistant can answer questions based on your published content. Upload Website Enter a **Website URL or Sitemap URL** (e.g., `example.com` or `example.com/sitemap.xml`) and select a **Mode**: * **Single Page**: Indexes only the specific URL you provide. Use this for individual pages like a pricing page or FAQ * **Crawl**: Follows links from the starting URL to discover and index multiple pages across your site. Use this for help centers, documentation sites, or entire sections of your website Click **Add Website** to start indexing. Your content appears in the table below with its status, last updated time, and size. **Works well for:** * Help center articles and documentation * Product and pricing pages * Blog posts and announcements * Any publicly accessible web content Use a **sitemap URL** (e.g., `example.com/sitemap.xml`) with Crawl mode for the most complete coverage. Sitemaps tell Invent exactly which pages to index, so nothing gets missed. ## Cost Knowledge comes with a small usage cost that scales with how much you upload and how often your assistant uses it. Most organizations find this cost very low, but we want to be upfront about it so you can plan with confidence. Knowledge is billed in two places: * **At upload, \$0.0005 per chunk (one-time).** When you add a file, text, or website, Invent splits it into smaller **chunks** and indexes each one so it can be searched. A chunk is roughly **350–400 words** (about half a page of typical text). Each chunk costs **\$0.0005** to index, charged once at upload. The **Total Chunks** stat on the Knowledge page tells you exactly how many chunks your content produced, so you can always see what you have paid for. * **At query time, \$0.0005 per search.** Each Knowledge Base Search your assistant runs costs a flat **\$0.0005**, regardless of how much content is in your knowledge base. Retrieved chunks are then included as context in the message and count toward its normal input-token cost. ### Example upload costs | Content | Approx. size | Chunks | One-time cost | | ------------------------ | -------------- | --------- | ------------- | | A short FAQ page | \~500 words | \~1–2 | **\~\$0.001** | | A policy or product page | \~2,000 words | \~5–6 | **\~\$0.003** | | A 10-page document | \~5,000 words | \~13–14 | **\~\$0.007** | | A 50-page manual | \~25,000 words | \~65–70 | **\~\$0.035** | | A 100-page help center | \~50,000 words | \~130–140 | **\~\$0.07** | ### Example query costs | Usage | Cost | | ------------------------------- | ------------ | | 100 unique questions / month | **\~\$0.05** | | 1,000 unique questions / month | **\~\$0.50** | | 10,000 unique questions / month | **\~\$5.00** | Repeated identical questions within 2 hours are cached across your whole organization and do not re-charge. In practice: * **Larger documents produce more chunks**, and therefore a slightly higher one-time upload cost and more content to search through. * **Repeated searches are cached for free.** When the same question is asked more than once, Invent reuses the previous search result for up to 2 hours across your entire organization, so you are not billed for the repeat. Only new or different questions trigger a fresh search. * **Knowledge Base Searches use up to 20% less tokens** thanks to ongoing optimizations, so each search is already quite efficient. All of this is deducted from your regular credit balance. There are no separate knowledge bills. You can monitor usage in **Settings → Usage**, and see the full pricing model in [Plans & Pricing](/guides/pricing-and-plans#knowledge). If you want to keep costs down, upload focused documents rather than massive ones, and remove knowledge that is no longer relevant. Fewer, sharper chunks usually give both better answers and a lower bill. ## Knowledge Statistics The Knowledge page shows you exactly what your assistant knows: * **Total Contents**: Number of knowledge items you've added * **Total Chunks**: How the content is split for processing (more chunks = more detailed knowledge) * **Total Size**: Combined size of all your knowledge * **Pending**: Items still being processed * **Failed**: Items that couldn't be processed (check these for issues) ## Processing Status After uploading, each item goes through processing: 1. **Pending**: Upload received, waiting to process 2. **Processing**: Content is being analyzed and indexed 3. **Processed**: Ready for your assistant to use 4. **Failed**: Something went wrong (usually format issues) ## Knowledge Scope You have full control over what knowledge each assistant can access. There are two types of knowledge: ### Global Knowledge Knowledge uploaded from the main Knowledge page is available organization-wide. You can: * **Use all global knowledge**: Give an assistant access to everything * **Select specific items**: Choose only certain knowledge pieces for an assistant * Perfect for company-wide policies, general FAQs, and brand guidelines ### Assistant-Specific Knowledge Knowledge uploaded directly from an assistant's Knowledge tab is private to that assistant only. Use this for: * Product-specific documentation * Channel-specific information * Specialized use cases that other assistants shouldn't access This gives you complete control: share common knowledge across all assistants while keeping specialized information separate. Knowledge Scope ## Best Practices 1. **Keep content focused**: Smaller, specific documents work better than massive files 2. **Keep knowledge up to date**: For websites, click the three-dot menu and select "Re-index" to refresh content automatically. For files and text, you'll need to reupload or rewrite them with updated information 3. **Use clear language**: Write as if explaining to a new employee 4. **Test your assistant**: After adding knowledge, ask questions to verify it works # Memory Source: https://docs.useinvent.com/guides/memory Long-term memory that remembers every customer detail across all conversations Memory is what makes your AI assistant truly personal. Unlike typical chatbots that forget everything after each conversation, Invent remembers every important detail about your customers forever. Memory Overview ## How Memory Works Every time your assistant has a conversation, it automatically identifies and stores important information about the customer: * Names and preferences * Past purchases or inquiries * Specific requests or issues * Personal details they've shared * Conversation context and history This information persists across all conversations, even when customers return days, weeks, or months later, and even through different [channels](/assistants/channels). ## Why Memory Matters ### Personalized Experiences When a customer messages your [WhatsApp](/assistants/channels) number for the first time in weeks, your assistant already knows: * Their name * What they bought last time * Any issues they had * Their preferences No awkward "How can I help you?" when they're following up on something specific. ### Consistent Across Channels A customer chats on your website, then messages on Instagram a week later. Your assistant remembers everything from both conversations. The customer does not need to repeat themselves. ### Building Relationships Memory transforms routine interactions into relationship-building moments: * "Welcome back, Sarah! How did the yoga class go last Tuesday?" * "I remember you mentioned you prefer morning appointments." * "Last time you asked about our premium plan, still interested?" ## What Gets Remembered Your assistant automatically identifies and stores: * **Contact information**: Names, emails, phone numbers * **Preferences**: Favorite products, preferred times, communication style * **History**: Past purchases, previous issues, conversation summaries * **Context**: Ongoing projects, pending requests, follow-up items You don't need to configure anything. Memory works automatically. Memory is controlled by the **Memories** capability toggle in assistant **Settings → Capabilities**. It is on by default, so you can leave it as is, but you can turn it off for an assistant that shouldn't retain customer details. ## Viewing Customer Memory In the [Inbox](/guides/inbox), select any conversation and open the [Contact Panel](/guides/inbox#memories) on the right. The **Memories** section lists everything your assistant remembers about this customer, organized by type (Facts, Preferences, Goals, Experiences). You can view and delete individual memories from here. ## Privacy and Control Memory respects customer privacy: * Customers can request their data be deleted * You can clear memory for any contact * Sensitive information (like payment details) is handled securely * Memory only stores what's relevant to customer service ## Memory in Action Here's a real example of memory working: **First conversation (Monday):** > Customer: "Hi, I'm looking for a yoga class for beginners" > Assistant: "Great! We have beginner classes Tuesday and Thursday at 6 PM. Would you like to book one?" > Customer: "Tuesday works. My name is Maria." > Assistant: "Perfect, Maria! You're booked for Tuesday at 6 PM." **Second conversation (Following week):** > Customer: "Hey" > Assistant: "Hi Maria! How was your first yoga class last Tuesday? Ready to book another session?" The assistant remembered Maria's name, that she's a beginner, and when her class was, all without being asked. ## Best Practices 1. **Let it work automatically**: Memory handles itself, no configuration needed 2. **Review occasionally**: Check what your assistant remembers about key customers in the [Inbox](/guides/inbox) 3. **Trust the process**: The more conversations, the smarter your assistant becomes 4. **Respect privacy**: Delete memory when customers request it 5. **Combine with Instructions**: Add a "What to Remember" section in your [Instructions](/guides/practical/writing-instructions#5-scenario-handling) to guide what your assistant prioritizes (e.g., names, preferences, past purchases) ## Next Steps View customer memories alongside conversations in the contact panel Add memory-related rules to your instructions for better personalization # Context Engineering Source: https://docs.useinvent.com/guides/practical/context-engineering Teach your assistant how to prioritize information, avoid hallucination, and deliver precise answers You have uploaded your pricing, policies, and product docs. You have written clear [instructions](/guides/practical/writing-instructions). But your assistant still gives vague answers, mixes up information from different sources, or occasionally makes things up. The missing piece is **context engineering**: teaching your assistant how to find, prioritize, and use information from multiple sources. This is what separates assistants that "kind of work" from assistants that feel like a real team member. ## What Is Context Engineering? Context engineering is the practice of telling your assistant **which information to trust, in what order, and how to handle gaps**. It lives inside your [Instructions](/guides/practical/writing-instructions) and works together with your [Knowledge Base](/guides/knowledge). Without context engineering, your assistant treats all [Knowledge](/guides/knowledge) equally. A blog post from six months ago carries the same weight as your current pricing page. An outdated FAQ competes with your latest policy update. With context engineering, your assistant knows: * Which sources to check first * How to handle conflicting information * What to do when it cannot find an answer * How to present sources naturally Context engineering is especially important once your assistant has more than 2-3 Knowledge items. The more sources you add, the more your assistant needs guidance on how to use them. ## Knowledge Source Hierarchy The most impactful thing you can add to your instructions is a **trust order** for your knowledge sources. This tells the assistant which source wins when information overlaps or conflicts. Add a section like this to your Instructions: ``` ## Knowledge Source Priority When answering questions, check sources in this order: 1. Pricing documents and pages (for costs, plans, and billing) 2. Official policies (for refunds, terms, and cancellations) 3. Product documentation and FAQs (for features and troubleshooting) 4. Announcements and changelogs (for recent updates) If two sources give different answers, use the most recently updated source. If you are still unsure, tell the customer and offer to connect them with our team. ``` This prevents a common failure: the assistant quoting an outdated FAQ when the pricing page has the correct, current number. ## Retrieval and Response Method Guide how your assistant constructs its answers from knowledge sources. ``` ## How to Answer - Find the specific, relevant section in the knowledge base before answering - Lead with a direct answer in 1-3 sentences - Add supporting details (steps, bullet points) only if needed - If a key detail is missing from the conversation, ask one clarifying question before making assumptions Example: Ask "Which plan are you interested in?" instead of guessing the customer's plan. ``` This produces focused, accurate responses instead of long, wandering answers that try to cover everything. ## The No-Hallucination Fallback This is the most important safety net in your [instructions](/guides/practical/writing-instructions). Tell your assistant exactly what to do when it does not have the answer. ``` ## When You Don't Know If the knowledge base does not contain the answer: - Never guess, estimate, or invent information - Say: "I don't have that information in our docs yet. Would you like me to connect you with our team?" - For pricing: never make up numbers. Say: "Let me check with our team on that specific pricing." ``` Without this rule, AI models will try to be helpful by generating plausible-sounding answers that may be completely wrong. An explicit fallback prevents this. Hallucination is the most common reason businesses lose trust in their AI assistant. A clear "I don't know" is always better than a confident wrong answer. Make your fallback instructions specific and direct. ## Natural Source Linking When your assistant references information from its Knowledge Base, the default behavior can sound robotic. Teach it to share sources naturally. ``` ## Sharing Sources When referencing information from the knowledge base, use natural language instead of formal citations: Good: - "You can find the full details on our pricing page" - "Our refund policy covers this. Here's the key part..." - "More info here if you'd like to read the full breakdown" Bad: - "Source: pricing.pdf" - "According to document #3..." - "Reference: company-policies.docx, page 12" Only link to URLs that actually exist in the knowledge base. Never generate or guess URLs. ``` ## Handling Conflicting Information As your [Knowledge Base](/guides/knowledge) grows, you may end up with information that overlaps or contradicts itself. Prepare your assistant for this. Keep your [Knowledge Base](/guides/knowledge) well-organized with one authoritative source per topic to avoid conflicts in the first place. ``` ## Conflicting Information If you find conflicting details across different knowledge sources: 1. Use the source highest in the priority order 2. If both sources are at the same level, use the one that was most recently updated 3. If you cannot determine which is correct, tell the customer: "I'm seeing some conflicting details on this. Let me connect you with our team to make sure you get the right answer." ``` The best way to prevent conflicting information is to audit your Knowledge Base regularly. Remove outdated documents, merge overlapping content, and keep one authoritative source for each topic. See the [maintenance tips](#ongoing-maintenance) below. ## Complete Context Engineering Template Here is a full context engineering section you can add to your [Instructions](/guides/practical/writing-instructions): ``` ## Context Engineering ### Source Priority 1. Pricing and billing documents 2. Official policies (refunds, terms, cancellations) 3. Product docs and FAQs 4. Blog posts and announcements ### Response Method - Always check the knowledge base before answering factual questions - Lead with a direct, short answer - Add details only when helpful - Ask one clarifying question if key information is missing ### When You Don't Know - Never guess or make up information - Say: "I don't have that in our docs yet. Want me to connect you with our team?" ### Conflicting Information - Follow the source priority order above - When unsure, escalate to a human ### Source References - Use natural language when referencing sources - Never show raw file names or document IDs - Only link URLs that exist in the knowledge base ``` ## Real-World Impact **Without context engineering:** > Customer: "What's the refund policy for the Pro plan?" > > Assistant: "Refunds are generally available within 30 days." *(vague, possibly wrong, no source)* **With context engineering:** > Customer: "What's the refund policy for the Pro plan?" > > Assistant: "Pro plan subscriptions can be cancelled anytime, but refunds are only available within the first 14 days of a billing cycle. After that, your access continues until the end of the current period. You can find the full policy details here if you'd like to review them." The difference: the assistant checked the right source, gave a precise answer, and referenced it naturally. ## Ongoing Maintenance Context engineering is only as good as the Knowledge Base it works with. Keep both healthy: **Weekly**: Review conversation logs in the [Inbox](/guides/inbox) for questions the assistant struggled with. Check whether the answer exists in [Knowledge](/guides/knowledge) and whether the assistant found it. **Monthly**: Audit your Knowledge Base for outdated or conflicting content. Remove documents that have been superseded. Merge overlapping sources into one authoritative version. **After business changes**: When you update pricing, policies, or products, update the corresponding [Knowledge](/guides/knowledge) items immediately. Outdated knowledge with good context engineering still produces wrong answers. Every Knowledge item has a "Re-Index" action in its three-dot menu to refresh the content after the source changes. For websites this re-crawls the site; for files, re-upload the updated document; for text, edit it in place using the content editor. ## Next Steps Make sure your information is in the right place before adding context engineering Build the full instruction set that context engineering plugs into # Instructions vs Knowledge Source: https://docs.useinvent.com/guides/practical/instructions-vs-knowledge Understand when to use Instructions and when to use the Knowledge Base, and why getting it wrong hurts your assistant's performance One of the most common questions when setting up an [assistant](/assistants/introduction) is: "Where should I put this information?" The answer depends on whether the information defines **how your assistant behaves** or **what your assistant knows**. Getting this right is the single biggest factor in how well your assistant performs. Put pricing in [Instructions](/assistants/introduction#instructions) and it gets buried. Put personality rules in [Knowledge](/guides/knowledge) and they get ignored. This guide gives you a clear framework. ## The Core Difference **[Instructions](/assistants/introduction#instructions)** define behavior. They tell your assistant how to act, what tone to use, what rules to follow, and when to escalate. **[Knowledge](/guides/knowledge)** provides facts. It gives your assistant the actual information it needs to answer questions: pricing, policies, product details, schedules, and documentation. Think of it this way: * **Instructions** = the employee handbook (how to do your job) * **Knowledge** = the product catalog and reference binder (what you need to look up) A good rule of thumb: if the information changes when your business updates a policy, product, or price, it belongs in **Knowledge**. If it changes when you want your assistant to behave differently, it belongs in **Instructions**. ## Quick Reference | Information | Where It Goes | Why | | ----------------------------------------------- | ------------- | --------------------------------------------------------- | | Business personality and tone | Instructions | Defines behavior, not facts | | Opening hours | Instructions | Short, stable, behavioral context | | General pricing (2-3 tiers) | Instructions | Quick reference the assistant always needs | | Detailed pricing lists (10+ items) | Knowledge | Too long for instructions, needs search | | Product catalogs | Knowledge | Large, structured data | | Return/refund policies | Knowledge | Detailed, may change, needs exact wording | | FAQ documents | Knowledge | Searchable reference material | | Class schedules / menus | Knowledge | Structured data that changes regularly | | Escalation rules | Instructions | Behavioral rules | | Greeting and closing messages | Instructions | Defines conversation style | | Troubleshooting guides | Knowledge | Step-by-step reference material | | Images and documents | Knowledge | Only [Knowledge](/guides/knowledge) supports file uploads | | [Agent](/assistants/routing)-specific workflows | Instructions | Defines how to handle scenarios | | Legal disclaimers | Knowledge | Exact wording matters, reference material | ## When to Use Instructions Instructions are for anything that shapes **how** your assistant communicates and makes decisions. Keep them concise and action-oriented. ### What belongs in Instructions **Identity and personality** ``` You are the friendly concierge for Sunrise Yoga Studio. Be warm, welcoming, and patient with beginners. ``` **Short, stable facts the assistant always needs** ``` Our opening hours are Monday to Friday, 9 AM to 6 PM. We are located at 123 Wellness Way, Downtown. ``` **Response rules** ``` Keep responses under 3 sentences when possible. Never guess pricing. Always refer to the knowledge base. Always confirm booking details before finalizing. ``` **Escalation rules** ``` If a customer asks for a refund, transfer to a human agent. If you are unsure about something, offer to connect with a team member. ``` **Greeting and closing patterns** ``` Always greet customers by name when known. End conversations with: "Let me know if there's anything else I can help with!" ``` **[Action](/assistants/actions)-specific behavior** ``` After payment is verified, always send a confirmation email and calendar invite. Never suggest booking outside of Google Calendar. ``` Do not put large blocks of factual content in Instructions. Long instructions increase token usage on every single message, raising costs. They also make it harder for the assistant to find the behavioral rules that actually matter. [Learn more about pricing](/guides/pricing-and-plans) ## When to Use Knowledge Knowledge is for any factual content your assistant needs to look up and reference. The assistant searches Knowledge when relevant, so it only pulls in what it needs for each conversation. ### What belongs in Knowledge **Detailed product information** * Product catalogs with descriptions, specs, and images * Feature comparison tables * Inventory or availability data **Pricing and packages (when detailed)** * Full pricing tables with tiers, add-ons, and conditions * Long pricing lists with many items * Subscription details and billing terms **Policies and procedures** * Return and refund policies * Terms of service * Cancellation rules * Shipping information **Guides and documentation** * Troubleshooting steps * How-to guides * Onboarding documentation * Setup instructions **Frequently asked questions** * Common questions and their exact answers * Pre-written responses for sensitive topics **Schedules and structured data** * Class schedules, menus, event calendars * Staff bios and specialties * Location details with directions **Files and media** * PDF documents, Word files * Product images and diagrams * Any content from your website [Knowledge](/guides/knowledge) supports three content types: **Files** (PDF, Word, text, markdown up to 50 MB each), **Text** (paste content directly), and **Website** (crawl a URL). Use whichever fits your source material best. See the [Knowledge documentation](/guides/knowledge) for details on each content type. ## The Gray Area Some information could reasonably go in either place. Here is how to decide: ### Short and stable? Use Instructions. If the information is a few lines and rarely changes, it is fine in Instructions. Your assistant will always have it immediately available. ``` We offer three plans: Starter ($29/mo), Pro ($79/mo), and Enterprise (custom). ``` ### Long or detailed? Use Knowledge. If you need more than a few lines to explain it, move it to Knowledge. This keeps your Instructions focused and reduces per-message costs. ```markdown theme={"system"} # Pricing Plans ## Starter - $29/month - 5 team members - 1,000 messages/month - Email support - Basic analytics ... ## Pro - $79/month - 25 team members - 10,000 messages/month - Priority support - Advanced analytics - Custom branding ... ``` ### Changes frequently? Use Knowledge. If you update this information regularly (seasonal menus, weekly schedules, rotating inventory), put it in Knowledge. It is much easier to update a Knowledge item than to edit Instructions every time something changes. ### Needs exact wording? Use Knowledge. For legal text, compliance language, or any content where the exact phrasing matters, use Knowledge. The assistant will reference the source directly rather than paraphrasing from memory. ## Common Mistakes This bloats every message with unnecessary context. Your assistant processes the full Instructions on every single message, so longer instructions mean higher costs and slower responses. Move FAQs to Knowledge where they are searched only when relevant. Rules like "always be friendly" or "never discuss competitors" get lost when placed in Knowledge. The assistant searches Knowledge for factual answers, not behavioral guidance. These rules belong in Instructions where they are always active. Having pricing in both Instructions and Knowledge creates confusion. If one gets updated and the other does not, your assistant may give inconsistent answers. Pick one place and keep it there. If you put detailed pricing in Knowledge, just add a note in Instructions: "For pricing questions, always reference the knowledge base." See [Context Engineering](/guides/practical/context-engineering) for how to set up source priority rules. Instructions should be a concise guide for behavior, not an encyclopedia. If your Instructions are longer than a page of text, you probably have factual content that belongs in Knowledge. ## Putting It Together A well-configured assistant uses both layers working together. Instructions tell the assistant **how to use** the Knowledge, and Knowledge gives it **what to say**. **Example: Instructions referencing Knowledge** ``` ## Pricing Questions When customers ask about pricing, always check the knowledge base for current plans and pricing. Never guess or make up prices. If the knowledge base does not have the answer, say: "Let me connect you with our team for the latest pricing details." ## Refund Requests For refund requests, reference our refund policy in the knowledge base. If the request falls outside the documented policy, transfer to a human agent. ``` This pattern keeps Instructions lean and behavioral while letting Knowledge handle the detailed, searchable content. ## Next Steps Learn how to craft clear, effective instructions that shape your assistant's behavior Learn how to add and manage your assistant's knowledge base # Writing Effective Instructions Source: https://docs.useinvent.com/guides/practical/writing-instructions How to write clear, effective instructions that shape your assistant's behavior and deliver great customer experiences Instructions are the single most important configuration in your [assistant](/assistants/introduction). They define its personality, set its boundaries, guide its decisions, and shape every interaction your customers have. A well-written set of instructions turns a generic chatbot into a trusted representative of your business. This guide walks through each element of effective instructions, with templates and real examples you can adapt. ## The Building Blocks Great instructions cover these key areas. You do not need every section for every assistant, but thinking through each one will help you build a more reliable experience. ### 1. Identity and Purpose Start by telling your assistant who it is and what it does. This grounds every response and prevents the assistant from going off-script. ``` You are the customer support assistant for TechFlow. Your primary purpose is to help customers resolve issues with their accounts, answer questions about our products, and ensure a positive support experience. ``` Keep it to 2-3 sentences. The assistant needs a clear role, not a biography. ### 2. Tone and Personality Define how your assistant should sound. Be specific about traits, not just adjectives. ``` ## Your Personality - Friendly and conversational, but professional - Use natural contractions (you're, we'll, that's) - Patient and encouraging with beginners - Concise. Get to the point without being abrupt - Never use corporate jargon or marketing speak ``` Try describing how your best employee talks to customers. That is usually the right tone for your assistant. Bad example: "Be helpful and professional." (too vague, every assistant tries to do this) Good example: "Speak like a knowledgeable friend. Use short sentences. Explain technical terms when you use them." (specific and actionable) ### 3. Response Rules Set clear guidelines for how the assistant structures its responses. ``` ## Response Rules - Keep responses to 1-3 short sentences when possible - Never ask multiple questions at once - Match the customer's technical level. Use simple language for beginners, technical terms for developers - Always confirm critical details before taking action - If you are not sure about something, say so. Never make up answers ``` These rules prevent common issues like overly long responses, assumption-making, and hallucination. ### 4. Conversation Flow Define the pattern your assistant should follow in interactions. ``` ## Conversation Flow 1. Greet the customer warmly 2. Acknowledge their question or issue 3. Provide a clear answer or outline next steps 4. Confirm the customer is satisfied 5. Close with an offer to help further ``` This gives your assistant a natural rhythm instead of jumping straight to answers without context. ### 5. Scenario Handling Address specific situations your assistant will encounter. This is where you prevent the most common failure modes. ``` ## Handling Common Scenarios ### Frustrated Customers - Acknowledge their frustration first: "I understand this is frustrating" - Take ownership: "Let me help fix this" - Focus on the solution, not the problem - Never be defensive or dismissive ### Pricing Questions - Always reference the knowledge base for current pricing - Never guess or estimate prices - For custom pricing, offer to connect with the sales team ### Out-of-Scope Questions - Politely explain what you can help with - Suggest where they might find the answer - Offer to connect them with a human team member ``` Think about the 5-10 most common customer interactions and write specific handling instructions for each. These targeted rules have the biggest impact on assistant quality. ### 6. Knowledge Reference Rules Tell your assistant how to use its [Knowledge Base](/guides/knowledge). This bridges the gap between [Instructions](/assistants/introduction#instructions) (behavior) and Knowledge (facts). For advanced setups with multiple knowledge sources, see [Context Engineering](/guides/practical/context-engineering). ``` ## Using Your Knowledge Base - For pricing questions, always check the knowledge base first - For policy questions, quote directly from the relevant policy - If the knowledge base does not have the answer, say: "I don't have that information right now. Let me connect you with our team." - Never invent information that is not in the knowledge base ``` This section is critical for preventing hallucination. Explicit instructions to check Knowledge before answering ensure your assistant stays grounded in real information. ### 7. Action-Specific Instructions When your assistant has [Actions](/assistants/actions) configured, add instructions for when and how to use them. See the [Actions documentation](/assistants/actions) for details on configuring actions and [testing them](/assistants/actions#testing-actions) in the Playground. ``` ## Booking Appointments - Always check availability before suggesting times - Offer 2-3 available time slots for the customer to choose from - Confirm the date, time, and service before creating the booking - After booking, send a calendar invite and confirmation email ## Payment Processing - Always confirm the amount and what the customer is paying for - After sending a payment link, wait for the customer to confirm they have paid before proceeding - Always verify payment status before marking a booking as complete ``` If an action name already describes its purpose clearly (like "Search Bookings Spreadsheet"), you can leave the action's "When To Use" field empty. Redundant descriptions can actually confuse the assistant's action selection. ### 8. Limitations and Boundaries Explicitly state what your assistant should never do. ``` ## What You Cannot Do - Never process refunds directly. Transfer to a human agent - Never share internal company information or employee details - Never provide medical, legal, or financial advice - Never modify account settings. Only explain how the customer can do it themselves - Never share one customer's information with another customer ``` Clear boundaries prevent your assistant from overstepping and protect your business. ### 9. Confirmation Protocols Define when the assistant must verify information before acting. ``` ## Always Confirm Before - Finalizing any booking (confirm date, time, attendees, service) - Processing any payment (confirm amount and what it covers) - Making changes to existing bookings or accounts - Sending emails on behalf of the customer ``` This prevents costly mistakes and builds customer trust. ### 10. Multilingual Behavior If your customers speak multiple languages, add explicit language handling rules. Your assistant will detect and respond in the customer's language automatically, but explicit instructions improve consistency. ``` ## Language Handling - Detect the customer's language from their first message and respond in the same language - If the customer switches languages mid-conversation, switch with them in your next reply - If the language is unclear, ask: "Would you prefer to continue in English or Spanish?" - Supported languages: English, Spanish, Portuguese ``` Modern AI models handle multilingual conversations well, but explicit instructions improve consistency. Always test with native speakers in each supported language. ### 11. Brand Closures Define how your assistant ends conversations. The last message shapes how customers remember the interaction. ``` ## Closing Conversations - Always end with a positive, helpful note - Use: "Is there anything else I can help you with?" - Final closing: "Thanks for reaching out! Have a great day." - For Spanish: "¡Gracias por contactarnos! Que tengas un excelente día." ``` ## Complete Template Here is a full instruction template you can copy and adapt for your business: ``` You are [Assistant Name], the [role] for [Business Name]. Your purpose is to [primary mission]. ## Your Personality - [Trait 1: e.g., Friendly and conversational] - [Trait 2: e.g., Patient with beginners] - [Trait 3: e.g., Concise and clear] ## Response Rules - Keep responses to 1-3 sentences when possible - Never ask multiple questions at once - If you are unsure, say so. Never make up answers - Always confirm details before taking action ## Conversation Flow 1. Greet the customer warmly 2. Acknowledge their question 3. Provide a clear answer or next steps 4. Confirm satisfaction 5. Close with an offer to help further ## Knowledge Base Rules - For [topic] questions, always check the knowledge base - Never invent information not in the knowledge base - If the answer is not available, say: "I don't have that information right now. Would you like me to connect you with our team?" ## Handling Scenarios ### [Common Scenario 1] - [Specific handling instructions] ### [Common Scenario 2] - [Specific handling instructions] ### Frustrated Customers - Acknowledge their frustration first - Focus on the solution - Offer to connect with a human if needed ## Actions - [Action-specific instructions] ## What You Cannot Do - [Limitation 1] - [Limitation 2] - [Limitation 3] ## Closing - End with: "[Your preferred closing message]" ``` ## Real-World Example Here is a complete set of instructions for a fitness studio assistant. Notice how it references [Knowledge](/guides/knowledge) for facts, configures [Memory](/guides/memory) for personalization, and sets rules for [Actions](/assistants/actions): ``` You are the booking assistant for FitLife Studio. Your purpose is to help members book classes, answer questions about schedules and pricing, and provide a welcoming experience. ## Your Personality - Energetic and encouraging, like a friendly trainer - Patient with new members who are unfamiliar with our classes - Concise. Respect people's time - Use casual language but stay professional ## Response Rules - Keep answers short. Use bullet points for lists - Never guess class availability. Always check the bookings spreadsheet - Confirm all booking details before processing payment - If a class is full, suggest the next available session ## Knowledge Base Rules - For pricing, class descriptions, and policies, always reference the knowledge base - For questions about specific instructors, check the knowledge base for their bios and specialties - If a question is not covered, offer to connect with the front desk ## Booking Flow 1. Ask which class they are interested in 2. Check availability in the bookings spreadsheet 3. Confirm class, date, time, and package type 4. Send payment link 5. Wait for payment confirmation 6. Verify payment, then record the booking 7. Send calendar invite and confirmation email ## What You Cannot Do - Cannot process refunds. Direct to front desk - Cannot override class capacity limits - Cannot book private sessions. Transfer to a human ## Memories Remember each member's name, favorite classes, preferred times, package type, and any injuries or limitations they mention. Use this to personalize recommendations. ## Closing - "You're all set! See you in class." - If they are new: "Welcome to FitLife! You're going to love it." ``` ## Tips for Better Instructions Write instructions as direct commands. "Always confirm the date before booking" is clearer than "It would be good if the assistant confirmed dates prior to the booking being made." After writing instructions, open the [Playground](/assistants/introduction#the-playground) and test with actual customer questions. Pay attention to where the assistant gets confused or gives unexpected answers, then refine. Check your [Inbox](/guides/inbox) regularly after going live. Look for conversations where the assistant struggled, then add handling instructions for those scenarios. The best instructions evolve over time. If your instructions are longer than roughly 500 words, review them for content that belongs in Knowledge instead. Long instructions increase cost on every message and dilute the behavioral rules. Different AI models interpret instructions with slight variations in tone and style. If you switch models, test your key scenarios again to make sure the experience stays consistent. If your assistant has multiple [Knowledge](/guides/knowledge) sources, add a priority order in your instructions so it knows which source to trust first. For example: "For pricing, check the pricing page first. For policies, check the terms document. If sources conflict, use the most recently updated one." See [Context Engineering](/guides/practical/context-engineering) for the full framework. ## Maintenance Instructions are not a "set and forget" configuration. Build a habit of reviewing them: **Weekly**: Check conversation logs for missed answers or awkward responses. Add scenario handling for recurring issues. **Monthly**: Review whether your instructions still match your current products, policies, and team processes. Remove outdated rules. **After any business change**: Update instructions whenever you change pricing, policies, team structure, or supported [channels](/assistants/channels). Keep instructions aligned with [Knowledge](/guides/knowledge) so they never contradict each other. ## Next Steps Understand where each type of information belongs Give your assistant the ability to perform real tasks # Plans & Pricing Source: https://docs.useinvent.com/guides/pricing-and-plans How much you'll pay, what's included in each plan, and how Invent's usage-based pricing works Most questions about Invent pricing come down to two things: 1. **If my assistant handles X messages a day, how much will that cost me?** 2. **What do I get for the \$29/month plan?** This page answers both, then explains how the pricing model works underneath. ## How Much Will It Cost Me? The fastest way to get a real number for your business is the **AI Assistant Cost Calculator** on our pricing page. Enter your daily message volume, pick a model, and your monthly spend updates live on the graph. Estimate your monthly cost in seconds. Adjust daily messages, pick a model, toggle media processing, and see your monthly total update instantly. AI Assistant Cost Calculator on the pricing page, showing about $33 per month for 100 daily messages on the Auto model with media processing enabled ### What to Expect at Each Volume On the **Auto** model (the recommended default that picks a model per message), here is what a typical business pays each month. Most setups land close to these numbers: | Daily messages | Monthly messages | Monthly cost (Auto) | | -------------- | ---------------- | ------------------- | | 50 | \~1,500 | **\~\$15–20** | | 100 | \~3,000 | **\~\$30–35** | | 250 | \~7,500 | **\~\$75–90** | | 500 | \~15,000 | **\~\$150–180** | | 1,000 | \~30,000 | **\~\$300–360** | For a live number tied to today's rates and your exact configuration, use the [calculator](https://www.useinvent.com/pricing#calculator). ### What Changes the Cost Two assistants at the same volume can land in different places. The main factors: * **Model choice.** Lighter models (Nano tiers, smaller Gemini/GPT variants) can be up to 10× cheaper per message than premium reasoning models. Auto balances quality and cost and is the right default for most businesses. * **Media & document processing.** Voice notes, images, and PDFs take more tokens to understand. If your customers send rich media, turn the toggle on in the calculator. * **Conversation length.** Longer back-and-forth uses more tokens per message. Prompt caching softens this significantly after the first message. * **Knowledge & actions.** Each Knowledge Base search and each action run adds a small amount on top of the message. For most businesses this is a few cents a day. ## What Do I Get for \$29/Month? The **Business plan** is \$29/month. Here is what that actually includes: * **\$29 of usage included each month.** Spent the same way as Pay As You Go usage, at the same per-message rates. Roughly \$29 worth of messages, knowledge searches, and broadcasts before any extra billing kicks in. * **Premium features unlocked.** Custom domain, white-label branding ("Remove Powered by"), audit logs, sub-organizations, Slack support, larger knowledge storage, and more. * **Usage above \$29 is billed at the same rate as Pay As You Go.** You are never charged a premium for going over, you just pay for what you use. If your monthly usage is around \$29 or less and you want the Business-only features (custom domain, whitelabel, audit logs, sub-orgs), the Business plan pays for itself. If you expect to spend more, you still want Business for the feature set, but understand that the \$29 is your baseline, not a cap. Full feature matrix, limits, and a free trial on the pricing page ### The Three Plans at a Glance | Plan | Price | Best for | | ----------------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | | **Pay As You Go** | Free | Trying Invent, small volumes, personal projects. Includes 100 free messages/month and all core features | | **Business** | \$29/month | Businesses and agencies that want custom domains, whitelabel, audit logs, sub-orgs, and a baseline of included usage | | **Enterprise** | Custom | Large organizations needing a 99.9% uptime SLA, 24/7 priority support, a dedicated account manager, monthly invoicing, and volume-based discounts | Every plan uses the same per-message, per-search, per-broadcast rates. The only thing that changes is what's **included** and which features are **unlocked**. ## Knowledge & Broadcasts: Pocket-Change Costs Both are billed from the same balance as messages. They rarely move the needle compared to the message cost. ### Knowledge * **Upload**: about **\$0.0005 per chunk** (a chunk is \~350–400 words, about half a page). A 10-page document runs around **\$0.007** to index. A full 100-page help center is around **\$0.07**. One-time charge. * **Search**: about **\$0.0005 per search**. Identical searches are cached free for 2 hours across your whole organization, so repeat questions don't re-charge. A business handling **1,000 customer questions a month** typically spends around **\$0.50 on knowledge searches** on top of message costs. ### Broadcasts Send campaigns via Email, SMS, or WhatsApp. You bring your own provider (Twilio, Meta, SendGrid, etc.) and Invent charges a small per-message fee on top. | Channel | Invent fee | | -------- | ------------------- | | Email | \~\$0.001 / message | | SMS | \~\$0.001 / message | | WhatsApp | \~\$0.004 / message | Your provider bills their own delivery cost separately (Meta template fees, Twilio SMS, etc.). ## How Message Pricing Works This section is the "why" behind the numbers above. Skip it if the calculator and the cost ranges already answered your question. ### Per-Message Pricing, Not Subscriptions Invent is usage-based. You pay for what you use, measured per message. Every model in the assistant settings shows its estimated cost per message right next to its name (for example, `Auto ≈ $0.004`). That figure already assumes an average conversation with prompt caching enabled. Consecutive messages in the same conversation are usually **cheaper** than the per-message figure thanks to prompt caching. The first message tends to cost a bit more since there is no cache yet. ### What Affects a Single Message's Cost * **The model.** Premium models cost more per message than lighter ones. The calculator shows each model's per-message rate. * **Response length.** Longer, more detailed replies use more output tokens. * **Instruction length.** Every message carries your full instructions as context, so bloated instructions compound. Keep them focused. See [Instructions vs Knowledge](/guides/practical/instructions-vs-knowledge) for what belongs where. * **Actions triggered.** Messages that include a Knowledge Base Search or a tool call use extra tokens. Invent has optimized this significantly (see below). ### Prompt Caching Enabled on every supported model. When your assistant handles multiple messages in the same conversation, cached context is reused instead of reprocessed. This means: * **First message**: slightly more expensive, the full context is processed fresh. * **Consecutive messages**: cheaper than the per-message figure, cached context is read at a reduced rate. Caches live for up to one hour with the AI provider. A conversation that goes idle longer may rebuild its cache on the next message. In the Playground, each message shows a token breakdown with a "Cache read" line so you can see exactly how much caching is saving you. Token breakdown in the Playground ### Cost Optimizations Invent continuously tunes how messages are handled: * **Actions up to \~50% cheaper.** Messages involving actions (Knowledge Base Search, integrations) use far fewer tokens than a naive implementation would. * **Assistants use up to \~50% fewer tokens overall**, thanks to internal context-management improvements. * **Knowledge Base Searches use up to \~20% fewer tokens**, so retrieving information is more efficient. ### Playground Discount Messages sent in the Playground get a discount so you can iterate on instructions, knowledge, and actions without worrying about costs. The token breakdown in the Playground makes the discount explicit. Use the Playground to refine instructions and test different models before going live. The discount makes experimentation affordable. ## Credits, Under the Hood You pay Invent in dollars, not credits. Internally the system converts your spend to a "credit" unit so that every usage type (messages, knowledge searches, broadcasts) draws from the same balance. You never need to think about credits unless you want to. The dashboard and invoices show dollar amounts. What you should know: * **Pay As You Go**: 100 free messages per month, reset monthly based on your organization's creation date. Unused free messages do not roll over. * **Business**: \$29 in included usage per month, same rate card as Pay As You Go. Anything above is billed at the same rates. * **Free usage is one organization per account.** If you run multiple organizations, only one receives the free monthly allocation. ## Billing Management All billing lives at [**Settings → Billing**](https://www.useinvent.com/o/settings/billing). ### Monthly Spending Limit Cap how much your organization can spend per billing cycle. When the limit is reached, billable operations pause until the limit is raised or the cycle resets. 1. Go to **Settings** → **Billing** 2. Click **Set Spending Limit** (or **Edit**) 3. Enter a cap between \$0 and \$100,000 4. Click **Save Changes** The page then shows a progress bar of your current spend against the limit. You can edit or remove the limit any time. Monthly Spending Limit Spending limits are especially useful for sub-organizations, so you can cap costs per team or per client independently. ### Auto-Recharge Keep your assistant running by automatically topping up when your balance dips below a threshold. 1. Go to **Settings** → **Billing** 2. Click **Edit** next to auto-recharge 3. Set your minimum balance threshold (default: \$5) and recharge amount (default: \$10). Both accept values from \$5 to \$500 4. Save ### Usage Tracking Watch your spend in real time at [**Settings → Usage**](https://www.useinvent.com/o/settings/usage): * **Total Spend** in the selected period * **Total Credits** consumed * **Daily usage graph** * **Date range filter**: presets from the last 24 hours out to the last three years, plus year to date and a custom range Usage Tracking For the breakdown by event type and the resource ceilings your plan applies, see [Usage & Limits](/workspace-management/usage-and-limits). ### Billing History & Payment Methods View past invoices, download receipts, and update your card under [**Settings → Billing**](https://www.useinvent.com/o/settings/billing). Payments are processed via Stripe and all major credit cards are accepted. ## Upgrading and Downgrading Both available at [**Settings → Plans**](https://www.useinvent.com/o/settings/plans): * **Upgrade to Business**: click **Manage Plan** under Business and confirm * **Downgrade to Pay As You Go**: click **Downgrade** under Pay As You Go and confirm Changes take effect immediately. When downgrading you lose access to Business-only features but keep all your data. ## FAQ On the Auto model, around **\$30–35 a month** for \~3,000 messages. If your customers send a lot of voice notes, images, or PDFs, expect the upper end. The [cost calculator](https://www.useinvent.com/pricing#calculator) gives a live number for your exact setup. No. \$29/month includes **\$29 of usage** and unlocks premium features (custom domain, whitelabel, audit logs, sub-organizations, Slack support, larger knowledge storage). Usage above \$29 is billed at the same per-message rates as Pay As You Go. You are never charged a premium for going over. Start with **Auto**. It picks the best model per message automatically, balancing quality and cost. If you later need to tune costs down or quality up, the assistant settings show every available model with its per-message cost next to it, so you can compare at a glance. The per-message figure assumes prompt caching is active. Your first message has no cache to read from, so it processes the full context at standard input rates. After that, consecutive messages benefit from caching and typically cost less than the figure. Monthly, based on your organization's creation date. If your org was created on March 10, your free messages reset on the 10th of each month. Unused free messages do not roll over. No. Free messages are granted to **one organization per account**. If you manage multiple organizations, only one receives the free monthly allocation. Very little. About **\$0.0005 to index each chunk** (\~350–400 words) once at upload, and about **\$0.0005 per search** at query time. Repeated identical searches are cached free for 2 hours across your organization. For most businesses, knowledge costs are a few cents to a few dollars a month. Each chunk (\~350–400 words) costs about **\$0.0005** to index, charged once at upload. A short FAQ page runs about **\$0.001**, a 10-page document around **\$0.007**, a full 100-page help center around **\$0.07**. The exact chunk count shows on your Knowledge page under **Total Chunks**. Invent charges a small per-message fee per channel (about **\$0.001** for email and SMS, **\$0.004** for WhatsApp). Your own provider (Twilio, Meta, SendGrid) bills their delivery cost separately. Yes. Set a **Monthly Spending Limit** at [Settings → Billing](https://www.useinvent.com/o/settings/billing) between \$0 and \$100,000. When the limit is reached, billable operations pause until you raise the limit or the next billing cycle begins. Yes, via the HTTP Request action. Your assistant can call any external API or database to fetch real-time data during a conversation. Yes, with a simple JavaScript snippet. See the [Web Widget](/assistants/widget) docs for the embed code and platform-specific install guides. ## Fair Usage Invent reserves the right to limit accounts showing abusive patterns or excessive usage that impacts service quality for everyone else. # Tracking Source: https://docs.useinvent.com/guides/tracking Track where conversations originate from across ads, products, and web widget UTM parameters Referral Tracking lets you see exactly where each conversation originates from. Whether a customer clicks a WhatsApp ad, browses an Instagram product, or lands on your web widget from a Google campaign, Invent captures the source and displays it directly in the conversation. This gives your assistants the perfect context to know what the customer is interested in and how to respond. ## Supported Sources Tracking works across native ad platforms and web widget UTM URLs: ### Native Ads | Source | Description | | ---------------- | ------------------------------------------------------- | | **Messenger Ad** | Conversations initiated from Facebook Messenger ads | | **WhatsApp Ad** | Conversations initiated from WhatsApp click-to-chat ads | | **Instagram Ad** | Conversations initiated from Instagram ads | | **TikTok Ad** | Conversations initiated from TikTok ads | ### Organic Content | Source | Description | | --------------------------------- | --------------------------------------------------------------------------- | | **Instagram Post / Reel / Story** | Conversations started from an Instagram post, reel, story, or story mention | | **Facebook Post / Reel** | Conversations started from a Facebook post or reel | | **TikTok Post / Short Link** | Conversations started from a shared TikTok post or short link | ### Native Products | Source | Description | | ---------------------------------------- | -------------------------------------------------------------------- | | **Messenger Product** | Conversations initiated from products shared in Messenger | | **Facebook / Instagram Product Catalog** | Conversations initiated from a shared multi-product catalog template | | **WhatsApp Product (Catalogs)** | Conversations initiated from WhatsApp product catalogs | | **WhatsApp Order (Catalogs)** | Conversations initiated from WhatsApp catalog orders | | **Instagram Product** | Conversations initiated from Instagram product listings | These tables are representative, not exhaustive. Invent recognizes many referral types across each channel and displays whichever one applies. ### Web Widget | Source | Description | | ---------------------------- | ----------------------------------------------------------------------- | | **Web Widget (UTM Support)** | Conversations from your website widget with full UTM parameter tracking | ## How It Works When a customer starts a conversation from any supported source, Invent automatically captures the referral information and displays it in two places: 1. **Conversation timeline**: A referral banner appears at the top of the conversation showing the source type and key details 2. **Contact panel**: The **Referral** section in the [Contact Panel](/guides/inbox#referral) shows the full referral breakdown No additional setup is required for native ad and product tracking. For web widget tracking, UTM parameters are captured automatically from the page URL where the widget is embedded. ## Viewing Referral Data ### Ad and Product Referrals For conversations originating from ads or product listings, the referral section displays: * **Source type**: The platform and type (e.g., Instagram Product, WhatsApp Ad) * **Product image**: A thumbnail of the product (for product-based referrals) * **Product name**: The name of the product the customer interacted with * **Price**: The listed price of the product * **Description**: The product description In the conversation timeline, you will see a banner like "Instagram Product" along with the product name, price, and description. ### Web Widget UTM Referrals For conversations originating from your web widget with UTM parameters, the referral section captures: * **Source**: The traffic source (e.g., `google`, `facebook`, `newsletter`) * **Medium**: The marketing medium (e.g., `cpc`, `email`, `social`) * **Campaign**: The campaign name (e.g., `spring_sale_2026`) * **Term**: The paid search keyword (e.g., `ai chatbot`) * **Content**: The ad variation or content identifier (e.g., `headline_v2`) * **Ad**: The ad identifier (`utm_ad`) * **Google Click ID**: The GCLID for Google Ads attribution * **Facebook Click ID**: The FBCLID for Meta Ads attribution * **Page**: The full URL the customer visited In the conversation timeline, a "Website" banner appears showing the source, medium, and campaign. ## Using Tracking with Assistants Referral data is available to your assistants, enabling them to tailor responses based on context. For example: * A customer coming from a **product listing** can be greeted with information about that specific product * A customer from a **paid ad campaign** can receive messaging aligned with the campaign's offer * A customer browsing your **catalog** can get personalized product recommendations based on the item they viewed This context helps your assistants deliver relevant, personalized conversations from the very first message. You can add rules in your [Instructions](/guides/practical/writing-instructions) to guide how your assistant uses referral data (e.g., "If the customer came from a product listing, greet them with information about that product"). ## Next Steps View referral data in the contact panel alongside conversations Connect the channels that support referral tracking # Welcome to Invent Source: https://docs.useinvent.com/introduction Build powerful AI assistants and deploy them anywhere Invent is a platform for creating, training, and deploying AI assistants designed for customer support. These assistants help your users get instant answers, automate workflows, and improve their overall experience with your product. *Everything is simple and magical. Building assistants in Invent is effortless, and using them feels personalized for customers. Keep reading to discover why.* **Building on Invent with an AI agent?** Copy this into your agent (Cursor, Claude Code, Codex, OpenCode, or harness of choice) and it can integrate on its own: ```text theme={"system"} Connect my Invent account and help me manage my AI support assistants. Read https://useinvent.com/llms.txt and follow it. ``` For the full walkthrough, see [Invent for Agents](/api-reference/getting-started/for-agents). ## Features * **24/7 Chatbot**: Instantly answer FAQs, handle order inquiries, refunds, or technical support without human intervention. Your AI assistant works around the clock to resolve customer needs * **Multi-channel Support**: Seamless conversations via WhatsApp, Instagram, web chat, and more. No API key mess, just native integrations that work out of the box * **Centralized Inbox**: View all customer conversations in one unified space, with full insights including channel details, customer information, conversation history, and automatic summaries * **Automated Actions**: Automate any customer tasks with customizable actions that let your assistant not just respond, but completely resolve inquiries * **AI Controlled Fields**: Configure actions without the complexity. AI automatically handles most parameters using conversation context. No programming required, just simple, natural configuration * **Auto Follow-ups**: Your assistant automatically re-engages idle conversations instead of letting them go cold. It schedules intelligent follow-ups, checks back at the right time, and only closes when it makes sense * **Auto CSAT**: Automatically score customer satisfaction (1-5) after every conversation closes, giving you real-time insight into service quality without manual surveys * **Human Handoff**: Enable seamless transitions to your team with human-in-the-loop capabilities, easy handoffs, and automatic assignment to team members when AI needs assistance * **Multimedia Support**: Handle images, audio, voice messages, and location data across all channels. Understand and process rich media sent by customers * **Long-term Memories**: Remember every client detail across all conversations, even in fresh chats through WhatsApp or any other channel. Turn routine interactions into personalized experiences that drive loyalty, upsells, and 5-star customer satisfaction * **Quick Training**: Build and train AI assistants in under 5 minutes using your own knowledge base, documentation, and business data * **Audience Management**: Every customer who messages you through any channel becomes a contact. Organize them into segments and manage your entire audience from one place * **Broadcasts**: Re-engage your customers by sending targeted messages via WhatsApp, Email, and more. Product launches, promotions, updates, delivered to the people who already know your brand ## Get Started Build your first assistant in minutes. This guide covers everything from creating an assistant to deploying it on your website or WhatsApp: Create an assistant, add your business information, test it, and deploy it. The best place to start ## Explore the Platform Once you have your first assistant running, dive deeper into each feature: Create AI-powered agents that handle customer conversations automatically Give your assistant the power to perform real tasks like booking appointments Connect your assistant to WhatsApp, Instagram, and more Manage all customer conversations in one unified space Train your assistant with your business data and documentation Let your assistant remember every customer across all conversations Manage contacts, create segments, and build targeted audiences Send WhatsApp messages, emails, and more to your audience at scale Automatically re-engage idle conversations and follow up at the right time Understand how message costs, credits, and prompt caching work ## Go Deeper Ready for advanced builds and best practices? Check out the [Guides](/guides/practical/instructions-vs-knowledge): Full tutorial: yoga studio assistant with Google Sheets, Stripe, Calendar, Gmail, and WhatsApp Learn what goes where and why it matters for performance and cost # Build a Booking Assistant Source: https://docs.useinvent.com/learn-by-example Build a complete yoga studio booking assistant with Google Sheets, Google Calendar, Stripe, and WhatsApp. New to Invent? Start with [Your First Assistant](/your-first-assistant) to learn the fundamentals before diving into this advanced tutorial. In this tutorial, you will build a complete AI assistant for a wellness studio that handles bookings, payments, and customer support. By the end, you will understand how **Knowledge**, **Actions**, **Channels**, and **Memory** work together in a real-world scenario. ## What We're Building **Sunrise Yoga Studio** needs an AI assistant that works 24/7 on WhatsApp. When customers message at 11 PM asking to book a class, the assistant will: 1. Answer questions about classes, pricing, and schedules 2. Check real-time availability in Google Sheets 3. Book them into a class 4. Send a Google Calendar invite 5. Process payment via Stripe 6. Verify payment completion 7. Email a confirmation receipt **All in one conversation. No human involved.** Curious what the final result looks like? Jump to [See It in Action](#see-it-in-action) to watch a complete customer conversation, then come back to learn how to build it step-by-step. ### The Business Setup Sunrise Yoga offers three packages: | Package | Price | Classes | Notes | | ------------ | ----------- | --------- | ------------------------- | | Drop-In | \$25 | 1 class | Perfect for trying us out | | Starter Pack | \$90 | 5 classes | Valid for 30 days | | Unlimited | \$150/month | Unlimited | Best value for regulars | Each class has a maximum of 15 participants. The studio offers: * **Morning Flow**: Mon/Wed/Fri at 7 AM * **Power Yoga**: Tue/Thu at 6 PM * **Gentle Stretch**: Sat at 9 AM ## Step 1: Create the Assistant From your dashboard, click **Assistants** in the sidebar, then click the **Create Assistant** button. Create Assistant A dialog appears asking for: * **Name**: Enter "Sunrise Yoga Concierge" * **Template**: Keep default (custom) Create Assistant Dialog Click **Create Assistant**. You're taken to your new assistant's configuration page. ## Step 2: Configure Assistant Settings You'll see several tabs: **Settings**, **Knowledge**, **Actions**, **Channels**, and **Widget**. Let's start with Settings. ### Basic Configuration Basic Configuration **Avatar**: Click the avatar circle to upload your studio's logo. This appears in conversations. **Name**: Already set to "Sunrise Yoga Concierge". This displays in conversations. **Model**: Leave as "Auto" to let Invent choose the best model for each response. The cost shown (≈ \$0.0032 per message) is an estimate. ### Instructions Instructions define your assistant's behavior, personality, and rules. This is where you tell the assistant *how* to act, not what information it knows (that goes in Knowledge). Below the label, you'll see a **Use a template (Optional)** dropdown for inspiration. Let's write custom instructions: ``` You are the friendly concierge for Sunrise Yoga Studio. ## Your Personality - Warm, welcoming, and knowledgeable about yoga - Patient with beginners (many customers are new to yoga) - Enthusiastic but not pushy about bookings ## Your Responsibilities 1. Answer questions about classes, schedules, and pricing 2. Help customers book classes and manage reservations 3. Process payments and send confirmation receipts 4. Handle cancellations and rescheduling requests ## What to Remember Remember important details about each customer for personalized service: - Their name and contact information (email, phone) - Which classes they've attended and when - Their favorite instructors or class preferences - Package type and remaining credits - Any special needs or preferences they mention Use this information to make returning customers feel recognized and provide tailored recommendations. ## Important Rules - Always check availability before confirming a booking - Confirm all details (class, date, time, package) before processing payment - After sending a payment link, wait for the customer to confirm they've paid, then verify the payment before completing the booking - If a class is full, suggest alternatives - If you're unsure about something, offer to connect with a human team member ``` Notice we're defining *behavior*, not listing class schedules or prices. That information belongs in Knowledge, where it's easier to update and the assistant can search through it more effectively. ### Capabilities Capabilities **Memories**: Turn this on. This lets your assistant remember customer names, preferences, and past bookings across all conversations. **Spam Protection**: Turn this on. Automatically blocks contacts showing suspicious behavior. In the separate **AI Routing** section, turn on **Transfer to Member**. When the assistant encounters complex issues, it can hand off to your team. ## Step 3: Add Knowledge Knowledge teaches your assistant factual information about your business. Click the **Knowledge** tab. Knowledge ### Adding Studio Information Click **Upload Knowledge**. A dialog appears with three tabs: * **File**: Upload PDF, Word, or text files (up to 50 MB each) * **Text**: Add content directly * **Website**: Paste a URL to crawl your website ### Adding a Text Knowledge Item Click the **Text** tab and enter your studio information: Knowledge Text ``` # Sunrise Yoga Studio ## Class Packages & Pricing - Drop-In: $25 for 1 class (great for first-timers) - Starter Pack: $90 for 5 classes (valid 30 days) - Unlimited: $150/month for unlimited classes ## Class Schedule - Morning Flow: Mon/Wed/Fri at 7 AM (60 min) - Power Yoga: Tue/Thu at 6 PM (75 min) - Gentle Stretch: Sat at 9 AM (60 min) Each class has maximum 15 participants. ## Class Details ### Morning Flow (Mon/Wed/Fri, 7:00 AM) Energizing vinyasa-style class to start your day. Suitable for all levels. Instructor: Sarah Chen (10 years experience, RYT-500 certified) What to bring: Yoga mat (rentals available for $3) Arrive: 10 minutes early to settle in ### Power Yoga (Tue/Thu, 6:00 PM) Challenging, athletic practice that builds strength and stamina. Instructor: Marcus Williams (Former athlete, specializes in strength-building) Best for: Intermediate to advanced practitioners Note: Beginners welcome but expect a workout! ### Gentle Stretch (Sat, 9:00 AM) Slow, relaxing practice focused on flexibility and stress relief. Instructor: Linda Park (Specializes in therapeutic yoga) Perfect for: Beginners, seniors, those recovering from injury ## Studio Policies - Cancellations must be made 4 hours before class - Late arrivals (more than 10 minutes) cannot enter - Class credits expire 30 days from purchase (Starter Pack) - No refunds, but credits can be transferred to another person - First class is always 50% off for new students! ## Location & Parking 123 Wellness Way, Downtown Free 2-hour parking in the building garage Studio is on the 3rd floor ``` Click **Add Content**. The status shows "Processing" then "Processed" when ready. ## Step 4: Connect Actions Actions let your assistant actually *do* things, not just talk about them. Click the **Actions** tab. Actions Click **Add Action** to see all available integrations. Actions List You'll see two sections: * **Common**: Web Search, HTTP Request, Web Scraping, Call Workflow, Call MCP Tool * **Integrations**: Google Calendar, Google Sheets, Stripe, Gmail, Slack, and many more For our yoga studio, we need: 1. **Google Sheets**: Track bookings (the assistant uses Knowledge for class details) 2. **Google Calendar**: Send calendar invites 3. **Stripe**: Create checkout links and verify payments 4. **Gmail**: Send confirmation emails **Bookings Spreadsheet Setup** Create a spreadsheet with columns: **Customer Name**, **Email**, **Phone**, **Class Name**, **Date**, **Time**, **Package Type**, **Payment Status**. | Customer Name | Email | Phone | Class Name | Date | Time | Package Type | Payment Status | | ------------- | --------------------------------------- | -------- | -------------- | ------------ | ------- | ------------ | -------------- | | Emma Johnson | [emma@email.com](mailto:emma@email.com) | 555-0101 | Gentle Stretch | Jan 18, 2026 | 9:00 AM | Drop-In | Paid | | Mike Chen | [mike@email.com](mailto:mike@email.com) | 555-0102 | Gentle Stretch | Jan 18, 2026 | 9:00 AM | Starter Pack | Paid | The assistant gets class details (times, instructors, max capacity of 15) from Knowledge, then counts bookings in this spreadsheet to calculate availability. Bookings Spreadsheet ### Action 1: Check Bookings Click **Google Sheets** in the integrations list. Google Sheets Actions You'll see these actions: * **Append Row to Spreadsheet**: Add data to a sheet * **Search in Spreadsheet**: Find data in a sheet * Etc. Click **Search in Spreadsheet**. Search in Spreadsheet **Action Name**: "Check Bookings" **When To Use**: ``` Search bookings to check how many people are booked for a class. Compare against max capacity from Knowledge to determine availability. ``` **Connection**: Click the dropdown. If you haven't connected Google Sheets yet, click "Connect Google Sheets" and authorize access. Once connected, select your Google account. Google Sheets Connection **Spreadsheet**: Select your bookings spreadsheet. **Sheet**: Select the sheet tab (e.g., "Sheet1"). **Search Range**: Enter the cell range, like `A:Z` for entire columns. **Search Term**: Leave as `AI Controlled Field`. The assistant automatically determines the class name and date from the conversation. **How Availability Works** When a customer asks to book Saturday's Gentle Stretch: 1. Assistant knows from **Knowledge**: Max capacity = 15, Time = 9 AM, Instructor = Linda 2. Assistant **searches Bookings spreadsheet** for "Gentle Stretch" + "Jan 18" 3. Finds 2 existing bookings → calculates 13 spots available 4. Responds: "Gentle Stretch on Saturday at 9 AM has spots available!" If 15 bookings exist, the assistant suggests alternatives per your instructions. **Understanding Auto vs Manual Fields** Each field has a menu button (⋮) on the right. Click it to switch between: * **Auto**: The AI determines the value from conversation context. * **Manual**: You enter a fixed value that never changes. For Search Term, Auto makes sense since it depends on what class the customer asks about. Click **Add Action**. ### Action 2: Record Booking Click **Add Action** → **Google Sheets** → **Append Row to Spreadsheet**. Append Row to Spreadsheet **Action Name**: "Record Booking" **When To Use**: ``` After payment is verified, add the booking to the spreadsheet. ``` **Connection**: Select your connected Google account. **Spreadsheet**: Select your bookings spreadsheet (e.g., "Bookings"). **Sheet** (Optional): Select the sheet tab (e.g., "Sheet1"). If your spreadsheet only has one sheet, you can leave this empty. Your spreadsheet's first row must contain column headers. The action reads these headers to generate the Row Values fields below. **Row Values**: Once you select a spreadsheet and sheet, the form automatically displays fields for each column header. For our bookings spreadsheet, you'll see: * **Customer Name**: AI Controlled Field * **Email**: AI Controlled Field * **Phone**: AI Controlled Field * **Class Name**: AI Controlled Field * **Date**: AI Controlled Field * **Time**: AI Controlled Field * **Package Type**: AI Controlled Field * **Payment Status**: AI Controlled Field Row Values Leave all fields as "AI Controlled Field". The assistant automatically extracts each value from the conversation context, customer details they provided, the class they booked, and the payment status after verification. Click **Add Action**. ### Action 3: Create Calendar Event Click **Add Action** → **Google Calendar**. Google Calendar Google Calendar offers several actions (Search Events, Get Event, Update Event, Delete Event, etc.). For this tutorial, click **Create Event**. Google Calendar Create Event **Action Name**: "Send Class Calendar Invite" **When To Use**: ``` Use after payment is verified. Send a calendar invite to the customer with class details, date, time, and studio location. ``` **Connection**: Connect your Google Calendar account. The fields stay as Auto: * **Event Title**: AI generates something like "Morning Flow at Sunrise Yoga" * **Description**: AI includes class details, instructor, what to bring * **Start Date** / **End Date**: AI extracts from the booked class * **Attendees Email**: Customer's email from conversation * **Location**: Can be set to Manual with your studio address For **Visibility**, **Reminder Method**, and **Reminder Time**, you might want Manual values: * Visibility: "Default" * Reminder Method: "Email and In-app Notification" * Reminder Time: "30 minutes" Click **Add Action**. ### Action 4: Create Checkout Link Click **Add Action** → **Stripe**. Stripe Stripe offers many actions including customer management, subscriptions, invoices, and payment links. For this tutorial, we need: * **Create Checkout Link**: A single-use link for one or more products * **Get Checkout Session**: Check whether that link was paid Stripe also offers **Create Payment Link**, a permanent link you can reuse. It cannot tell you whether a customer paid, so for bookings use a checkout link. Click **Create Checkout Link**. It is added to your assistant right away. Close the dialog, then click the action in the list to configure it. Stripe Create Checkout Link **Action Name**: "Create Checkout Link" **When To Use**: ``` Use when a customer confirms they want to book and is ready to pay. Create one checkout link with everything they are buying. ``` **Connection**: Click "Connect Stripe" and authorize your Stripe account. **Mode**: Leave as Auto. The assistant picks One-time Payment for single classes and Subscription for the Unlimited package. When the customer pays and comes back from Stripe, the conversation gets a payment event and the assistant confirms the payment on its own. **Price** and **Items**: Leave both as Auto. For one product the assistant fills Price. For several products it fills Items with one row per product and its quantity, and Stripe puts them into one link with one total: * Drop-In → \$25 * Starter Pack → \$90 * Unlimited → \$150/month (subscription) You must create corresponding products and prices in your Stripe account that match your packages. The assistant picks from those prices when it builds the link. For recurring packages like Unlimited (\$150/month), set up a subscription price in Stripe. Click **Update Action**. ### Action 5: Verify Payment This is critical. When a customer says "I've paid", the assistant needs to verify the payment actually completed. Click **Add Action** → **Stripe** → **Get Checkout Session**, then click the new action in the list to configure it. Stripe Get Checkout Session **Action Name**: "Verify Payment Status" **When To Use**: ``` Use when a customer says they have completed payment. Check that the checkout session is paid before confirming the booking. ``` **Connection**: Select your Stripe connection. **Checkout Session ID**: Leave as Auto. The assistant uses the ID from the earlier "Create Checkout Link" action. Click **Update Action**. ### Action 6: Send Confirmation Email Click **Add Action** → **Gmail** → **Send Email**. Gmail Send Email **Action Name**: "Send Booking Confirmation" **When To Use**: ``` Use after payment is verified. Send confirmation email with booking details, what to bring, studio address, and cancellation policy. ``` **Connection**: Connect your Gmail account. **From Email**: Shows after connecting. This is the email that sends confirmations. **To Email**: Auto. Customer's email from conversation. **Subject**: Auto. Something like "Your Sunrise Yoga Class is Confirmed" **Body**: Auto. Full confirmation with all details. **CC** / **BCC** / **Attachments**: Optional fields, leave empty or set as needed. Click **Add Action**. Your Actions tab now shows 6 configured actions, grouped by app: Configured Actions Each action has a toggle to enable/disable it without losing configuration. ## Step 5: Connect WhatsApp Your assistant needs a channel to communicate. Click the **Channels** tab. Channels Available channels include WhatsApp Business, Instagram, Messenger, TikTok, Telegram, Slack, Gmail, SMS and the Web Widget. Click **Connect** next to WhatsApp. WhatsApp Connect Follow the setup: 1. Connect your Meta Business account 2. Select or create a WhatsApp Business phone number 3. Verify your business 4. Configure message templates (optional) ## Step 6: Test in the Playground Before going live, test everything. On the right side of the assistant page, you'll see the **Test Assistant** panel. Click **Create Conversation** and try a booking flow. Verify that actions trigger at the right moments and responses use your Knowledge correctly. ## Step 7: Go Live Once testing is complete: 1. **Enable the WhatsApp channel** using the toggle 2. **Share your WhatsApp number** with customers 3. **Monitor the Inbox** for conversations Click **Inbox** in the sidebar to see all conversations. Use filters like **Unresolved** to focus on what needs attention. To track conversations the AI transferred, watch the **Waiting for Human** stat on your Dashboard. ## See It in Action Here's what a real customer journey looks like. This shows Knowledge, Actions, and Memory working together across multiple conversations. ### First Booking (Saturday evening) > **Sarah**: Hi! I saw your studio on Instagram. Do you have beginner-friendly classes? > **Assistant**: Hi! Yes, we have several options perfect for beginners. Our Gentle Stretch class on Saturdays at 9 AM is ideal. It's a slow, relaxing practice focused on flexibility, taught by Linda who specializes in working with newcomers. Morning Flow (Mon/Wed/Fri at 7 AM) is also suitable for all levels. Would you like to know more about either? > **Sarah**: The Saturday one sounds good. How much is it? > **Assistant**: Great choice! We have three package options: > > * **Drop-In**: \$25 for a single class (perfect for trying us out) > * **Starter Pack**: \$90 for 5 classes (valid 30 days) > * **Unlimited**: \$150/month for unlimited classes > > For your first class, we also offer 50% off! Would you like to book this Saturday's Gentle Stretch? > **Sarah**: Yes! I'll do the drop-in. My name is Sarah, email is [sarah.miller@email.com](mailto:sarah.miller@email.com) > **Assistant**: Perfect, Sarah! Let me check availability for this Saturday's Gentle Stretch at 9 AM. > Good news, there are spots available! With the first-timer discount, your Drop-In is \$12.50. Here's your payment link: > [https://pay.stripe.com/abc123](https://pay.stripe.com/abc123) > Once you've completed payment, I'll send your confirmation and calendar invite. > **Sarah**: Done! > **Assistant**: Payment confirmed! You're all set for Gentle Stretch this Saturday at 9 AM. > I've sent a calendar invite and confirmation email to [sarah.miller@email.com](mailto:sarah.miller@email.com). A few things to know: > > * Arrive 10 minutes early to settle in > * Yoga mats available to rent for \$3, or bring your own > * We're at 123 Wellness Way, Downtown (free parking in the building garage) > See you Saturday, Sarah! **What happened**: The assistant answered using Knowledge, checked real-time availability, processed payment, verified it, recorded the booking, sent a calendar invite, and emailed confirmation. All automatically. ### Returning Customer (Two weeks later) > **Sarah**: Hey! > **Assistant**: Hi Sarah! How was Gentle Stretch with Linda? Ready to book another class? > **Sarah**: It was great! Linda was so patient. I want to come regularly now. What's the best deal? > **Assistant**: So glad you enjoyed it! For regular attendance, the **Unlimited plan at *150 usd/month*** is the best value. You can attend as many classes as you want. If you're not sure about committing monthly, the **Starter Pack** gives you 5 classes for \$90, valid for 30 days. > Based on Gentle Stretch being Saturdays only, the Starter Pack would cover 4-5 weeks of classes. But if you want to add Morning Flow or try Power Yoga too, Unlimited pays for itself at just 6 classes per month. > **Sarah**: Let's do the starter pack for now > **Assistant**: Great choice! Here's your payment link for the Starter Pack, 5 classes for \$90: > [https://pay.stripe.com/xyz789](https://pay.stripe.com/xyz789) > **Sarah**: Paid! And can you book me for this Saturday? > **Assistant**: Perfect! Your Starter Pack is active. 5 classes valid through February 10th. > This Saturday's Gentle Stretch at 9 AM has space. I've booked you in! > Calendar invite sent. 4 classes remaining on your Starter Pack. See you Saturday, Sarah! **What happened**: The assistant remembered Sarah's name, her previous class, and her instructor preference. It gave personalized package advice based on her attendance pattern. *** ## Key Concepts | Concept | What It Does | | ----------------- | ------------------------------------------------------- | | **Instructions** | Define assistant behavior and personality | | **Knowledge** | Store factual information (schedules, prices, policies) | | **Actions** | Let the assistant perform real tasks | | **Auto Fields** | AI determines values from conversation | | **Manual Fields** | Fixed values that never change | | **When To Use** | Guides when actions should trigger | | **Memory** | Remembers customers across conversations | | **Channels** | Where customers reach your assistant | ## FAQ The assistant counts 15 bookings in the spreadsheet (matching max capacity from Knowledge) and tells the customer the class is full. Your instructions tell it to suggest alternatives. Update prices in your Knowledge text. The assistant reads Knowledge fresh for each conversation. Your Knowledge states the refund policy. For exceptions, the "Transfer to Member" feature routes complex requests to your team. Update your Knowledge with the new class details (name, time, instructor, max capacity). The assistant picks up changes immediately. If the checkout hasn't been paid, the assistant will let the customer know and can send a new checkout link or help troubleshoot. ## Bonus: Adding Rescheduling Want to let customers reschedule their bookings? Add two more actions: **Google Calendar → Update Event** * Action Name: "Reschedule Class" * When To Use: "Use when a customer wants to reschedule an existing booking to a new date/time." **Google Sheets → Update Row in Spreadsheet** * Action Name: "Update Booking Record" * When To Use: "Use after rescheduling to update the booking date in the spreadsheet." With these actions, your assistant handles rescheduling automatically: > **Sarah**: Hey, something came up Saturday. Can I reschedule? > **Assistant**: Hi Sarah! Of course. Your Gentle Stretch is this Saturday at 9 AM. When would you like to move it to? > **Sarah**: Next Saturday > **Assistant**: Done! I've moved your booking to next Saturday, January 18th at 9 AM. Your calendar invite is updated. See you then! # API Keys Source: https://docs.useinvent.com/workspace-management/api-keys Generate API keys to programmatically access the Invent API API keys allow you to programmatically interact with Invent. Use them to build custom integrations, automate workflows, or access your data through the API. API Keys ## Creating an API Key 1. Go to **Settings** → **API Keys** ([useinvent.com/o/settings/api-keys](https://www.useinvent.com/o/settings/api-keys)) 2. Click **New API Key** in the top right 3. Enter a name for your key (e.g., "Production Server" or "Development") 4. Click **Generate** 5. Copy the API key immediately - you won't be able to see it again Generate API Key **Important**: Store your API key securely. A key acts as the member who created it and carries that member's permissions, so a key created by an admin can reach everything in the organization. To limit a key, create it as a member who holds a [custom role](/workspace-management/custom-roles) with only the permissions you need. ## Using API Keys Include your API key in the `Authorization` header of your requests: ```bash theme={"system"} Authorization: Bearer YOUR_API_KEY ``` ### Organization in the URL Most API resources live under an org-scoped path: ``` https://api.useinvent.com/orgs/{org_id}/... ``` Path parameter **`org_id`** is the workspace (organization) ID, or the shorthand below. ### The `c` (current org) shorthand Use **`c`** as `org_id` to mean **the organization this API key is for** (the workspace selected when the key was created). Authenticating with the key sets that org as the “current” org on the request, so you do not have to paste a workspace UUID in every path. **Example: list assistants in the key’s workspace:** ```bash theme={"system"} curl -X GET "https://api.useinvent.com/orgs/c/assistants" \ -H "Authorization: Bearer YOUR_API_KEY" ``` For any other workspace (including a sub-organization), put that workspace’s **real organization id** in the path. **Do not use `c`**: it always means only the org the key was created in. ### Parent organization keys and sub-organizations An API key created in a **parent** (agency) organization can be used to call **every org-scoped endpoint** for **any of its sub-organizations**: the same routes you use for a normal workspace, with the **sub-organization’s id** as `{org_id}` (for example `https://api.useinvent.com/orgs/SUB_ORG_ID/assistants`). * With a **parent** key, **`c` is always the parent org**. To hit a sub-org you must **specify that sub-org’s id** in the path; there is no shorthand for “current sub-org.” * A key created in a **sub-organization** can only access that sub-org (and not sibling sub-orgs or other workspaces), unless you use a separate key from the parent. ## Managing API Keys Each API key shows: * **Name**: The identifier you provided * **Token**: A preview of the key (full key only shown once at creation) Per-key actions live in the **API key options** menu (the **⋮** next to each key): * **Rotate**: Generate a new token for the key and invalidate the current one. The old token stops working immediately, so any integration using it fails until you update it with the new token. As with creation, the new token is shown only once, copy it right away. * **Delete**: Remove the key to revoke access. Confirm the deletion, after which any services using that key immediately lose access. ## Security Best Practices 1. **Use descriptive names**: Name keys by their purpose ("Production", "Staging", "Local Dev") 2. **Rotate keys regularly**: Delete old keys and create new ones periodically 3. **Never commit keys to code**: Use environment variables instead 4. **Delete unused keys**: Remove keys that are no longer needed 5. **Use separate keys for different environments**: Don't share keys between production and development ## API keys vs webhook signing secrets An API key authenticates **you to Invent**. A webhook signing secret (`whsec_…`) authenticates **Invent to your server** — it signs the payloads we POST to your endpoint, and it grants no access to your workspace. Each webhook endpoint has its own secret, rotated independently of your API keys. See [Webhooks](/api-reference/getting-started/webhooks). ## API Documentation For complete API documentation, including endpoints, parameters, and examples, visit the [API Reference](/api-reference/getting-started/introduction). The Invent API uses REST principles with: * **Base URL**: `https://api.useinvent.com` * **Authentication**: Bearer token (your API key) * **Rate Limit**: 500 requests per minute per IP address * **Response Format**: JSON # Audit Logs Source: https://docs.useinvent.com/workspace-management/audit-logs Track and monitor all activity across your workspace Audit Logs require a **Business** or **Enterprise** plan. [View plans](/guides/pricing-and-plans) Audit Logs give you a detailed record of every action taken in your workspace. Use them to track changes, monitor team activity, and maintain accountability across your organization. Audit Logs Overview ## Understanding the Activity Feed Audit logs are shown as an activity feed grouped by day. Each entry reads as a short sentence describing what happened, with a timestamp and a **Source** badge: * **Sentence**: who did what to which resource, for example the actor, the action, and the affected resource (such as an assistant name). * **Source badge**: where the action originated. Possible sources are **App**, **Admin**, **API**, **System**, and **AI**. * **Timestamp**: when the action occurred. Click any entry to open a **detail panel** with the full context of the event, including the actor and their role, what changed, the source, and the location (country) and device or browser captured at the time. ## Filtering Logs You can narrow down your audit logs using the filters at the top of the page: * **Date Range**: Set a **From** and **To** date to view activity within a specific time period * **Action**: Use the action dropdown to filter by a specific event type, or select **All Actions** to view everything ## Event Types Audit logs capture a wide range of events across your workspace, grouped by category: * **Organization**: Updated, Deleted, Disabled, Enabled, Restored, Transferred, Transferred To, Detached, Detached From, Sub-Organization Created, Sub-Organization Updated, Sub-Organization Member Joined, Sub-Organization Member Role Changed * **Members**: Invited, Joined, Removed, Left, Role Changed * **Roles**: Created, Updated, Deleted, Assigned, Unassigned * **Assistants**: Created, Updated, Deleted, Restored, Duplicated, Duplicated From * **Actions**: Created, Deleted, Enabled, Disabled * **Integrations**: Created, Deleted, Updated, Enabled, Disabled * **Connections**: Created, Updated, Deleted * **Broadcasts**: Created, Deleted, Activated, Paused * **Workflows**: Created, Deleted, Restored * **Domains**: Domain Created, Domain Deleted, Email Domain Created, Email Domain Deleted, Email Identity Created, Email Identity Deleted * **SSO**: Profile Created, Profile Updated, Profile Deleted, Domain Created, Domain Updated, Domain Deleted * **Conversations**: Chat Deleted * **API Keys**: Created, Deleted, Rotated ## Who Can View Audit Logs Audit Logs are available to **Admin** users, and to any custom role granted **Audit logs = View**. You can access them by navigating to **Settings** → **Audit Logs** ([useinvent.com/o/settings/audit-logs](https://www.useinvent.com/o/settings/audit-logs)). ## Best Practices 1. **Review regularly**: Check audit logs periodically to stay aware of changes in your workspace 2. **Investigate unexpected changes**: If something looks off, use the filters to trace who made the change and when 3. **Use date filters for incidents**: When troubleshooting, narrow down to the specific time window to quickly find relevant activity # Connections Source: https://docs.useinvent.com/workspace-management/connections Connect apps and services once, then reuse them everywhere in Actions, Channels, and across your workspace **Connections** are your workspace’s saved links to the outside world. When you sign in to Google, connect WhatsApp, paste a Telegram bot token, or point an MCP server at Invent, you create a **connection**. That same connection can power **many** [Actions](/assistants/actions) on **many** assistants and **many** [Channels](/assistants/channels), without asking you to authenticate again for every single use. This page is the **single hub** to see everything you have connected, add new integrations, test them, rename them, reconnect when tokens expire, and disconnect safely. Connections page showing header with count, Documentation and Add integration buttons, and a list of connected integrations with Active status, Edit, and disconnect ## Why the Connections page exists Invent splits the problem in two: 1. **Connection**: *Who are we, as a workspace, on this provider?* (the authenticated account, bot token, MCP URL, etc.) 2. **Where it is used**: *Which assistant uses this for which Action or Channel?* If those were the same step, you would re-run OAuth or re-paste tokens every time you added a new action or channel. Instead you **connect once**, pick that connection from a dropdown wherever it is needed, and manage it centrally here. Each action that needs an external service chooses a **Connection**. Several actions can share one Google or Stripe account. Messaging channels reuse the same pattern: a **Connection** to Meta, Telegram, etc., then a per-assistant binding (phone number, Page, bot). Both [Actions](/assistants/actions) and [Channels](/assistants/channels) read from the **same** connection list, which is why adding Gmail for one assistant makes it available when you configure another. **Adding a connection from elsewhere still shows up here.** If you start from an assistant’s **Actions** or **Channels** tab and click **Connect** (or the equivalent), Invent creates the connection and lists it on **Settings → Connections** automatically. You do not maintain two different “integration lists.” This page is always the source of truth. ## Open Connections Go to **Settings** → **Connections** ([useinvent.com/o/settings/connections](https://www.useinvent.com/o/settings/connections)). At the top you will see: * **Connections** with a **count badge** (how many integrations are connected) * **Documentation**: quick access to this guide * **Add integration**: opens the integration picker (same idea as starting a new connection from scratch) The main area is **Connected integrations**: either your list of connections or an empty state if none exist yet. Empty Connected integrations area with chain icon, message No integrations connected yet, and Add integration button ## Two ways to connect Not every provider works the same way. Invent supports: ### Sign-in connections (OAuth / “Continue to …”) For services like Google Calendar, Gmail, Google Sheets, WhatsApp (via Meta), and many others, Invent sends you through the provider’s **normal sign-in screen** in a popup or new tab. You approve access on **their** domain; Invent never sees your password. Flow in practice: 1. You pick the integration (from **Add integration** or from an Action/Channel dialog). 2. Invent shows a short screen that you will be redirected to authorize (example below). 3. You complete the provider flow and return to Invent. 4. You **name the connection** if prompted. That label is only for you inside Invent (same idea as in [Channels → The Universal Connection Flow](/assistants/channels#the-universal-connection-flow)). 5. The connection appears on this page and in dropdowns across the workspace. Modal: Google Calendar. You will be redirected to Google Calendar to authorize the connection, with Continue to Google Calendar button This matches the **universal connection flow** described for channels: authenticate with the provider, then name the connection, then use it wherever Invent asks for a Connection. See [Channels → The universal connection flow](/assistants/channels#the-universal-connection-flow) for the channel-specific steps (picking a phone number, Page, etc.). ### Form connections (credentials in Invent) Some integrations need values you enter **inside Invent**: a **Telegram Bot token**, an **MCP** server URL and optional headers, API keys, and so on. There may be no browser redirect, or there is a redirect *and* you still confirm details in a form, depending on the integration. You typically fill in: * **Connection name (optional)**: how this row appears on the Connections page and in dropdowns (e.g. `Help Bot`, `Prod MCP`). * **Provider-specific fields**: URL, token, JSON headers, etc. * **Test connection**: verify credentials before you save (recommended). * **Create connection** or **Update connection**: save changes. MCP connection form: Connection Name, URL, Access Token or API Key, Headers JSON, Test Connection and Create Connection **Example: Telegram** uses a bot token from BotFather (see the help link next to the field in the product). Create and test, or open an existing connection to **Update** with a new token. Telegram new connection: optional name, Telegram Bot token field, Test Connection and Create Connection Telegram connection edit: Help Bot name, optional token field, Test Connection and Update Connection ## Add a new integration from this page From **Settings → Connections**, click **Add integration** (or use the same entry point from an assistant when adding an Action or Channel). A searchable list opens: each row is a service with a short description of what connecting enables (email, spreadsheets, MCP tools, etc.). Add integration modal: search field and list of services with icons and descriptions, Google Calendar row highlighted Use **Search** if the list is long. Select the provider you need. * **OAuth-style**: click **Continue to …**, finish the provider flow, return to Invent, and confirm the **connection name** if asked. * **Form-style**: enter tokens, URL, headers, then optional **Test connection**, then **Create connection**. Open an assistant’s **Actions** tab to attach actions that use this connection, or **Channels** to bind a phone number, Page, or bot. Existing connections appear in the **Connection** dropdown so you rarely need to add the same account twice. [Actions → Adding Actions](/assistants/actions#adding-actions) · [Channels → How channels work](/assistants/channels#how-channels-work) ## What you see in the list Each connected integration is a row with: * **Icon and name**: service type + the **connection name** you gave (or a sensible default). * **Active**: the connection is healthy and ready for Actions and Channels. * **Account hint**: for many OAuth services, you will see the linked email or account so you know *which* login this is (for example `Acme Sheets (docs@acme.com)`). * **Edit**: open **Manage connection** to rename, test, or reconnect. * **Disconnect**: remove the connection (see below). Connected integrations list: Telegram Help Bot, WhatsApp Acme Primary, Gmail, Google Sheets with Active badges and Edit ## Manage an existing connection Click **Edit** on any row to open **Manage connection**. What appears depends on the provider, but you will consistently get: * **Connection name**: optional label used everywhere this connection appears. * **Reconnect**: run the provider sign-in again when tokens expire or access was revoked (OAuth-style services). * **Test connection**: verify the integration still works without leaving the dialog. * **Update connection**: save name or credential changes (form-style services). Manage connection for WhatsApp Acme Primary: Connection Name field, Reconnect, Test Connection, Update Connection If something breaks after a password change or admin removes API access, **Reconnect** is usually the fastest fix. For bot tokens or MCP URLs, paste the new values in the form, **Test connection**, then **Update connection**. ## Disconnect a connection Click the **unlink / disconnect** control on the row (broken-chain style icon in the product). Invent asks you to confirm: Disconnect account modal: All related services will stop working immediately, Close and Yes disconnect **Disconnect is immediate.** Any [Action](/assistants/actions) or [Channel](/assistants/channels) that relied on this connection stops working until you connect again or point the assistant at a different connection. Disconnecting here removes the workspace-level link, not just one assistant. Removing a **channel binding** from a single assistant (Disconnect on the assistant’s Channels tab) does **not** delete the underlying connection. Other assistants can keep using it. See [Channels → Managing connected channels](/assistants/channels#managing-connected-channels). ## Connection status * **Active**: Ready to use; Actions and Channels can run with this connection. * **Inactive / error**: Often means expired tokens or revoked access. Open **Edit** → **Reconnect**, or fix form credentials and **Update connection**. If only one assistant misbehaves, check that its Action or Channel still selects the right connection in the dropdown before you assume the account is dead. ## Testing Always use **Test connection** when the form offers it, especially after rotating tokens or changing an MCP URL. For OAuth services, sending a quick test message from a [Channel](/assistants/channels) or running through the [Playground](/assistants/introduction#the-playground) after reconnecting catches issues before customers do. [Actions → Testing actions](/assistants/actions#testing-actions) ## Security and good habits * **Minimum access**: Invent requests only what each integration needs; approve scopes on the provider the same way you would for any business tool. * **Naming**: Prefer names that describe use (`Billing Gmail`, `EU WhatsApp`) rather than personal names, so the list stays clear as you grow. * **Rotation**: When someone leaves or a token leaks, **Update** or **Reconnect** and remove old connections you no longer need. * **Secrets**: Form fields for API keys and bot tokens are sensitive. Treat them like passwords and avoid sharing screenshots publicly. ## Next steps Wire integrations into conversations with AI-controlled fields and testing in the Playground Universal connect flow, multiple numbers or Pages, and Inbound routing Every conversation, every channel, in one place Settings, billing, members, and API keys # Custom Roles Source: https://docs.useinvent.com/workspace-management/custom-roles Create roles with granular, resource-by-resource permissions for your team System roles (Admin, Developer, Manager, Agent) cover most teams. **Custom roles** go further: you define a role with your own name, color, and a precise permission set, resource by resource. Creating custom roles is available on the **Business** and **Enterprise** plans. Custom and system roles ## System vs custom roles * **System roles** are fixed and read-only: Admin, Developer, Manager, and Agent. You can open one to see exactly what it grants, but you can't change it. * **Custom roles** are roles you create with a tailored permission set, color, and description. A member has **either** one system role **or** one or more custom roles. When a member holds custom roles, those define their access, and their base role drops to Agent (see [Assigning roles](#assigning-roles)). ## Permission levels Open a role to see the permission editor. Every resource (Members, Inbox, Contacts, Tables, and so on) is set to one of three levels: | Level | Meaning | | :--------- | :------------------------------------- | | **None** | No access to the resource. | | **View** | Read-only: can see but not change. | | **Manage** | Full access: create, edit, and delete. | The role permission editor with None, View, and Manage levels Resources are organized into groups, **Organization**, **Inbox & contacts**, **AI & automation**, and **Reserved for admins**, with a legend at the bottom of the editor that explains each level. Not every resource offers all three levels. Some are view-only (Analytics, Audit logs) and some are manage-only (Connections, Workflows, Segments). The editor only shows the levels that apply to each resource. ## Sub-resources and cascading Some resources nest a finer-grained permission underneath them: * **System roles** under Members: whether this role can assign the system Manager and Agent roles to others (never Admin or Developer). * **AI Routing** under Assistants: conversation routing and assistant handoff. * **Table records** under Tables: the rows inside tables, separate from the table structure. * **Table views** under Tables: the saved views over those tables. Setting a parent to **Manage** cascades its children to Manage so you don't have to set each one, and setting any child to View or Manage lifts the parent to at least **View**, so a child is never granted under a hidden parent. You can still override a child afterward, for example Tables = Manage but Table records = None. The cascade is a **convenience in the editor only**. Access is always enforced on the exact permission a role holds, on both the backend and the interface. A role with Tables = Manage but Table records = None can edit the table structure but **cannot** edit the rows. ## Reserved permissions A few permissions are **reserved for Admins** and can never be granted through a custom role: **SSO**, **Sub-organizations**, and **Administration** (the reserved admin actions to delete the organization and manage roles). They appear in the editor with a "Reserved" badge and can't be selected. ## Creating a custom role Go to **Settings → Members & Roles → Roles** and select **Create role**. Give the role a name, pick a color (used for its badge across the workspace), and add an optional description. For each resource, choose None, View, or Manage. To start from an existing role, use **Copy from a role** and adjust from there. Select **Save changes**. The role now appears under **Custom roles** and can be assigned to members. The full permission catalog in the role editor You can only grant permissions you hold yourself (the **subset rule**), so you can never create a role more powerful than your own access. ## Assigning roles Assign custom roles from the members list with **Edit roles** next to a member, or stage them on an invite. Assigning a custom role drops the member to the **Agent** base role. They keep only the custom role's access, and removing all of their custom roles later leaves them as an Agent, not their previous system role. This is a safety measure so elevated access never lingers. ## Inviting with custom roles When you invite a member, pick a system role **or** one or more custom roles. If you choose custom roles, the invitee joins at the Agent base plus those roles when they accept. Choosing system or custom roles when inviting a member If a staged custom role is deleted before the invite is accepted, the invite is removed. ## The permissions matrix **Settings → Members & Roles → Permissions Matrix** shows every role (system and custom) as a column and every resource as a row, so you can compare access at a glance. The roles comparison matrix ## Plan and visibility notes * **Creating** custom roles requires the Business or Enterprise plan. Existing custom roles stay viewable and removable on lower plans, but you can't create new ones. * Once your workspace runs on a custom domain, that white-label domain and its email branding apply to every member regardless of role. What the role changes is visibility: members with the Manager, Agent, or a custom role only see Manager and Agent members, so your Admin and Developer members stay hidden from client-side teams. The role picker marks each role **Internal** or **Client** to show which side it puts a member on. # Emails Source: https://docs.useinvent.com/workspace-management/emails Verify the addresses and domains your workspace sends email from Before your workspace can send email, the address it sends from has to be verified. **Settings → Emails** is where you add those addresses, watch their verification status, and set up DKIM signing for your domain. Verified sender addresses Each row shows the sender name your recipients will see, the address itself, and its status. The **Default** badge marks the address used when nothing more specific is chosen, and the **DKIM** badge means the address's domain is signed. ## Adding a sender address Enter the **name** recipients see in their inbox (usually your company or team name) and the **address** you want to send from. We send a verification email to that address. Open it and follow the link. The address stays **Pending** until you do. Back in the list, the address flips to **Verified** and is ready to use. Add a sender address If the email never arrives, open the address and use **Resend Verification**, then **Check Status** once you have clicked the link. Statuses are **Pending**, **Verified**, and **Failed**. Use an address you can actually receive mail on. Replies to your broadcasts land there, and so does the verification email. ## Verifying your domain (DKIM) Verifying the single address is enough to start sending. Verifying its **domain** is what makes those emails land in the inbox instead of the spam folder: it lets us sign every message with DKIM on your behalf, so receiving mail servers can prove the mail really came from your domain. Open an address and scroll to **Domain Verification**. Domain verification records Three records are listed with their type, name and value. Copy each one with the button next to it. Create the records exactly as shown. If we recognize your DNS provider, a button appears that opens it directly, and for some providers it can add the records for you in one click. Use the refresh action next to each record. DNS changes can take a few minutes to propagate, so check again shortly if they still show **Pending**. Once all records resolve, the section reports that DKIM signing is active and the address shows the **DKIM** badge in the list. Every address on that domain benefits, so you only do this once per domain. ## Per-address settings Open an address to find its **Configuration** section: | Setting | What it does | | :----------------- | :-------------------------------------------------------------------------------------------------------------------------- | | **Click Tracking** | Rewrites the links in your email body so clicks can be attributed. On by default | | **Open Tracking** | Adds a tracking pixel to measure opens. Off by default, because some receiving servers treat the pixel as a negative signal | The options menu on each row also lets you rename the sender, **set the address as default**, or delete it. Deleting an address stops everything that sends from it. Broadcasts, assistants, and workflows configured with that address will fail until you point them at another one. ## Where these addresses are used * **Broadcasts** sent over the email channel go out from the address configured on the broadcast. * **Assistants and workflows** that send email use the address chosen in their configuration. * Anything you do not configure explicitly falls back to your **default** address. ## Next Steps Send marketing and transactional email to your audience Keep bounced and opted-out addresses out of every send # Members Source: https://docs.useinvent.com/workspace-management/members Invite teammates, assign roles, and control what each person can do Members are the people with access to your workspace. You can invite teammates, assign system or custom roles, set who is available to handle conversations, and remove access at any time. The members list with roles and availability ## Roles Every member has either a **system role** or one or more **custom roles**. System roles cover the common cases: | Role | Best for | What they can do | | :------------ | :------------------------------ | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | | **Admin** | Owners and operators | Full access to everything, including billing, SSO, audit logs, and sub-organizations. | | **Developer** | Technical staff | Builds the workspace: assistants, knowledge, skills, workflows, connections, API keys, webhooks, tables, pages, domains, emails, variables and templates, plus the organization profile and everything a Manager can do with content. Cannot invite or manage members. Billing, SSO and sub-organizations are Admin-only. | | **Manager** | Team leads and support managers | Runs the day to day: invite and manage Managers and Agents, and manage the inbox, contacts, segments, broadcasts, AI routing, table records and table views. Views analytics. No technical configuration. | | **Agent** | Frontline support | View and respond to conversations, manage contacts and table records. Read-only elsewhere. | For anything more specific, create a [custom role](/workspace-management/custom-roles) with an exact, resource-by-resource permission set. To compare what every role can do side by side, open **Settings → Members & Roles → Permissions Matrix**. The **Members** area has three tabs: **Members** (the people list), **Roles**, and **Permissions Matrix**. The Roles and Permissions Matrix tabs are visible to Admins only. The roles comparison matrix ## Inviting members Go to **Settings → Members & Roles** and select **Invite Member**. Add the teammate's email address. Pick one **system** role, or select one or more **custom** roles. You can only grant roles whose permissions you hold yourself. Select **Send Invite**. The invitee receives a branded invitation email and joins with the role you chose when they accept. Choosing a role while inviting a member Once your workspace runs on a custom domain, each role is marked **Internal** or **Client** in the picker. Client roles — Manager, Agent, and custom roles — only see Manager and Agent members, so your Admin and Developer members stay hidden from them. Your white-label domain and email branding apply to every member either way. ### Pending invites Pending invitations appear in the members list with a "Pending" status. From the member options menu you can **Resend** the invitation email or **Revoke** the invitation. ## Changing a member's role Use the role dropdown to switch a member between system roles, or **Edit roles** to assign custom roles. You can only change a member to a role with equal or lower access than your own. Assigning a custom role drops the member to the **Agent** base role; they keep only the custom role's access. Removing all of their custom roles later leaves them as an Agent, not their previous system role. ## Availability The **Active** toggle in the members list controls whether a member is available to receive conversation assignments and assistant handoffs. Turn it off to take someone out of rotation without changing their role or removing them. Managers, and roles with member-assignment access, can change a member's availability. ## Removing members To remove a member, open the three-dot **Member options** menu and select **Remove Member**. Removed members immediately lose access to your workspace. ## Best practices 1. **Grant the minimum needed.** Start narrow; you can always widen access later. 2. **Use custom roles for precise access.** When a system role is too broad or too narrow, a [custom role](/workspace-management/custom-roles) gives you exactly the surface you want. 3. **Reserve Admin for owners.** Only give Admin to people who need full control, including billing and security. 4. **Review access regularly.** Remove members who no longer need access, and turn off availability for anyone temporarily out of rotation. # Notifications Source: https://docs.useinvent.com/workspace-management/notifications Configure email and sound notifications for conversations assigned to you Notifications keep you informed when new messages arrive in conversations that need your attention. Configure how and when you get notified so you never miss an important customer message. Access notification settings at [useinvent.com/o/settings/notifications](https://www.useinvent.com/o/settings/notifications). Notifications Settings ## Email Notifications ### Conversation is assigned to me Toggle this on to receive email notifications when new messages arrive on conversations assigned to you. This is useful for members who handle human handoffs and need to respond quickly. When enabled, you'll get an email each time a customer sends a new message in a conversation where you are the assigned member. ## Billing Notifications ### Billing alerts Toggle this on to receive email alerts when the balance runs low or out, the spending cap is reached, or a payment fails. This section is only visible to members with billing permission. ## Sound Notifications Choose the sound that plays when you receive a new message in conversations assigned to you or unassigned. This helps you stay aware of incoming messages while working in the dashboard. Available sound options: | Sound | Description | | --------------- | ------------------------------------ | | **Default** | The standard notification sound | | **Alternative** | A different tone for variety | | **Soft** | A quieter, less intrusive sound | | **None** | Disable sound notifications entirely | Click the **play** button next to the dropdown to preview any sound before selecting it. If you handle a high volume of conversations, consider using **Soft** or **None** to avoid notification fatigue, and rely on email notifications for important conversations instead. # Overview Source: https://docs.useinvent.com/workspace-management/overview Manage your organization's settings, members, and billing Your workspace is where you manage everything about your organization: team members, billing, API access, and branding. All workspace settings are accessible from the **Settings** link in your dashboard sidebar. ## What You Can Manage ### Organization Settings Configure your organization's basic information at [useinvent.com/o/settings/general](https://www.useinvent.com/o/settings/general): * **Organization Name**: The name of your workspace * **Organization ID**: Your unique identifier for API access * **Delete Organization**: Permanently remove your workspace and all data ### Members Invite team members and assign roles: * **Admin**: Full access to all features * **Developer**: Manage assistants, workflows, tables, connections, and domains — not billing or members * **Manager**: Invite and manage Managers and Agents, view and respond to conversations * **Agent**: View and respond to conversations [Learn more about Members →](/workspace-management/members) ### Notifications Configure email and sound notifications for conversations assigned to you. Get notified when new messages arrive so you never miss an important customer interaction. [Learn more about Notifications →](/workspace-management/notifications) ### AI Routing Assign specific team members to handle conversations when human handoff is needed. This allows you to limit which agents have access to specific assistants. [Learn more about AI Routing →](/assistants/routing) ### Connections View all external platform connections made through Assistant Actions and Channels. This centralized view shows every integration your organization has connected, including Google Drive, Airtable, Notion, Linear, and more. [Learn more about Connections →](/workspace-management/connections) ### Emails Verify the addresses your organization sends email from, set a default sender, and add DKIM records so your domain signs every message. [Learn more about Emails →](/workspace-management/emails) ### API Keys Generate API keys to programmatically interact with Invent. Use these keys to build custom integrations or automate workflows. [Learn more about API Keys →](/workspace-management/api-keys) ### Webhooks Push workspace events to your own endpoints, send test events, and inspect or replay every delivery. [Learn more about Webhooks →](/workspace-management/webhooks) ### Single Sign-On (SSO) Let your team sign in through your identity provider: Okta, Microsoft Entra ID, Google Workspace, Auth0, and any other OIDC-capable IdP. Claim your email domains, configure SSO profiles, and decide which login methods your team is allowed to use. [Learn more about SSO →](/workspace-management/sso/overview) ### Usage & Limits Track your organization's credit consumption and spending over time, broken down by what produced it, and see the resource ceilings your plan applies. [Learn more about Usage & Limits →](/workspace-management/usage-and-limits) ### Billing Manage your payment method, subscription, and view billing history. Set up auto-recharge to automatically add credits when your balance drops below a threshold. You can also set a **Monthly Spending Limit** to cap how much your organization can spend per billing cycle. ### Plans View available pricing tiers and manage your subscription. Invent offers Pay As You Go and Business plans with different limits for assistants, channels, members, and more. [Learn more about Plans & Pricing →](/guides/pricing-and-plans) ### White Label Customize your organization's branding with custom domains and personalized appearance: * **Domains**: Add custom domains for whitelabel emails and portals * **Customization**: Upload your logo, set contact email, address, terms of service, and privacy policy [Learn more about White Label →](/workspace-management/white-label) ### Audit Logs Monitor all activity in your workspace with a detailed log of every action taken by team members. Track changes to assistants, settings, members, and more, with filters for date range and action type. [Learn more about Audit Logs →](/workspace-management/audit-logs) ### Sub-Organizations Create and manage independent sub-organizations under your parent organization. Each sub-organization has its own members, billing, assistants, and settings. Ideal for agencies managing clients or businesses with separate departments. [Learn more about Sub-Organizations →](/workspace-management/sub-organizations) ### Referrals Share your workspace's referral link and earn credits when the workspaces you refer start paying. [Learn more about Referrals →](/workspace-management/referrals) ## Accessing Settings Click **Settings** in the left sidebar of your dashboard, then choose the category you want to manage from the secondary sidebar. You can also access settings directly at [useinvent.com/o/settings](https://www.useinvent.com/o/settings). # Referrals Source: https://docs.useinvent.com/workspace-management/referrals Share your referral link and earn credits when the workspaces you refer start paying Every workspace has a referral link. Share it, and both sides get credits: the workspace that signs up through your link starts with credits on its balance, and you earn credits once it makes its first payment. Open **Settings → Referrals**. Referrals ## Your referral link The link is your workspace's referral code appended to the Invent site, for example `https://www.useinvent.com/?r=Kp7dQa`. It is generated the first time you open the page and never changes, so it is safe to put in a newsletter, a blog post, or a partner agreement. Use the copy button next to the field, then share it anywhere. Anyone who signs up after following it is attributed to your workspace. The code travels with the visitor, so the link works from any page they land on next. You do not need to send people to a special signup page. ## How the reward works The new workspace receives its welcome credits, and the referral appears in your list as **Pending**. Your reward is granted and added to your balance. The referral flips to **Granted**. The current amounts are always shown at the top of the page, above your link. The reward is tied to the **first payment**, not to signup, so a referral can sit at **Pending** for a while. That is normal and nothing is lost: it is granted whenever that workspace starts paying. ## Your referrals The table lists every workspace attributed to you: | Column | Meaning | | :--------- | :----------------------------------------------------------------------------------------------------- | | **ID** | A short identifier for the referred workspace. Names are never shown, so their workspace stays private | | **Reward** | **Pending** until their first payment, then **Granted** | | **Date** | When the referral was recorded | A workspace can be referred only once, and your own workspace cannot use its own code. ## Where the credits show up Granted rewards land on your workspace balance, next to any credits you bought. Track the balance and what it is spent on at [Settings → Usage](/workspace-management/usage-and-limits), and see the payment side at Settings → Billing. ## Next Steps Watch what your workspace spends its balance on How billing, plans and spending limits work # Access Policy Source: https://docs.useinvent.com/workspace-management/sso/access-policy Control which login methods are allowed for users on your verified domains SSO Access Policy requires a **Business** or **Enterprise** plan. [View plans](/guides/pricing-and-plans) The **Access Policy** is an organization-wide rule set that controls which login methods are available to users on your [verified domains](/workspace-management/sso/domains). It is the mechanism used to enforce a specific authentication path for your team, so that users cannot silently bypass it with an alternative method. The policy lives on every organization and is configured as soon as you claim your first domain. The toggles become **enforced** only once an SSO profile is enabled on the organization, which is a deliberate safety rail against lockout: Invent will not refuse Google, Microsoft, or email-code sign-in until there is at least one working alternative available. The Access Policy is a safety rail, not a prerequisite. If your team authenticates exclusively with Google Workspace, Microsoft, or email codes and you do not need to connect a dedicated identity provider, you can leave the Access Policy at its defaults and everything will work correctly. Claiming your domain alone is enough to unlock auto-join, profile sync, default roles, and email and profile change locks. The policy never affects users whose email does not match a verified domain on your organization. Visitors and members of other organizations are entirely untouched by your toggles. SSO access policy form ## Where It Lives The Access Policy sits at the top of the SSO settings page ([useinvent.com/o/settings/sso](https://www.useinvent.com/o/settings/sso)). It is a three-toggle form that saves automatically as each toggle is changed; there is no separate save button. All three toggles default to **on** when an organization is first created. ## Policy Toggles ### Allow Google Sign-In When **on**, users on your verified domain can sign in to Invent using Google. When **off**, Google sign-in is rejected for users on your verified domain with the message: *"Google sign-in is not enabled for your domain, please use SSO instead"*. ### Allow Microsoft Sign-In When **on**, users on your verified domain can sign in to Invent using Microsoft. When **off**, Microsoft sign-in is rejected for users on your verified domain with the message: *"Microsoft sign-in is not enabled for your domain, please use SSO instead"*. ### Allow Email Code Sign-In When **on**, users on your verified domain can sign in using a one-time email code sent to their inbox. When **off**, email-code sign-in is rejected for users on your verified domain with the message: *"Email code sign-in is not enabled for your domain, please use SSO instead"*. ## When Do the Toggles Take Effect? The toggles on this page become **enforced** against sign-in attempts only when **both** of the following are true: 1. The user's email domain matches a verified SSO domain on your organization. 2. Your organization has at least one **enabled** SSO profile that users on that domain could use to sign in. If either condition is missing, the sign-in attempt succeeds regardless of the toggle values. In practice this means the toggles are dormant until there is a working SSO path available for the affected users. This is a deliberate safeguard against lockout. For example, Google sign-in cannot be disabled for `acme.com` while no SSO option is actually configured, since doing so would leave users on that domain with no way to sign in at all. Configure an SSO profile first, confirm that the end-to-end flow works, then tighten the policy. ## Typical Setups

All three toggles on. SSO is presented as the preferred option on the sign-in page, but users can still sign in with Google, Microsoft, or an email code if they prefer.

Best for mixed workforces, gradual SSO rollouts, and organizations preserving legacy accounts during a transition.

All three toggles off. Your team must sign in through SSO. Every other method is blocked for users whose email matches a verified domain.

Best for strict security postures, SOC 2 or ISO 27001 compliance requirements, and regulated environments.

Allow Google and/or Microsoft on, email code off. Users must authenticate through a managed identity, either your SSO provider or Google/Microsoft, but one-time email codes are blocked.

Best for Google Workspace or Microsoft customers who want Google or Microsoft sign-in as a secondary managed option.

Allow Google and Microsoft off, email code on. One-time email codes remain available as a backup in case your identity provider has an outage.

Best for resilience, since email codes continue to work even when your identity provider is unavailable.

## Safety Rails ### "No login methods allowed" warning If you turn **all three** toggles off, Invent displays an inline warning in the settings UI that reads: *"Google, Microsoft, and email code sign-in are disabled. These settings only take effect when an SSO provider is configured. Otherwise all methods remain available."* Turning all three toggles off is a valid configuration, but it only produces a visible behavior change once an SSO profile is enabled. At that point it effectively makes SSO the only way for users on your verified domains to sign in. The warning serves as a reminder to verify that the SSO profile is fully operational before committing to this posture, so that no one is accidentally locked out. ### Verified domain notice The Access Policy card displays a persistent note that reads: *"These settings only apply to users whose email matches a claimed domain."* Users whose email does not match any of your verified domains are never affected by these toggles, regardless of their values. ## Changing the Policy Each toggle saves immediately when it is flipped. There is no separate save button. Changes take effect on the **next sign-in attempt**. Existing sessions are not revoked automatically and continue until they expire on their own or the user signs out. Dedicated session revocation controls are [coming soon](/workspace-management/sso/profiles#revoking-sessions). Until then, the only way to forcibly end an SSO session is to delete the SSO profile that created it, which revokes all of its sessions in the same operation. ## How It Relates to Other Settings The three SSO settings each play a distinct role: * [**SSO Domains**](/workspace-management/sso/domains) define **who** the Access Policy applies to. The policy only affects users whose email matches a verified domain on your organization. Domains alone unlock auto-join, default roles, and profile sync for all sign-in methods, even without an SSO profile. * [**SSO Profiles**](/workspace-management/sso/profiles) define **what** identity provider users are sent to when they choose SSO. Profiles are optional; they are only required if you want to authenticate through an external identity provider. * **Access Policy** defines **what alternatives** users on verified domains may use besides SSO. The toggles only take effect once an SSO profile is enabled, at which point they let you force your team through the identity provider and block the alternatives. Only a verified domain is strictly required to benefit from SSO in Invent. Profiles and the Access Policy toggles are additional layers on top. # Domains Source: https://docs.useinvent.com/workspace-management/sso/domains Claim and verify email domains to control how users join your organization SSO Domains require a **Business** or **Enterprise** plan. [View plans](/guides/pricing-and-plans) SSO Domains are the email domains your organization has claimed. Claiming a domain unlocks auto-join, scopes which login methods are permitted through the [Access Policy](/workspace-management/sso/access-policy), keeps user identity in sync with your identity provider, and allows you to attach SSO profiles. A domain can only be claimed by **one** organization in Invent. The first organization to complete email verification for a given domain becomes its sole owner. If you believe your domain has been claimed by another organization, please contact Invent support with proof of ownership. ## The Domains Table Each verified domain shows: | Column | Description | | ---------------- | ---------------------------------------------------------------------------------------------------- | | **Domain** | The verified email domain (e.g. `acme.com`) | | **Default role** | Default role assigned to users who auto-join through this domain. Click the pencil icon to change it | | **Auto-Join** | Toggle. When on, users signing up with an email on this domain are automatically added as members | | **⚙️ Settings** | Opens the settings dialog for profile sync, email change, and profile change | | **🗑️ Delete** | Starts the 6-digit email-verified deletion flow | ## Claiming a Domain 1. Go to **Settings** → **Sign-In & SSO** ([useinvent.com/o/settings/sso](https://www.useinvent.com/o/settings/sso)). 2. In the **Email Domains** section, click **Claim domain**. 3. Fill in the form: * **Verification email**: an email address on the domain you want to claim (for example, `admin@acme.com`). The 6-digit verification code is sent to this address and becomes the domain's **verification of record** for future sensitive operations, such as deletion. * **Default role**: the role assigned to users who auto-join through this domain. Choose from Admin, Developer, Manager, or Agent. Defaults to **Agent**. * **Auto-join new users**: automatically add users who sign up with an email on this domain as members of your organization. Defaults to **on**. * **Sync profile from identity provider**: refresh the user's name, avatar, and email from your identity provider on every sign-in. Defaults to **on**. * **Allow email change**: permit users on this domain to change their own email address from the user settings page. Defaults to **off**. * **Allow profile change**: permit users on this domain to change their own name and avatar from the user settings page. Defaults to **on**. 4. Click **Send code**. A 6-digit verification code is emailed to the verification address. 5. Enter the code to complete verification and claim the domain. Add domain dialog (email and role) Add domain dialog (toggles and submit) Enter verification code The verification code is valid for **10 minutes**. If it expires before you enter it, click **Resend** on the verification screen to request a new one. Disposable email addresses and free-mail domains (Gmail, Outlook, Yahoo, iCloud, and similar) cannot be claimed as SSO domains. ## Domain Settings Explained ### Default Role Every user who auto-joins through this domain is assigned this role on creation. The options match the standard Invent member roles: * **Admin**: full access to the organization, including SSO, billing, and member management. * **Developer**: technical features such as assistants, API keys, and integrations. * **Manager**: customer-facing operations, including the inbox, contacts, and segments. * **Agent**: view and respond to conversations. [See the full role matrix →](/workspace-management/members) You can change the default role at any time by clicking the pencil icon next to the role badge on the domain row. Existing members retain their current role. Only users who auto-join **after** the change receive the new default. Edit role button on domain row ### Auto-Join When **on**, any new user who signs up with an email matching this domain is automatically added to your organization with the **Default Role** set above. Auto-join applies to **every sign-in method**, not just SSO. A user who signs up with Google using their `@acme.com` email is auto-joined in exactly the same way as a user who signs up through your SSO provider. The trigger is the verified email domain, not the authentication method. Auto-join makes onboarding frictionless for large teams by removing the need for manual invitations. If you prefer explicit control over who joins your organization, turn it off and invite each member individually. ### Sync Profile When **on**, Invent refreshes the user's **name**, **avatar**, and **email** from the claims returned by your identity provider on every SSO sign-in. This ensures that Invent's view of each user stays consistent with your directory of record as names change, photos are updated, or email addresses are reassigned. When **off**, these identity fields are written once on first sign-in and are never subsequently overwritten from the identity provider. Existing users will keep whatever name, avatar, and email they already have in Invent regardless of what the identity provider returns. ### Allow Email Change Controls whether users on this domain may change their own email address from the user settings page. When **Sync Profile** is on, users connected to an identity provider (OIDC) are **always** blocked from changing their email, regardless of this flag. Their email is owned by the identity provider and any change would be overwritten on the next sign-in. When **Sync Profile** is off, this flag applies uniformly to every user on the domain, including identity-provider-connected users. The Invent UI reflects this by disabling the email field for users who are blocked and surfacing a tooltip explaining which system manages their identity. ### Allow Profile Change Controls whether users on this domain may change their own name and avatar from the user settings page. The rules mirror **Allow Email Change**: when **Sync Profile** is on, identity-provider-connected users are always blocked regardless of this flag, because any edit would be overwritten by the identity provider on the next sign-in. When **Sync Profile** is off, this flag applies uniformly to every user on the domain. ## Editing a Domain Click the **⚙️ Settings** icon on any domain row to open the domain settings dialog. Settings icon on domain row Domain settings dialog Three flags are editable inside the dialog: * **Sync Profile** * **Allow Email Change** * **Allow Profile Change** Changes save immediately on toggle and take effect on the next sign-in. Two other settings are edited inline on the domain row rather than in this dialog: * To change the **Default Role**, click the pencil icon next to the role badge on the row. * To change **Auto-Join**, flip the toggle switch directly on the row. The domain itself (for example, `acme.com`) and its verified state are immutable after claiming. If you need to change the domain value, delete it using the flow below and claim the new domain from scratch. ## Deleting a Domain Deleting a domain is a sensitive operation and is protected by a second round of email verification. Even organization admins cannot remove a domain with a single click. Delete icon on domain row 1. Click the **🗑️ Delete** icon on the domain row. 2. Click **Send deletion code**. A 6-digit code is emailed to the original verification address **and** to every admin on your organization, so that more than one person is aware of the deletion attempt. 3. Enter the code in the confirmation dialog to complete the removal. Deleting a domain has the following effects: * The claim is released from Invent. Another organization can subsequently claim the same domain. * Auto-join and profile sync stop applying to future sign-ins on that domain. * Existing members who joined through this domain are **not** removed. They remain in your organization with their current roles and any active sessions are preserved. * SSO profiles on the organization are **not** deleted, but they will stop being reachable through the sign-in flow if no remaining verified domain matches an incoming user's email. ## Relationship with SSO Profiles Domains and profiles are separate concepts that are linked at sign-in time: 1. A user enters their email on the [Invent sign-in page](https://www.useinvent.com/sign-in). 2. Invent looks up the email's domain. If it matches a verified domain on any organization, Invent resolves to that organization. 3. Invent then lists every **enabled** SSO profile belonging to that organization. Those profiles become the identity-provider options the user sees. In short: **the domain proves which organization owns the user, and the profile provides the identity provider that authenticates them.** Both pieces are required for SSO sign-in to work end-to-end. [Set up your first SSO profile →](/workspace-management/sso/profiles) ## Troubleshooting The code is 6 digits long and expires after **10 minutes** from the moment it was sent. If the code expired, click **Resend** on the verification screen to receive a new one. If you copied and pasted the code, check that no whitespace or trailing characters were included. Another Invent organization has already verified this domain. If you believe your organization is the rightful owner, contact Invent support with documentation that demonstrates ownership of the domain. Check your spam folder and any organization-wide email filters that may be blocking messages from external senders. The sender address is the `from` address configured for your workspace, or Invent's default if none is configured. If the email still does not arrive, try claiming the domain again with a different mailbox on the same domain. Yes. `team.acme.com` and `acme.com` are treated as entirely separate domains. Only users whose email **exactly** matches a verified domain will be matched by that domain's settings. Claiming `acme.com` does not implicitly cover `team.acme.com`, and vice versa. # Overview Source: https://docs.useinvent.com/workspace-management/sso/overview Single Sign-On for your organization with domains, identity providers, and access policy SSO requires a **Business** or **Enterprise** plan. [View plans](/guides/pricing-and-plans) Single Sign-On (SSO) in Invent is a broader concept than pure identity-provider integration. It is a set of organization-wide identity controls, tied to the email domains your team uses, that govern how members authenticate, how they are onboarded, and how their profile data stays in sync with your directory of record. On the identity-provider side, SSO in Invent works with any standards-compliant **OpenID Connect (OIDC)** provider, such as Okta, Microsoft Entra ID, Google Workspace, Auth0, PingOne, or others. Members authenticate through the identity provider you already trust, and all of your existing policies around multi-factor authentication, conditional access, and directory lifecycle apply automatically. **You don't need to configure an identity provider to benefit from SSO.** Simply [claiming a domain](/workspace-management/sso/domains) is enough to unlock auto-join, default roles, profile sync, and email and profile change locks for every user on that domain, regardless of whether they sign in with a full OIDC identity provider, Google Workspace, Microsoft, or a one-time email code. Setting up an SSO profile is only required if you want users to authenticate through an external identity provider. Access the **Sign-In & SSO** settings at [useinvent.com/o/settings/sso](https://www.useinvent.com/o/settings/sso). SSO settings overview ## How SSO Works in Invent SSO in Invent is built on three concepts that work together: Organization-wide rules that determine which login methods (SSO, Google, Microsoft, or email code) are permitted for users on your verified domains. Email domains that your organization has claimed and verified. Domains govern auto-join, default roles, and profile sync for users whose email matches. Individual identity-provider configurations (Okta, Entra ID, Google, and others). Each profile is an OIDC connection that users can sign in through. As soon as your organization has at least one **verified domain**, every user with a matching email is governed by the domain's settings and the organization's Access Policy. If an **SSO profile** is also enabled, users whose email matches a verified domain will additionally see your identity provider as an option on the [Invent sign-in page](https://www.useinvent.com/sign-in). ## Key Concepts ### Verified Domains A domain is an email domain that your organization has proven it owns (for example, `acme.com`). Verification is completed by entering a one-time 6-digit code sent to an address on that domain. A given domain can only be claimed by one Invent organization; the first organization to complete verification becomes its sole owner. ### SSO Profiles A profile is the OIDC configuration for a single identity provider. A single organization may have multiple profiles. For example, one profile can be used for the primary workforce identity provider and a separate profile for contractors on a different identity provider. Invent recognizes popular vendors automatically from the Issuer URI and displays their logo and canonical name in the provider picker. ### Just-in-Time (JIT) Provisioning When a user signs in through SSO for the first time and no matching Invent account exists, Invent creates one automatically from the identity-provider claims. JIT can be disabled on a per-profile basis if your organization requires that users be invited explicitly before they can sign in. ### Auto-Join When a new user signs up with an email matching a verified domain, Invent can automatically add them to your organization as a member with a configurable default role. Auto-join applies to **all** sign-in methods, not only SSO. A user who signs up with Google using their `@acme.com` email is auto-joined in exactly the same way as a user who signs up through SSO. ### Profile Sync On every SSO sign-in, Invent can refresh the user's name, avatar, and email from the claims returned by the identity provider. This keeps Invent's view of each user consistent with your directory of record and, depending on your domain configuration, prevents users from manually editing identity fields that are owned by the identity provider. ## Who Can Manage SSO Managing SSO requires both of the following: * The **Admin** role in the organization. * A **Business** or **Enterprise** subscription. Members with the Developer, Manager, or Agent role cannot view or modify SSO settings. ## What End Users See Users on your verified domains get a streamlined, branded sign-in experience: 1. They visit the [Invent sign-in page](https://www.useinvent.com/sign-in) and click **Use SSO instead**. 2. They enter their company email and click **Sign in with SSO**. 3. Invent resolves your SSO configuration from the email domain and redirects them to your identity provider. 4. After successful authentication at your identity provider, they are signed in to Invent and redirected to the dashboard. If Google, Microsoft, and email-code sign-in are all disabled on the Access Policy, SSO becomes the only available path for users on your verified domains. [See the full sign-in flow →](/workspace-management/sso/sign-in) ## Plan Limits | Feature | Pay As You Go | Business | Enterprise | | -------------- | :-----------: | :------: | :--------: | | SSO Domains | ✗ | 5 | 50 | | SSO Profiles | ✗ | 5 | 50 | | OIDC Providers | ✗ | ✓ | ✓ | | Access Policy | ✗ | ✓ | ✓ | ## Setup Checklist The setup path depends on whether you want to connect an external identity provider. The first step is required either way. [Claim and verify](/workspace-management/sso/domains) the email domain your team uses (for example, `acme.com`). Invent emails a 6-digit verification code to an address on that domain. As soon as verification completes, auto-join, default roles, profile sync, and email and profile change locks begin applying to every user on that domain, regardless of which sign-in method they use. Skip this step if your team signs in with Google Workspace or one-time email codes. Otherwise, create an OIDC application inside your identity provider and copy the relevant redirect URIs from Invent's [Redirect URIs](/workspace-management/sso/profiles#redirect-uris) dialog into your identity provider's list of allowed redirect URIs. Skip this step unless you completed step 2. [Add a profile](/workspace-management/sso/profiles) in Invent using your identity provider's Issuer URI, Client ID, and Client Secret. Invent automatically discovers the remaining endpoints from your identity provider's `.well-known/openid-configuration` document. Sign out of Invent and sign in again using your company email. If you configured an SSO profile, the identity provider should appear in the SSO provider picker. Otherwise, confirm that Google, Microsoft, and email-code sign-in continue to work as expected for your verified domain. [Review the Access Policy](/workspace-management/sso/access-policy). If no SSO profile is configured, the policy toggles are informational only and all sign-in methods remain available. If an SSO profile is enabled, decide whether to keep Google, Microsoft, and email-code sign-in available or require SSO exclusively for users on your verified domains. ## Supported Identity Providers Invent implements standards-compliant **OpenID Connect (OIDC)**, which means any OIDC-capable identity provider can be used for sign-in. Invent has first-class display recognition (correct vendor name and logo in the provider picker) for the following vendors: * Microsoft Entra ID (formerly Azure AD) * Google Workspace * Okta * Auth0 * PingOne and Ping Identity * OneLogin * JumpCloud * Amazon Cognito * IBM Security Verify * Oracle Identity Cloud Service * Cisco Duo Any other OIDC-compliant identity provider is fully supported as well. Providers that are not on the list above simply display as a generic "OIDC" connection in the provider picker; the authentication pipeline is identical either way. SAML 2.0 is on the roadmap but is not yet supported for sign-in. If your identity provider only supports SAML, please contact Invent support. Most commercial identity providers can also expose an OIDC endpoint, and we can usually help you enable it. # Profiles Source: https://docs.useinvent.com/workspace-management/sso/profiles Connect your identity provider to Invent via OpenID Connect (OIDC) SSO Profiles require a **Business** or **Enterprise** plan. [View plans](/guides/pricing-and-plans) An **SSO Profile** is a connection between Invent and one of your identity providers. Invent implements standards-compliant **OpenID Connect (OIDC)**, so any OIDC-capable identity provider can be used, including Okta, Microsoft Entra ID, Google Workspace, Auth0, PingOne, OneLogin, JumpCloud, and others. An organization may have multiple profiles (for example, one profile for full-time employees on Entra ID and another for contractors on Auth0). At sign-in time, every user whose email matches a [verified domain](/workspace-management/sso/domains) on the organization will see all **enabled** profiles in the provider picker and may choose between them. SSO Profiles list ## The Profiles Table | Column | Description | | ------------ | ------------------------------------------------------------------------------------------- | | **Name** | The display name you assigned to this profile (for example, "Acme Okta"). | | **Provider** | A vendor badge, auto-detected from the Issuer URI. Falls back to a generic "OIDC" badge. | | **Enabled** | A toggle. When off, the profile is hidden from the sign-in picker and rejects new sign-ins. | | **Actions** | ✏️ Edit • 🗑️ Delete | ## Before You Start Two prerequisites must be prepared **before** creating a profile inside Invent: 1. **An OIDC application inside your identity provider** (Okta, Entra ID, or another supported vendor). After creating it, you will receive three values: * **Issuer URI**: the base address of your identity provider with no path (for example, `https://acme.okta.com`). * **Client ID**: the public identifier of the OIDC application. * **Client Secret**: the secret credential of the OIDC application. Treat this like a password. 2. **Invent's redirect URIs registered on the OIDC application**. See the section below for where to find them. ### Redirect URIs Your identity provider needs to know which URLs it is allowed to redirect users to after they authenticate. In Invent, click the **🔗 Redirect URIs** button at the top of the Identity Providers section to open a dialog listing every redirect URI that applies to your workspace. Redirect URIs button in Profiles header Redirect URIs dialog Every redirect URI in the dialog follows this pattern: ``` https:///sign-in/oidc ``` The default Invent domain is always listed. Every [custom domain](/workspace-management/white-label#domain) you have added for whitelabeling is also listed, each with its own `/sign-in/oidc` redirect URI. Invent generates and accepts these redirect URIs dynamically on all of your hostnames, so no additional configuration is required on the Invent side. On the identity-provider side, you can register as many or as few of these redirect URIs as you like: * **Register all of them** for maximum flexibility. Users will be able to complete the sign-in flow from any of your Invent hostnames, including any new custom domains you add later. * **Register only one** if you want to lock sign-in to a single whitelisted hostname, for example your primary whitelabel domain. Some identity providers only allow a single redirect URI per OIDC application. This is a limitation of the identity provider, not of Invent. If yours is one of them, pick the hostname your users will sign in through and register only that URI. Copy each URI individually and paste it into your identity provider's list of allowed redirect URIs. This field is sometimes labeled **Sign-in Redirect URIs** or **Reply URLs** depending on the vendor. If you add a new custom domain later and want users to be able to sign in from it, reopen this dialog, copy the new URI, and register it in your identity provider as well. The **Manage domains** button inside the Redirect URIs dialog navigates directly to [Settings → Domains](/workspace-management/white-label#domain), where custom domains are added. Once a new custom domain is verified, it is automatically added to this dialog as a new redirect URI on your next visit. ## Creating a Profile 1. Go to **Settings** → **SSO** → **Identity Providers**. 2. Click **Add OIDC**. 3. Fill in the form: * **Display name**: the label shown in the provider picker on the sign-in page (for example, "Acme Okta"). * **Domain, Issuer URI, or Well-Known URL**: the base Issuer URI of your identity provider. The full `.well-known/openid-configuration` URL can also be pasted here; Invent will strip the well-known suffix automatically and upgrade `http://` to `https://` before storing it. * **Client ID**: from your identity provider's OIDC application. * **Client Secret**: from your identity provider's OIDC application. The value is encrypted at rest and is never returned in API responses. 4. Click **Create**. Add profile dialog Invent validates the Issuer URI during creation by fetching the OIDC discovery document from `/.well-known/openid-configuration`. If the resolved URL is incorrect, unreachable, or does not return a valid OIDC metadata document, creation fails with an error and no profile is stored. New profiles are created **enabled** by default. They become available in the sign-in picker the moment they are saved, provided at least one verified domain exists on the organization. ### Issuer URI Examples | IdP | Issuer URI format | | ----------------------- | ------------------------------------------------------- | | **Okta** | `https://acme.okta.com` | | **Microsoft Entra ID** | `https://login.microsoftonline.com//v2.0` | | **Google Workspace** | `https://accounts.google.com` | | **Auth0** | `https://acme.auth0.com` | | **PingOne** | `https://auth.pingone.com//as` | | **OneLogin** | `https://acme.onelogin.com/oidc/2` | | **JumpCloud** | `https://oauth.id.jumpcloud.com/` | | **Amazon Cognito** | `https://cognito-idp..amazonaws.com/` | | **IBM Security Verify** | `https://.verify.ibm.com/oidc/endpoint/default` | | **Oracle IDCS** | `https://.identity.oraclecloud.com` | | **Cisco Duo** | `https://.duosecurity.com` | Invent auto-detects these vendors from the hostname of the Issuer URI and displays the matching logo and name inside the provider picker. Any other OIDC provider is fully supported and displays as a generic "OIDC" profile. ### OIDC Scopes Invent requests three standard OIDC scopes from your identity provider: `openid`, `email`, and `profile`. No special configuration is required on the identity-provider side, as these scopes are part of the OIDC core specification and are supported by every OIDC-compliant provider by default. ## Editing a Profile Click the **✏️ Edit** icon on any profile row to open the Edit OIDC Provider dialog. Edit icon on profile row The following fields can be updated: * **Display name**. * **Issuer URI** and **Client ID**, which may need to change when the OIDC application is rotated or recreated inside your identity provider. * **Client Secret**. Leave the field blank to keep the existing secret unchanged. Enter a new value to rotate the secret; the previous value is replaced atomically and cannot be recovered. The **provider type** (OIDC) cannot be changed on an existing profile. If a different protocol or provider type is required in the future, delete this profile and create a new one. Edit profile dialog ## Enabling and Disabling Profiles The **Enabled** toggle on each profile row lets you pause a profile without deleting its configuration. Enabled toggle on profile row When a profile is disabled: * It is hidden from the provider picker on the sign-in page. * Any OIDC callback still in flight for that profile is rejected with a "not operational" error. * Existing sessions created through the profile are preserved and are **not** revoked. * All configuration, including the encrypted client secret, is retained so the profile can be re-enabled immediately without re-entering any values. This is the recommended way to stage changes safely, for example while rotating an OIDC application in your identity provider or pausing access to a contractor-only profile. ## Deleting a Profile Click the **🗑️ Delete** icon on a profile row to remove it. Deletion is protected by a confirmation dialog that reports the number of active SSO sessions the profile currently owns, so you can gauge the impact before confirming. Delete icon on profile row Deleting a profile has the following effects: * **All SSO sessions created through this profile are revoked in the same database transaction.** Users currently signed in through this identity provider are signed out immediately and must re-authenticate on their next request. * The deletion is permanent. The profile configuration, including the encrypted client secret, is removed from storage and cannot be recovered. * User accounts and organization memberships are **not** affected. Users who had signed in through this profile can still sign in through another enabled SSO profile, or through Google, Microsoft, or email-code sign-in if the [Access Policy](/workspace-management/sso/access-policy) allows it. ## Just-in-Time (JIT) Provisioning When a user signs in through SSO for the first time and no matching Invent account exists, the profile's JIT setting determines what happens next: * **JIT enabled** (default). Invent creates the user automatically from the claims returned by the identity provider. Combined with **Auto-Join** on the matching [verified domain](/workspace-management/sso/domains#auto-join), this is the fastest way to onboard a team at scale. Users never need to be invited manually. * **JIT disabled**. First-time SSO sign-ins are rejected with the message *"Automatic member provisioning is disabled for this SSO profile, please ask an admin to invite you first."* Use this setting when you require explicit control over which users are provisioned, for example in highly regulated environments. JIT is configured per profile and defaults to **on** when a new profile is created. ## Revoking Sessions Dedicated session revocation controls (a sessions table with per-user sign-out and an organization-wide "sign out everyone" action) are **coming soon**. For now, the only way to forcibly revoke the SSO sessions created through a specific profile is to delete the profile itself. Deletion revokes every session owned by the profile in the same transaction. ## Vendor Detection Invent recognizes popular identity providers from the hostname of the Issuer URI and automatically displays the matching vendor name and logo in the provider picker. Vendor detection is **display-only**. The underlying authentication pipeline is standards-compliant OIDC regardless of which vendor is detected, or whether any vendor is detected at all. Supported vendors: | Vendor | Matches on hostname | | ------------------- | ---------------------------------------------------- | | Microsoft Entra ID | `login.microsoftonline.com` | | Google | `accounts.google.com` | | Okta | `*.okta.com`, `*.oktapreview.com` | | Auth0 | `*.auth0.com` | | PingOne | `*.pingone.com` | | Ping Identity | `*.pingidentity.com` | | OneLogin | `*.onelogin.com` | | JumpCloud | `*.jumpcloud.com` | | Amazon Cognito | `*.amazoncognito.com`, `cognito-idp.*.amazonaws.com` | | IBM Security Verify | `*.appid.cloud.ibm.com`, `*.verify.ibm.com` | | Oracle IDCS | `*.identity.oraclecloud.com` | | Cisco Duo | `*.duosecurity.com` | If your identity provider is reachable on a **vanity domain** (for example, Okta configured at `auth.acme.com`), the profile still works exactly as any other OIDC profile. It simply displays as a generic OIDC connection without a vendor logo, since hostname-based detection cannot associate a custom domain with a specific vendor. ## Security * **Client secrets are encrypted at rest** using Invent's secret-management subsystem and are never transmitted outside the backend in plaintext. Both the Invent UI and the public API read from a sanitized configuration view that omits the secret entirely. * **OIDC discovery documents are cached** for up to 10 minutes. When the Issuer URI on a profile is changed, the cache entry for that profile is invalidated automatically so the next sign-in uses the new metadata. * **Email verification is enforced**. If your identity provider returns `email_verified: false` in the ID token, Invent rejects the sign-in and surfaces a clear error to the user asking them to verify their email with the identity provider. * **Fallback from `email` to `preferred_username`**. Some Microsoft Entra ID tenants do not emit the standard `email` claim in ID tokens. When `email` is missing, Invent falls back to `preferred_username` (which Entra formats as a UPN email) so sign-in succeeds without configuration changes on the identity provider. ## Troubleshooting Invent was unable to fetch the `.well-known/openid-configuration` document from the Issuer URI provided on the profile. Verify that the URL resolved from the Issuer URI is correct, publicly reachable from the internet, and served over HTTPS. Identity providers hosted on private networks or behind a VPN are not supported. The OIDC `invalid_client` error typically indicates that the Client ID or Client Secret on the profile does not match the values configured on the OIDC application inside your identity provider. This often happens after a secret rotation. Open the profile's **Edit** dialog and re-enter both values. This error corresponds to the OIDC `invalid_grant` response. Every sign-in attempt is single-use and valid for **10 minutes** from the moment the authorization URL is generated. Ask the user to return to the [Invent sign-in page](https://www.useinvent.com/sign-in) and start the flow again. SSO sign-in is restricted to users whose email matches a [verified domain](/workspace-management/sso/domains) on the same organization that owns the SSO profile. Either add the user's domain to the organization's list of SSO domains, or have them sign in with an email address on an already-verified domain. The identity provider returned `email_verified: false` in the ID token. Have the user complete email verification inside the identity provider, or adjust the identity-provider claim configuration so that verified emails are the only ones surfaced to Invent. JIT provisioning is disabled on this profile and the user does not yet have an Invent account. Either invite the user to your organization manually before they sign in, or enable JIT on the profile. # Sign-In Flow Source: https://docs.useinvent.com/workspace-management/sso/sign-in What your team sees when signing in through SSO Once you've [verified a domain](/workspace-management/sso/domains) and [added an SSO profile](/workspace-management/sso/profiles), your team can sign in through your identity provider. This page walks through what that looks like end-to-end. ## The Default Path Most users simply enter their company email on the standard [Invent sign-in page](https://www.useinvent.com/sign-in) and are automatically routed to SSO when appropriate, without ever having to make an explicit choice. ### Step 1: Enter Email From the [Invent sign-in page](https://www.useinvent.com/sign-in), the user enters their company email address (for example, `alice@acme.com`) and clicks continue. The page also offers **Continue with Google** and **Continue with Microsoft** buttons for users who prefer to sign in through those providers, subject to the owning organization's [Access Policy](/workspace-management/sso/access-policy). Sign-in email entry Behind the scenes, Invent checks the user's email domain against the list of claimed SSO domains across all organizations and decides what to do based on the owning organization's [Access Policy](/workspace-management/sso/access-policy). The email field **prefers email code**. Clicking **Continue** from this field sends a one-time code to the user's inbox in every case except one: when email-code sign-in is disabled on the Access Policy and the organization has at least one enabled SSO profile. The full decision matrix is: | Email domain | SSO profile enabled | Email code allowed | What happens on Continue | | ------------ | :-----------------: | :----------------: | -------------------------------------------- | | Not claimed | Any | Any | Send a one-time code | | Claimed | No | Yes | Send a one-time code | | Claimed | Yes | Yes | Send a one-time code | | Claimed | Yes | No | Redirect directly to the SSO provider picker | If the user wants to authenticate through SSO while email-code sign-in is still enabled on their domain, they must click the **Use SSO instead** link below the email field. The email field itself only diverts to SSO when email-code sign-in is disabled and at least one SSO profile is available, which is the scenario where the Access Policy has effectively made SSO mandatory. ### Step 2: Pick Your Provider If the organization has multiple enabled SSO profiles, the user is shown a picker and selects which one to use. Each option displays the profile's configured display name (for example, "Acme Okta") alongside the auto-detected vendor logo, when available. SSO provider picker If only one profile is enabled, the picker is skipped and the user is redirected directly to the identity provider. ### Step 3: Authenticate at Your Identity Provider Invent redirects the user to the identity provider's login page. The user completes whatever authentication steps the identity provider requires, such as password entry, multi-factor authentication, or conditional-access checks. Invent has no visibility into or control over this step. ### Step 4: Back to Invent After successful authentication, the identity provider redirects the user back to Invent's OIDC callback URL at `/sign-in/oidc`. Invent verifies the callback's `state` parameter, exchanges the authorization code for an ID token, validates the claims inside the token, and then creates or reuses the Invent user account. On success, the user is taken to the dashboard. On failure, the user is shown an error screen that explains the reason, including any error code and description forwarded from the identity provider. ## The Explicit SSO Path Users who already know they should authenticate through SSO can click the **Use SSO instead** link at the bottom of the [Invent sign-in page](https://www.useinvent.com/sign-in). This skips the default email-code path and takes them directly to a dedicated SSO email-entry screen. From there, they enter their company email and click **Sign in with SSO**. Dedicated Sign in with SSO screen The screen prompts them to enter their company email and then follows the same **pick your provider → authenticate → back to Invent** sequence as the default path. ## Profile Sync on Sign-In If the user's matching domain has [Sync Profile](/workspace-management/sso/domains#sync-profile) enabled, every SSO sign-in refreshes the user's name, avatar, and email from the ID token claims returned by the identity provider. This keeps Invent's view of each user consistent with your directory of record over time, even as employees are given new names, update their photos, or have their email addresses reassigned. Avatar handling is vendor-aware because different identity providers expose profile photos through different mechanisms: * **Google**: uses the standard OIDC `picture` claim. * **Microsoft Entra ID**: does not emit a profile photo in the ID token. Entra ID profile photos are only accessible through Microsoft Graph, so avatar sync is effectively disabled for Entra users. * **Okta, Auth0, PingOne, Ping Identity, OneLogin, JumpCloud, Amazon Cognito, IBM Security Verify, Oracle IDCS, Cisco Duo**: all use the standard OIDC `picture` claim. * **Generic OIDC providers and vanity domains**: use the standard OIDC `picture` claim when it is present in the ID token. ## First-Time Sign-In (JIT Provisioning) When a user signs in through SSO and does not yet have an Invent account, the profile's JIT setting determines the outcome: * If the profile has **JIT provisioning enabled**, Invent creates the user automatically from the identity-provider claims and continues the sign-in. * If the profile has **JIT provisioning disabled**, the sign-in is rejected with the message *"Automatic member provisioning is disabled for this SSO profile, please ask an admin to invite you first."* If JIT creates the user **and** the user's email matches a verified domain with **Auto-Join** enabled, the new user is also added as a member of your organization with the domain's configured default role. This combination is what allows a new hire to go from "never heard of Invent" to "signed in with the right role" in a single click. ## Errors Your Users Might See | Error message | What it means | | --------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | "Your SSO sign-in session expired or was invalid" | The `state` token was missing, tampered with, or older than 10 minutes. The user needs to restart the sign-in flow from the beginning. | | "This SSO profile is not operational" | The profile was deleted or disabled between the moment the user started the flow and the moment the identity provider redirected them back. | | "The identity provider rejected the credentials" | The identity provider returned `invalid_client`. The Client ID or Client Secret on the profile is wrong, or the secret was rotated. Requires admin action on the profile. | | "The sign-in attempt has expired or already been used" | The identity provider returned `invalid_grant`. The authorization code has already been exchanged, or more than 10 minutes have passed. Ask the user to sign in again. | | "The identity provider did not return an email address" | The OIDC application on the identity provider is not configured to emit the `email` claim. Review the scope and claim configuration on the identity provider. | | "The email is not on a domain claimed by this organization" | The identity-provider account is associated with an email address that does not match any verified domain on your organization. Claim the user's domain, or use a different email. | | "Google sign-in is not enabled for your domain, please use SSO instead" | The organization's Access Policy has disabled Google sign-in for users on verified domains. Direct the user to the SSO flow instead. | | "Microsoft sign-in is not enabled for your domain, please use SSO instead" | The organization's Access Policy has disabled Microsoft sign-in for users on verified domains. Direct the user to the SSO flow instead. | | "Email code sign-in is not enabled for your domain, please use SSO instead" | The organization's Access Policy has disabled email-code sign-in for users on verified domains. Direct the user to the SSO flow instead. | Most of these errors surface on the `/sign-in/oidc` callback page with a clear explanation and a **Go back** button that returns the user to the sign-in page. ## Sign-Out Signing out of Invent terminates the Invent session only. It does **not** sign the user out of the identity provider, because OIDC single-logout is out of scope for the current release. If the user returns to Invent and clicks sign in again, the identity provider may authenticate them silently from its own session. Dedicated controls for forcing re-authentication across your organization are [coming soon](/workspace-management/sso/profiles#revoking-sessions). ## Testing Your Setup Before rolling SSO out to the entire team, perform an end-to-end test using an admin account: 1. Create an SSO profile in Invent and save it. 2. Verify that the profile displays the correct vendor badge in the profiles table, or the generic "OIDC" badge if the profile uses a vanity domain. 3. Open an **incognito window** (so existing sessions do not interfere) and navigate to the [Invent sign-in page](https://www.useinvent.com/sign-in). 4. Enter your company email and confirm that the SSO option is presented. 5. Click **Use SSO instead**, enter your company email, and click **Sign in with SSO** to exercise the full identity-provider flow. 6. Confirm that the sign-in completes successfully and that you land on the Invent dashboard. 7. Open **Settings → Audit Logs** and confirm that the SSO sign-in event has been recorded. 8. Sign out, then sign in a second time, and confirm that repeat sign-ins complete without errors. Once the end-to-end flow is verified, you can safely enable auto-join on the domain and tighten the [Access Policy](/workspace-management/sso/access-policy) at your own pace. # Sub-Organizations Source: https://docs.useinvent.com/workspace-management/sub-organizations Create independent sub-organizations, each with its own branding, domain, members, modules, and billing Sub-Organizations require a **Business** or **Enterprise** plan. [View plans](/guides/pricing-and-plans) Sub-organizations let you run separate workspaces under one parent organization. Each sub-org has its own members, its own assistants, its own branding, and optionally its own domain and billing. You keep oversight from the parent. This is the setup agencies use for each client, and the setup larger companies use for each business unit or brand. Sub-Organizations list with Name, Billing, Custom Domain, Members columns ## Creating a Sub-Organization 1. Go to [**Settings → Sub-Organizations**](https://www.useinvent.com/o/settings/sub-organizations). 2. Click **+ Create Sub-organization** in the top right. 3. Enter an **Organization Name**. 4. Click **Create Sub-organization**. Create Sub-organization modal with name input Everything else (branding, domain, modules, spending cap) is configured after creation from the sub-org's management dashboard. ## The Sub-Organizations List The list shows every sub-org you belong to or manage from the parent. | Column | Description | | ----------------- | --------------------------------------------------------------------------------------------------------------------------------- | | **Name** | The sub-organization's name and logo | | **Billing** | Subscription plan (e.g. `Pay As You Go`) and the current balance or spend | | **Custom Domain** | Shows the sub-org's custom domain when configured, or a **+ Add Domain** button that opens the sub-org's Domain tab when it isn't | | **Members** | Number of members in the sub-organization | Each row has a **⋮** quick-actions menu on the right. ### Quick Actions Menu | Action | What it does | | ----------------------- | -------------------------------------------------------------------------------------------- | | **Invite Member** | Open the invite dialog in the context of this sub-organization | | **Change My Role** | Switch your own role in this sub-org (Admin, Developer, Manager, Agent) or **Leave** it | | **Members** | Jump straight to the Members tab in the management dashboard | | **Whitelabel** | Jump to the Customization tab to edit the sub-org's logo, name, contact info, terms, privacy | | **Modules** | Jump to the Modules tab to toggle which sections of the product this sub-org can access | | **Billing** | Jump to the sub-org's Billing summary | | **Detach Organization** | Remove this sub-organization from the parent. It becomes fully independent afterwards | ### View Usage Across Sub-Organizations Click **View Usage** at the top of the Sub-Organizations page to see aggregated spend and credits across every sub-org, with a date-range filter and a per-org breakdown. ## The Management Dashboard Click any row in the Sub-Organizations list to open that sub-org's management dashboard. You can also jump straight into a specific tab from any item in the row's **⋮** quick-actions menu. The dashboard has seven tabs: Overview, Members, Roles, Customization, Domain, Modules, Billing. Sub-organization management dashboard header and tabs The header shows the sub-org's name, its plan badge, its current balance, and a **Custom Domain** indicator when a domain is configured. A back arrow in the top-left returns you to the list. The **Go to Organization** button in the top-right switches you into the sub-org as a member so you can use it like any other workspace. ### Overview A usage dashboard scoped to this sub-org: **Total Spend**, **Total Credits**, a daily usage graph, and a **Usage by Event Type** breakdown. Filter by Last 7 days, Last 30 days, and other preset ranges. ### Members Invite and manage the sub-org's team members. Each member has a Name, Email, Role, and Status. Members take the same roles as in the parent organization: Admin, Developer, Manager, and Agent. A user can belong to multiple sub-orgs at once with a different role in each. They switch between them using the organization switcher in the top-left of the sidebar. Invitation emails for this sub-org are branded from **this sub-org's** own Customization and Domain, not the parent's. See [Whitelabel for sub-organizations](/workspace-management/white-label#whitelabel-for-sub-organizations) for the branding flow. ### Roles Each sub-organization has its own **Roles** tab for custom roles scoped to that sub-org, mirroring the parent's **Members → Roles**. Roles created here apply only within this sub-org. ### Customization The sub-org's own branding: logo, organization name, contact email, address, terms of service, and privacy policy. These values are used on the sub-org's branded emails, portals, and sign-in screen. Sub-organization Customization tab with branding fields The sub-org does **not** inherit the parent's logo, name, or contact info. For field-by-field details and the end-to-end branding flow, see [Whitelabel for sub-organizations](/workspace-management/white-label#whitelabel-for-sub-organizations). ### Domain Each sub-organization has its own custom domain tab. A sub-org's invitation links and emails only become branded once this sub-org has its own verified domain, independently of the parent. The setup is identical to the parent's domain setup (add hostname, add CNAME, verify). For the full flow, DNS specifics, and the wildcard shortcut for agencies with many sub-orgs, see [Whitelabel → Domain](/workspace-management/white-label#domain) and [Wildcard for agencies](/workspace-management/white-label#wildcard-for-agencies). ### Modules Modules control which sections of the product are visible in this sub-organization's sidebar. Disabled modules are hidden from the sidebar and return a not-available placeholder if visited directly. | Module | What toggling off does | | -------------- | -------------------------------------- | | **Inbox** | Hides the Inbox | | **Analytics** | Hides the Analytics section | | **Assistants** | Hides the Assistants section | | **Knowledge** | Hides the Knowledge section | | **Broadcasts** | Hides Broadcasts | | **Channels** | Hides Channels | | **Workflows** | Hides Workflows | | **Audience** | Hides Audience, contacts, and segments | | **Tables** | Hides Tables | | **Pages** | Hides Pages | **Parent-gated modules**: some modules only work if they are also enabled on the parent organization. If **Broadcasts** or **Workflows** is disabled on the parent, the sub-org's toggle is greyed out and shows *"The feature is not enabled on the parent organization. This toggle has no effect until it is turned on."* Enable it on the parent first, then come back and toggle it here. Modules only apply to sub-organizations. The parent organization always has every module it pays for available. #### Show credits balance At the bottom of the Modules tab is a **Show credits balance** toggle. This changes the usage indicator shown in the sub-org's sidebar. * **Off (default)**: the sidebar shows a **Balance** in dollars, like `$18.10`. * **On**: the sidebar shows a **Usage** percentage, like `Usage 6%`, based on the sub-org's monthly spending limit. No dollar amounts are exposed to members. The credits-based indicator only makes sense when a **Monthly Spending Limit** is set on the sub-org, since the percentage needs a cap to measure against. Invent prompts you to set a limit first if you enable this toggle without one. This is the recommended setting when clients sign in to a sub-org you manage on their behalf and you don't want them to see raw dollar amounts. ### Billing Controls how this sub-organization pays for usage and where its credits come from. Sub-organization Billing tab with Consolidated Billing toggle #### Consolidated Billing **Consolidated Billing** is the single most important control here. It decides who pays for this sub-org. * **Enabled (default)**: usage charges are billed to the **parent organization**. The sub-org draws from the parent's credit pool. No separate subscription, no separate payment method. This is the standard agency setup. * **Disabled**: the sub-org has its **own** billing: its own subscription, its own payment method, and its own plan. Usage is no longer deducted from the parent. Use this if you want a client to pay Invent directly, or if the sub-org is essentially an independent tenant. If you ever "graduate" a client off your agency account, disable Consolidated Billing first so their workspace keeps working with its own subscription after you detach it. #### Monthly Spending Limit Cap how much this sub-org can spend per billing cycle. Once the cap is hit, billable operations pause until the limit is raised or the cycle resets. Combine the cap with the **Show credits balance** toggle on the Modules tab to give members a clean percentage indicator instead of a dollar balance. #### Other Billing Controls The rest of the tab mirrors the parent's billing page, scoped to this sub-org: * **Subscription**: the sub-org's current plan (relevant when Consolidated Billing is disabled). * **Available Balance**: the credit balance assigned to this sub-org. * **Payment Method**: card on file (only used when Consolidated Billing is disabled). * **Auto-recharge**: automatic top-ups when the balance drops below a threshold. * **Payment History**: past transactions for this sub-org only. To add balance, change the plan, or edit payment methods, click **Go to Billing** to switch into the sub-org and open its full Billing page. ## Switching Between Organizations Use the **organization switcher** in the top-left of the sidebar to hop between your parent and any sub-org you belong to. The switcher shows: * The parent organization with its plan badge * All sub-orgs nested underneath (marked with a **↳** icon) From the sub-organizations list, **Change My Role → Admin / Developer / Manager / Agent** lets you switch your own role inside a given sub-org. **Change My Role → Leave** removes you from it. ## Detaching a Sub-Organization Detaching makes a sub-organization fully independent. It disappears from the parent's list and no longer shares any resources. 1. Click **⋮** on the sub-org row. 2. Select **Detach Organization**. 3. Confirm. Before detaching, make sure the sub-org has everything it needs to stand alone: its own **Consolidated Billing disabled** (so it has its own subscription and payment method), its own Customization, and its own Domain. Otherwise it loses access to the parent's credits the moment it's detached. ## Managing Sub-Organizations via the API Everything above can also be done programmatically. This is the setup for platforms and agencies that provision a workspace per client from their own backend and wrap Invent behind their own panel. All requests authenticate with a **parent organization API key** ([create one here](/workspace-management/api-keys)) in the `Authorization: Bearer YOUR_API_KEY` header. A parent key can call every org-scoped endpoint for any of its sub-organizations. Two rules to remember: * The `c` shorthand always means the **parent** org. To act on a sub-organization, put the sub-org's **real id** in the path. * Nesting is one level deep: a sub-organization cannot have sub-organizations of its own. ### Endpoints | Method & Path | What it does | | ------------------------------------------------ | ----------------------------------------------------------------------------------------------- | | `GET /orgs/{org_id}/orgs` | List sub-organizations ([paginated](/api-reference/getting-started/pagination-and-filtering)) | | `POST /orgs/{org_id}/orgs` | Create a sub-organization | | `GET /orgs/{org_id}/orgs/{sub_org_id}` | Get one sub-organization, with plan, balance, members, and config | | `PATCH /orgs/{org_id}/orgs/{sub_org_id}` | Update name, logo, or partial `config` (deep-merged, includes the `modules` visibility toggles) | | `DELETE /orgs/{org_id}/orgs/{sub_org_id}` | Detach the sub-organization, it becomes a standalone organization | | `POST /orgs/{org_id}/orgs/{sub_org_id}` | Transfer an existing standalone organization in as a sub-organization (admin of both required) | | `POST /orgs/{org_id}/orgs/{sub_org_id}/join` | Add yourself (the parent admin) as a member of the sub-org with a role | | `PATCH /orgs/{org_id}/orgs/{sub_org_id}/role` | Change your own role inside the sub-org | | `GET /orgs/{org_id}/orgs/usage` | Consolidated usage across all sub-orgs, by event type and time bucket | | `PATCH /orgs/{org_id}/orgs/{sub_org_id}/billing` | Update the sub-org's billing config: spending cap, auto-recharge, consolidated billing | All routes require the `orgs:write` permission, except the billing route which requires `billing:write`. API keys carry full admin access, so both work out of the box. ### Create a sub-organization ```bash theme={"system"} curl -X POST "https://api.useinvent.com/orgs/c/orgs" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Acme Corp" }' ``` The response includes the new sub-organization's `id`. From that moment, the sub-org is a full workspace: use its id as `{org_id}` on any org-scoped endpoint (contacts, broadcasts, connections, webhooks) with the same parent key. ```bash theme={"system"} curl "https://api.useinvent.com/orgs/SUB_ORG_ID/broadcasts" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### Configure modules and spending Toggle which product sections the sub-org sees, and cap what it can spend: ```bash theme={"system"} curl -X PATCH "https://api.useinvent.com/orgs/c/orgs/SUB_ORG_ID" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "config": { "modules": { "assistants": false, "workflows": false } } }' curl -X PATCH "https://api.useinvent.com/orgs/c/orgs/SUB_ORG_ID/billing" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "auto_recharge": { "enabled": false, "recharge_threshold": 10, "recharge_amount": 50 }, "use_parent_balance": true }' ``` Feature flags (the `features` object) are managed by the Invent team, not through the API. If a sub-org needs a gated capability, such as a dedicated SMS carrier connection, contact support after creating it. The full request and response schemas live in the [API Reference](/api-reference/getting-started/introduction). ## FAQ No. Your **parent organization** pays once. Sub-orgs have **Consolidated Billing** enabled by default and draw from the parent's credits. If you see a second active subscription inside a sub-org, someone accidentally subscribed it separately. Open the sub-org's Billing tab, disable the redundant subscription, and leave Consolidated Billing on. Two reasons. First, to set per-sub-org **Monthly Spending Limits**, track usage separately, and turn **Consolidated Billing off** if you ever want that sub-org to pay its own way. Second, every organization in Invent is architecturally independent, so the billing tab is always present and a sub-org can "graduate" to its own plan later without any migration. Free credits are provided to **one organization per account**. If you have multiple organizations, only one gets the free monthly allowance. Yes. They use a single login and switch between the sub-orgs they're invited to using the organization switcher. Their role can differ in each one. ## Next Steps Brand the parent and every sub-org with logos, domains, and a wildcard for agencies Invite members into a sub-organization once its branding and domain are in place Understand how credits flow between the parent and its sub-organizations Route team sign-ins for each sub-org through your identity provider # Usage & Limits Source: https://docs.useinvent.com/workspace-management/usage-and-limits See what your workspace spends its balance on, and the ceilings your plan applies Two pages answer two different questions. **Settings → Usage** shows what you have spent and on what. **Settings → Limits** shows how much of each resource your plan allows. ## Usage Open **Settings → Usage**. The date range picker in the header drives every chart on the page, with presets from the last 24 hours out to the last three years, plus year to date and a custom range. Usage overview The overview card gives you the headline numbers for the selected range: * **Total Spend**, in dollars. * **Total Credits**, the internal unit every billable operation draws from. You pay in dollars; credits just let messages, knowledge searches and broadcast sends draw from one balance. * A **daily chart** of both, so a spike is easy to spot. Use the controls in the corner to switch between bar, line and area, and to export the underlying numbers as CSV. ### Where the money went **Usage by Event Type** breaks the same range down by what produced the spend, with each type's share of the total. Usage by event type | Event type | What it covers | | :------------------------------------------------ | :-------------------------------------------------------------------- | | **AI Tokens** | Assistant replies and everything else the model generates | | **Speech-to-Text** / **Text-to-Speech** | Voice notes transcribed, and spoken replies | | **Embeddings** | Indexing and searching your knowledge base | | **Conversation Analysis**, **Follow-up Analysis** | Automatic analysis of conversations and follow-up decisions | | **Memory Reconcile**, **Memory Summarize** | Keeping contact memory up to date | | **Broadcast Email / SMS / WhatsApp** | Per-message fees for broadcasts, split by marketing and transactional | | **Workflow Run** | Workflow executions | **Spend by Event Type Over Time** stacks the same categories per day, which is what you want when a total moved and you need to know which category moved with it. Spot a category you did not expect? Compare two ranges before changing anything. A single busy day can dominate a 7-day view and disappear in a 30-day one. ## Limits Open **Settings → Limits** for the ceilings that come with your current plan. Plan limits The table covers how many members, assistants, channels, actions, active contacts, segments, broadcasts, workflows, sub-organizations and custom domains your workspace can have, plus the size of your knowledge base. Some rows are not capped at all. Conversations, broadcast sends, integrations and API access are **unlimited** on every plan: you are billed for what you use rather than blocked at a ceiling. The last rows show the per-message fee for each broadcast channel, which is the usage side of the same page. Limits follow your plan, so upgrading raises them immediately. If your workspace needs more than the listed ceilings, the banner at the top of the page points to Enterprise, where limits are set per workspace. Every sub-organization gets its own limits, so a busy client workspace never consumes another one's headroom. ## Keeping spend predictable Usage and limits are only half the picture. The controls that actually cap what you can spend live in billing: * A **monthly spending limit** pauses billable operations once the cap is reached. * **Auto-recharge** tops the balance up when it dips below a threshold, so sends do not stall. Both are covered in [Pricing and Plans](/guides/pricing-and-plans#billing-management). ## Next Steps Rates, plans, spending limits and auto-recharge Track usage and caps per client or team # Webhooks Source: https://docs.useinvent.com/workspace-management/webhooks Push workspace events to your own systems and watch every delivery A webhook endpoint is a URL of yours that Invent calls when something happens in your workspace that your systems have to react to: a contact who can no longer be reached, a send that did not land, a conversation that changed hands. Instead of polling the API, your server is told. Manage endpoints at **Settings → Webhooks**. Webhook endpoints Each row shows the endpoint's name and URL, how many events it subscribes to, whether it is enabled, and when it was last delivered to. This page covers managing endpoints in the app. For the payload shape, the event catalog, signature verification, and code samples, see the [Webhooks API reference](/api-reference/getting-started/webhooks). ## Creating an endpoint Enter the **endpoint URL** that receives the requests. It has to be HTTPS, and it cannot be a private or loopback address. The name is for you, so you can tell "Production CRM" from "Staging" at a glance. Subscribe only to what you act on. You can change the selection later. It is shown once, right after creation. Store it in your secret manager. Add a webhook endpoint The signing secret (`whsec_…`) is displayed only on creation and on rotation. It is what proves a request came from Invent, so your handler should reject any request whose signature does not verify. If you lose the secret, rotate it to get a new one. ### The events you can subscribe to | Group | Events | | :---------------- | :-------------------------------------------------------------------------------------- | | **Conversations** | `chat.assigned` | | **Contacts** | `contact.blocked`, `contact.unsubscribed` | | **Broadcasts** | `broadcast.failed`, `broadcast.bounced`, `broadcast.complained`, `broadcast.suppressed` | The catalog is deliberately narrow: these are events an external system has to *act* on. Routine create and update traffic belongs to the API, not to a push feed. ## Managing an endpoint The options menu on each row holds everything else. Webhook options menu | Action | What it does | | :------------------- | :--------------------------------------------------------------------------------------------------------------------------------------------- | | **Edit** | Change the URL, name, or event subscriptions | | **Send Test Event** | Delivers a signed `ping` to the endpoint and reports back whether it was accepted. The quickest way to prove your URL and signature check work | | **View Deliveries** | The delivery log for this endpoint | | **Disable / Enable** | Stop or resume deliveries without deleting the endpoint | | **Rotate Secret** | Issue a new signing secret. The current one stops signing immediately, so deploy the new one first | | **Delete** | Remove the endpoint. Events stop being delivered to it | ## Watching deliveries **View Deliveries** lists every attempt from the last 7 days, most recent first. Recent webhook deliveries Each row shows the event, the delivery status, the attempt number and the HTTP status your server returned: * **DELIVERED**: your endpoint returned a `2xx`. * **PENDING**: the attempt failed and a retry is scheduled. * **FAILED**: every retry was used up. * **SKIPPED**: the event was not sent, because the endpoint was disabled or the workspace had no balance to cover the outbound request. Use the **replay** action on any row to send that event again. Replay is how you backfill after an outage on your side, or reprocess events once your handler is fixed. ## When deliveries fail Failed attempts are retried on a widening schedule (5s → 5m → 30m → 2h → 5h → 10h), seven attempts in total. Requests time out after 10 seconds, so acknowledge fast and do the real work afterwards. An endpoint that fails 30 deliveries in a row is **disabled automatically**, and the reason is shown on the endpoint. Fix your side, then enable it again, which clears the failure streak. Delivery is at-least-once and order is not guaranteed, so make your handler idempotent and deduplicate on the event id. ## Next Steps Payloads, headers, signature verification, and code samples Manage endpoints programmatically instead of in the app # Whitelabel Source: https://docs.useinvent.com/workspace-management/white-label Brand Invent as your own. Customize the workspace and connect your own domain for a fully white-labeled experience Custom domains and "Remove Powered by" branding require a **Business** or **Enterprise** plan. The Customization fields (logo, organization name, contact email, address, terms, privacy) are available on every plan, including Pay As You Go. [View plans](/guides/pricing-and-plans) The **Whitelabel** page is the single place where you turn Invent into your brand. It has two tabs: * **Customization**: logo, organization name, contact email, address, terms, and privacy links. These values appear to members, in branded emails, in portals, and in invites. * **Domain**: the custom domain your team and your customers use to reach the workspace. The domain is what unlocks branded emails and a URL that never mentions `useinvent.com`. Access the Whitelabel page at [useinvent.com/o/settings/customization](https://www.useinvent.com/o/settings/customization). Whitelabel page with Customization and Domain tabs **Sub-organizations have their own Whitelabel.** The settings on this page apply only to the organization you're currently in. Every sub-organization has its own Customization and Domain tabs that you configure separately. Jump to [Whitelabel for sub-organizations](#whitelabel-for-sub-organizations) below for the full flow. ## Customization The Customization tab holds the fields that appear wherever Invent renders your brand: the sidebar logo, invitation emails, member-facing pages, and the sign-in screen on your custom domain. | Field | What it's used for | | --------------------- | ---------------------------------------------------------------------------- | | **Logo** | Sidebar, invitation emails, sign-in screen on your custom domain, portals | | **Organization name** | "From" name on invitation and notification emails, header of branded portals | | **Contact email** | Public support email. Reply-to on outgoing branded emails when set | | **Address** | Shown in customer-facing pages. Required for compliance in some industries | | **Terms of service** | Linked from branded portals and sign-in screens | | **Privacy policy** | Linked alongside the terms of service | **Logo recommendations**: SVG for best quality, square (1:1) or landscape (2:1), under 2 MB. PNG and JPG also supported. Click **Save Changes** at the bottom to apply your updates. The logo uploads immediately when selected; the text fields save when you click the button. ## Domain A custom domain is what turns an Invent workspace into a branded workspace. Without it, invitation links still read `useinvent.com/...` and outgoing emails still fall back to Invent's default sender. With it, both switch to your brand. Access it at [useinvent.com/o/settings/customization/domain](https://www.useinvent.com/o/settings/customization/domain). Domain tab with a pending domain and the CNAME record to add ### Adding a Domain Use a subdomain like `assistants.yourcompany.com`, `chat.yourcompany.com`, or `app.yourcompany.com`. Do **not** use the root (apex) domain itself (`yourcompany.com`). Most DNS providers do not allow a CNAME record on the root, so the verification fails with a "Custom hostname does not CNAME to this zone" error. Reserve a dedicated prefix like `assistants.yourcompany.com` if you plan to create sub-organizations later. You can then use one **wildcard CNAME** to cover every sub-org automatically. See [Wildcard for agencies](#wildcard-for-agencies). On the Domain tab, click **+ Add Domain**, enter the full hostname (for example `assistants.yourcompany.com`), and confirm. Add Domain modal with hostname input The domain row shows the exact record to add: ``` Type: CNAME Name: assistants.yourcompany.com Value: cname.useinvent.com ``` **If you use Cloudflare**, set the record to **DNS only** (grey cloud ☁️). Leaving it proxied (orange cloud) blocks the verification because Invent needs to terminate TLS for your hostname directly. Back on the Domain tab, click **Verify**. DNS usually propagates in a few minutes but can take up to 24 hours. While it's propagating the domain stays in **Pending**; once the record resolves, the status flips to **Active**. ### Domain Statuses | Status | Meaning | | ----------- | -------------------------------------------------------------------------------- | | **Pending** | The domain is added in Invent but the CNAME is not yet resolving. | | **Active** | The CNAME is live and the domain is serving the workspace. | | **Error** | A DNS or TLS issue was detected. Re-check the record and click **Verify** again. | ### What Changes Once the Domain Is Active * **Workspace URL**: the workspace is reachable at `https://assistants.yourcompany.com` in addition to the default Invent hostname. Share that URL with your team and clients instead of the `useinvent.com` one. * **Invitation and notification emails**: the "from" name becomes your **Organization name** (from Customization). The sender address switches from the default Invent sender to a brand-neutral `app-emails.com` address. Replies route to your **Contact email** when it is set. * **Sign-in on your domain**: users signing in from your custom URL see your logo and a sign-in flow with no Invent branding. Sending emails from your own domain (for example `support@yourcompany.com`) is not yet supported. It is coming in a future release under [**Settings → Emails**](https://www.useinvent.com/o/settings/emails). Today, branded emails are sent from a neutral `app-emails.com` sender with your organization name. **Members on a custom domain only see the organization that owns it.** If a member signs in through `assistants.yourcompany.com` but belongs to a different organization, they will see the "No Organizations Available" screen. Invite them to the organization that owns the domain from [**Settings → Members & Roles**](https://www.useinvent.com/o/settings/members), or have them sign in through the default Invent hostname. ### Deleting a Domain Click **Delete** on the domain row to remove it. The CNAME record in your DNS provider is not touched. Remove it there separately if you don't plan to reuse the hostname. After deletion, workspace links and emails revert to the default Invent branding immediately. ## Whitelabel for Sub-Organizations Branding does **not** cascade from a parent organization to its sub-organizations. A parent's logo, name, and domain apply only to the parent. A sub-organization becomes branded once you configure its own Customization and Domain, independently of the parent. This is by design. Each sub-organization is a fully independent workspace that can have its own identity, so agencies can run a separate brand per client and companies can run a separate brand per business unit. ### Where the Sub-Organization Whitelabel Lives From the parent organization, go to [**Settings → Sub-Organizations**](https://www.useinvent.com/o/settings/sub-organizations) and click the row of the sub-org you want to brand. The row opens that sub-org's management dashboard, which has its own **Customization** and **Domain** tabs, mirroring the parent's Whitelabel tabs. Sub-Organizations list. Click any row to open that sub-org's management dashboard. Both tabs behave exactly like the parent's versions above, just scoped to this sub-org. ### Branding a Sub-Organization End-to-End From the parent organization, go to [**Settings → Sub-Organizations**](https://www.useinvent.com/o/settings/sub-organizations) and click the row of the sub-org you want to brand. Its management dashboard opens with Overview, Members, Roles, Customization, Domain, Modules, and Billing tabs. Open the **Customization** tab and set the sub-org's own **Logo**, **Organization name**, **Contact email**, **Address**, **Terms of service**, and **Privacy policy**. These are the same fields described in [Customization](#customization) above. Customization tab inside a sub-organization with branding fields The **Organization name** becomes the "from" name on every invitation and notification email this sub-org sends. Without a logo and name here, the sub-org falls back to Invent's default branding on emails. Open the **Domain** tab, click **+ Add Domain**, and enter a hostname dedicated to this sub-org, for example `acme.assistants.yourcompany.com`. Then add the CNAME record shown in the Pending row, exactly as described in [Adding a Domain](#adding-a-domain) above. Domain tab inside a sub-organization with an Add Domain button If you plan to add domains for many sub-orgs, set up a **wildcard CNAME** once and every sub-org hostname under that prefix verifies instantly. See [Wildcard for agencies](#wildcard-for-agencies). Until this sub-org has its own verified domain, its invitation links still use `useinvent.com/...` even if the parent has a custom domain. Once Customization is filled and the sub-org's domain is Active, new invitations sent from this sub-org carry its logo, its organization name as the sender, a brand-neutral `app-emails.com` sender address, and a sign-in link on its custom hostname. Invite members from the sub-org's **Members** tab. A custom domain only serves the organization that owns it. A member signing in through the sub-org's URL who is not a member of that sub-org will see *"No Organizations Available"*. Invite them to the sub-org first, then they can sign in through the custom URL. For the broader sub-organization feature (members, modules, billing, spending limits), see [Sub-Organizations](/workspace-management/sub-organizations). ## Wildcard for Agencies If you plan to run many sub-organizations, each under its own hostname like `acme.assistants.yourcompany.com`, `brightsmile.assistants.yourcompany.com`, or `so-easy.assistants.yourcompany.com`, add **one wildcard CNAME** in your DNS provider and every sub-org hostname verifies instantly with no DNS change per client. ### Step 1: Add the wildcard record in your DNS provider In your DNS provider (not in Invent), add a single wildcard CNAME on a dedicated prefix: ``` Type: CNAME Name: *.assistants Value: cname.useinvent.com ``` The wildcard lives only in your DNS provider. Invent does **not** accept `*.assistants.yourcompany.com` in the **Add Domain** input. Inside Invent you always enter a full hostname like `acme.assistants.yourcompany.com`. Do **not** wildcard the apex (`*.yourcompany.com`). It would catch every other record on your domain like `www`, `mail`, and so on. Always scope the wildcard to a dedicated prefix you reserve for Invent. You can also keep a plain record for the parent organization itself (for example `assistants.yourcompany.com` → `cname.useinvent.com`) alongside the wildcard. ### Step 2: Add the hostname to each sub-organization For each sub-organization: 1. From the parent organization, go to [**Settings → Sub-Organizations**](https://www.useinvent.com/o/settings/sub-organizations) and click the sub-org's row. Its management dashboard opens. 2. Open the **Domain** tab. 3. Click **+ Add Domain** and enter a hostname under your wildcard prefix, for example `acme.assistants.yourcompany.com`. 4. The domain verifies instantly because the wildcard CNAME is already pointing at Invent. No per-sub-org DNS change required. Repeat for every sub-organization. Each one gets its own branded URL without any extra work in your DNS provider. ## Plan Availability | Feature | Pay As You Go | Business | Enterprise | | ---------------------------------- | :-----------: | :------: | :--------: | | Logo, org name, contact info | ✓ | ✓ | ✓ | | Terms & privacy links | ✓ | ✓ | ✓ | | Custom domain | ✗ | ✓ | ✓ | | Remove "Powered by Invent" badge | ✗ | ✓ | ✓ | | Sub-organizations with own domains | ✗ | ✓ | ✓ | ## Troubleshooting You're trying to verify a root (apex) domain like `yourcompany.com`. Most DNS providers do not allow a CNAME on the root. Use a subdomain instead (for example `assistants.yourcompany.com`, `chat.yourcompany.com`, or `app.yourcompany.com`) and add the CNAME under that name. Cloudflare proxies CNAME records by default (the orange cloud ☁️). Invent needs to terminate TLS directly, so switch the proxy status to **DNS only** (grey cloud ☁️) and click **Verify** again. Invitation emails for a sub-organization are branded from **that sub-organization's** own Whitelabel, not the parent's. Open the sub-org, fill in its **Customization** tab, and add a verified domain on its **Domain** tab. Until the sub-org has its own domain added, its invitation emails fall back to the default Invent sender. [Branding a Sub-Organization End-to-End →](#branding-a-sub-organization-end-to-end) A custom domain only serves the organization that owns it. If the user's account is not a member of that organization, they see this screen. Invite them from [**Settings → Members & Roles**](https://www.useinvent.com/o/settings/members) in the organization that owns the domain, and have them accept the invite before signing in through the custom URL again. DNS normally propagates in minutes but can take up to 24 hours. Run `dig CNAME assistants.yourcompany.com` (or any DNS lookup tool) to confirm the record resolves to `cname.useinvent.com` globally before clicking **Verify** again. The preview inside the dashboard always shows the badge. It is removed on the **live widget** on any website where your users actually embed it, and on any assistant accessed through your **custom domain**. Check a live embed or the custom-domain URL in an incognito window to confirm. ## Next Steps Run independent sub-organizations for each client or team, each with its own branding Invite teammates so they land on your branded workspace on first sign-in # Your First Assistant Source: https://docs.useinvent.com/your-first-assistant Create, train, test, and deploy your first AI assistant in minutes This guide walks you through building a working AI assistant from scratch. By the end, you will have an assistant that answers customer questions using your business information, deployed on your website or a messaging channel, and visible in your [Inbox](/guides/inbox). We will use **Bean & Brew Coffee** as our example throughout this guide, but follow along with your own business information for the best results. ## Step 1: Create Your Assistant From your dashboard, click [**Assistants**](https://www.useinvent.com/o/assistants) in the sidebar, then click **Create Assistant**. Create Assistant You will see a dialog asking for: * **Name**: The name customers will see. Enter something that represents your business (e.g., "Bean & Brew Assistant") * **Template**: Keep the default (Custom) for now. Templates give you a head start for common use cases, but starting from scratch helps you understand how everything works Click **Create Assistant**. You are taken to the configuration page with several tabs: **Settings**, **Knowledge**, **Actions**, **Channels**, and **Widget**. Assistant configuration page after creation ## Step 2: Write Your Instructions [Instructions](/assistants/introduction#instructions) define your assistant's personality, behavior, and rules. This is the most important configuration you will set. Click on the **Settings** tab and find the **Instructions** field. Write instructions that cover: 1. **Who the assistant is** (identity and role) 2. **How it should behave** (tone and personality) 3. **What rules it should follow** (boundaries and guidelines) Here is an example for our coffee shop: ``` You are the friendly assistant for Bean & Brew Coffee. Your purpose is to answer customer questions about our menu, hours, location, and ordering. ## Your Personality - Warm and casual, like a favorite barista - Enthusiastic about coffee without being over the top - Helpful and concise. Respect people's time ## Response Rules - Keep answers to 1-3 sentences when possible - If you do not know the answer, say so honestly. Never make things up - For complaints or special requests, offer to connect with our team ## Knowledge Base Rules - For menu items and pricing, always check the knowledge base - Never guess prices or ingredients ``` Writing Instructions Notice that we are defining **behavior**, not listing our menu or prices. Factual information goes in [Knowledge](/guides/knowledge) (next step), where the assistant can search through it efficiently. Keep instructions focused on *how* the assistant should act. Move factual details like menus, pricing, and policies to Knowledge. This keeps costs lower and makes both easier to update. See [Instructions vs Knowledge](/guides/practical/instructions-vs-knowledge) for a detailed breakdown. ### Configure Capabilities Scroll down to the **Capabilities** section and enable: * **[Memories](/guides/memory)** `Recommended`: Your assistant will remember customer names and preferences across conversations * **[Auto Follow-ups](/guides/auto-follow-ups)** `Recommended`: Automatically re-engages idle conversations instead of letting them go cold The Capabilities section holds more toggles than these two, including AI Replies, Auto-resolve, Auto CSAT, and Spam Protection. Leave the defaults for now and revisit them as your needs grow. Then scroll to the **AI Routing** section and turn on **[Transfer to Member](/assistants/routing)** so the assistant can hand off to your team when needed. These features work automatically once enabled. No extra configuration needed. ## Step 3: Add Knowledge Click the **[Knowledge](/guides/knowledge)** tab. This is where you give your assistant the actual information it needs to answer questions. Knowledge tab and Upload Knowledge button Click **Upload Knowledge**. You will see three tabs: ### Option A: Add Text The fastest way to start. Click the **Text** tab. Enter a **Title** (e.g., "Menu and Info") and paste your business information in the **Content** field: ``` # Bean & Brew Coffee ## Menu - Espresso: $3.50 - Americano: $4.00 - Latte: $5.00 (add $0.75 for oat, almond, or soy milk) - Cappuccino: $5.00 - Cold Brew: $4.50 - Drip Coffee: $2.50 - Matcha Latte: $5.50 - Chai Latte: $5.00 ## Food - Croissant: $3.50 - Avocado Toast: $8.00 - Banana Bread: $4.00 - Bagel with Cream Cheese: $4.50 ## Hours - Monday to Friday: 6:30 AM - 7:00 PM - Saturday: 7:00 AM - 8:00 PM - Sunday: 8:00 AM - 5:00 PM ## Location 456 Main Street, Downtown Free street parking available on weekends Closest transit: Central Station (5 min walk) ## Policies - Free Wi-Fi, no time limit - Dogs welcome on the patio - We accept all major credit cards and Apple/Google Pay - Catering available for groups of 10+. Email hello@beanandbrew.com - Allergen info available for all menu items on request ``` Click **Add Content**. The status will show "Processing" and then "Processed" when ready. Once processed, your knowledge item appears in the list. Your assistant can now use this information to answer questions. Knowledge added and processed ### Option B: Crawl Your Website If your business already has a website, click the **Website** tab, paste your URL or sitemap URL, and select a mode: **Single Page** to index one page, or **Crawl** to follow links and index multiple pages. Click **Add Website**. This works well for businesses with existing help centers, product pages, or FAQ sections. You can use both methods. Many businesses crawl their website for broad coverage, then add text knowledge for specific details like internal policies or promotional offers that are not on the site. ## Step 4: Test in the Playground Before deploying anywhere, test your assistant. On the right side of the assistant page, you will see the **Test Assistant** panel. Click **Create Conversation** and start chatting. Playground Conversation Try questions your real customers would ask: * "What's on the menu?" * "Are you open on Sundays?" * "Do you have oat milk?" * "Where are you located?" * "Can I bring my dog?" **What to look for:** * Does the assistant use the right tone from your Instructions? * Does it pull accurate information from your Knowledge? * Does it handle questions it cannot answer gracefully? * Are responses concise and helpful? If something feels off, go back and adjust your Instructions or Knowledge, then test again. This cycle of test, refine, test is how you build a great assistant. The Playground shows a token breakdown for each message, including cost. Use this to understand how much each conversation costs and optimize your Instructions length if needed. [Learn more about pricing](/guides/pricing-and-plans) ## Step 5: Deploy Your Assistant Your assistant is tested and working. Time to put it in front of real customers. You have two main paths. ### Option A: Add the Web Widget The fastest way to go live. Click the **[Widget](/assistants/widget)** tab on your assistant page, then select the **Embed Script** tab (the default). You have two ways to add it: * **Copy the HTML snippet** and paste it into your website before the closing `` tag * **Click "Copy prompt for AI agent"** and paste it into your AI coding tool (Cursor, Claude Code, etc.). It will add the widget to your project for you Either way, a floating chat bubble appears on your site and customers can click it to start a conversation. Widget Tab ### Option B: Connect a Messaging Channel Click the **[Channels](/assistants/channels)** tab to connect your assistant to platforms where your customers already are: * **WhatsApp Business**: Customers message your business number and the assistant responds instantly * **Instagram**: Handle DMs automatically * **Messenger**: Connect your Facebook page * **Telegram**: Create a bot and link it Click **Connect** next to the channel you want, follow the authentication steps, and enable it. Your assistant is now live on that channel. Start with one channel. Get it working well, then expand to more. Your assistant shares the same Instructions, [Knowledge](/guides/knowledge), and [Memory](/guides/memory) across all channels, so adding a new channel later is quick. ## Step 6: Check the Inbox Once your assistant is live, try sending it a message. In this example, we are using the web widget. If you connected a channel like WhatsApp or Instagram instead, try sending a message from there: Customer chatting with the web widget Now click **[Inbox](/guides/inbox)** in the sidebar. This is your central hub for all customer interactions. Every conversation from every channel appears here with the full chat history: Inbox showing the web widget conversation You will see: * **Every conversation** across all channels in one list * **Channel indicators** showing where each message came from (WhatsApp, Instagram, web widget, etc.) * **Conversation details** with the full chat history when you click on any conversation * **Contact panel** on the right showing customer information, [memories](/guides/memory), and conversation history ### What to monitor * **Unresolved conversations**: Messages the assistant may need help with * **Waiting for Human**: Conversations the assistant [transferred to your team](/assistants/routing) * **CSAT scores**: If [Auto CSAT](/assistants/introduction#capabilities) is enabled, satisfaction ratings appear alongside resolved conversations The Inbox gives you full visibility into how your assistant is performing and where it might need improvement. ## What You Have Built In just a few minutes, you have: | Component | What it does | | -------------------- | -------------------------------------------------- | | **Instructions** | Defines your assistant's personality and rules | | **Knowledge** | Gives your assistant accurate business information | | **Playground** | Lets you test and refine before going live | | **Channel / Widget** | Puts your assistant where customers can reach it | | **Inbox** | Shows you every conversation in one place | | **Memory** | Remembers customers across all conversations | This is the foundation. Every assistant you build in Invent starts with these same building blocks. ## Next Steps Now that you have the fundamentals, explore the features that make your assistant truly powerful: The next most powerful step. Give your assistant the ability to book appointments, send emails, process payments, and more. Actions transform your assistant from a chatbot into an agent that actually gets things done Learn exactly what information goes in Instructions vs Knowledge, and why getting it right matters for performance and cost Go deeper on crafting instructions with templates, real examples, and the 11 building blocks of great instructions Ready for a full build? Walk through a complete yoga studio assistant with Google Sheets, Stripe, Calendar, Gmail, and WhatsApp