# Asks documentation > Documentation for Asks — the AI support agent that answers customers on your website, WhatsApp, Instagram, email, and more. --- # Introduction > What Asks is, who it's for, and where to start. Asks is an AI support agent trained on your business. It reads your website, documents, and articles, then answers your customers directly — on your site through a chat widget and on a hosted chat page today, with messaging channels like WhatsApp, Instagram, Facebook Messenger, and email rolling out. When a conversation needs a person, the agent hands it to your team in a shared inbox. ## Who it's for Asks is built for businesses that want customers answered around the clock without staffing every hour of it — e-commerce stores, SaaS products, agencies, and service businesses. Shopify merchants get a deeper integration: the agent can read your catalog and policies, and store context flows into conversations. You don't need a developer to get started; installing the widget is a copy-paste snippet. ## How it fits together Everything lives in a workspace — one per business or brand. You give the workspace knowledge (your website, uploaded documents, written articles), and the [AI agent](/ai-agent) grounds its answers in it. You connect [channels](/channels) so customers can reach the agent where they already are — the widget and chat page today, more channels as they roll out. Every conversation, from every channel, lands in one [inbox](/inbox); the agent resolves what it can and escalates the rest to your team. Each customer builds a profile in [Customers](/inbox/customers), and [Analytics](/analytics) shows what customers ask, where the agent struggles, and what to add to the knowledge base next. ## Explore the docs Go from a URL to a live agent in about ten minutes. Configure behavior, escalation, actions, and model tiers. Websites, articles, and documents the agent learns from. Widget, chat page, Shopify, and messaging channels as they roll out. One shared inbox for every conversation and handoff. One profile per person, deduplicated across every channel. Resolution rates, topics, ratings, and knowledge gaps. Plans, AI credits, add-ons, and invoices. REST API, webhooks, and the agent as an MCP server. ## Support Questions the docs don't answer go to [hello@asks.app](mailto:hello@asks.app). For platform uptime and incidents, see [status.asks.app](https://status.asks.app). --- # Quickstart > Go from your website URL to a live AI agent in about ten minutes. The fastest way to get Asks live is the onboarding wizard at [app.asks.app/onboarding](https://app.asks.app/onboarding). You give it your website, it builds an agent that already knows your business, you try the agent in a playground, and you put it on your site. No credit card is required during setup — you pick a plan once your agent is ready. Already have a workspace and want to add another one? Open [app.asks.app/onboarding?new=1](https://app.asks.app/onboarding?new=1) to run the wizard for a fresh workspace. Your progress saves per workspace — if you close the tab, the wizard resumes at the same step. ## Set up your agent The wizard walks five steps: **Your website → Building → Review → Try it → Go live**. Enter your store or website URL, then select **Build my agent**. That's the whole form — Asks derives your workspace name from the URL, starts reading your site, and works out your industry from what it finds. No website? Choose **Start without one** below the form. In this mode you enter your business name, pick an industry, and write a description of what you do (40–4,000 characters — what you sell, who your customers are, your policies). You can also attach up to 3 knowledge files of 10 MB each (PDF, DOC, TXT, and other common formats) — price lists, FAQs, or policies. The description and files become the agent's starting knowledge. Asks reads a first set of your key pages — up to about a dozen — and drafts your agent from what it finds: your products, policies, and tone. This takes about a minute. If your site is larger, the wizard moves on once enough pages are in and finishes reading that first set in the background. The wizard deliberately doesn't crawl your whole site. After setup, you pick exactly which pages the agent learns from — and add the rest — under [Knowledge base → Websites](/knowledge-base/websites). The wizard shows the agent it drafted from your site: the **agent name**, its **tone** and **response length**, and the **persona and instructions** it will follow. Adjust anything that doesn't sound like you, then select **Try your agent**. You can refine all of this later under [AI agent](/ai-agent). Chat with your agent in the playground — the exact widget your customers will see. Ask the questions your customers actually ask — shipping, returns, pricing — and check the answers against your site. When it sounds right, select **Put it on my site**. Pick how the agent appears: - **Floating widget** — a chat bubble in the corner of your site. The most common choice. - **Inline embed** — chat rendered inside a section of your page. - **Chat page** — a hosted link you can share; no website needed. For the widget and embed, copy the snippet and paste it into your site's HTML before the closing `` tag. Shopify stores can install without touching code. If you pick the chat page, set its access to **Anyone** — the link tells visitors it's unavailable until you do. Select **Finish & see what's next**. The wizard hands you to the **Get started** checklist in your dashboard, where you pick a plan — every plan starts with a 7-day free trial — and the agent switches on for your customers. See [Plans and limits](/workspace/limits). **Installing from the Shopify App Store?** The wizard connects your store automatically and skips the URL step, and the go-live step becomes a one-click **Add to my store** theme embed — no snippet to paste. **Verify it works** — open your site in a new tab, start a chat, and ask a question your site answers. The conversation appears in your [inbox](/inbox) as it happens. ## What's next - [Add more knowledge](/knowledge-base) — articles, documents, and the rest of your website make answers more complete. - [Customize the widget](/channels/widget-customization) — colors, greeting, launcher, and position to match your brand. - [Invite your team](/workspace/team) — teammates take over conversations the agent escalates. --- # Core concepts > The vocabulary Asks uses — workspaces, channels, conversations, credits, and how they relate. Eight terms come up everywhere in Asks and in these docs. Skim this page once and the rest of the product reads itself. ### Workspace A workspace is one business or brand — its agent, knowledge, channels, conversations, team, and billing all live inside it. You can belong to several workspaces and switch between them from the sidebar; each has its own plan and settings. See [Workspace](/workspace/team). ### Channels Channels are where conversations happen. The website [widget](/channels/widget), the hosted [chat page](/channels/chat-page), and [Shopify](/channels/shopify) are available today. Messaging channels — [WhatsApp](/channels/whatsapp), [Instagram](/channels/instagram), [Facebook Messenger](/channels/facebook), [Telegram](/channels/telegram), [Slack](/channels/slack), [Discord](/channels/discord), and [email](/channels/email) — are rolling out; each appears under **Channels** in your dashboard as soon as it's available for your workspace. Every channel feeds the same inbox and the same agent. See [Channels](/channels). ### Conversations and tickets A conversation is one thread with one customer on one channel. Conversations have a status — **Open** or **Closed** — and can carry a ticket for work your team tracks, with a priority of **Low**, **Normal**, **High**, or **Urgent**. Tickets keep their own status — **Open**, **In progress**, or **Closed** — separate from the conversation's. A conversation marked **Needs human** has been escalated past the AI and is waiting for your team. See [Inbox](/inbox) and [Tickets](/inbox/tickets). ### AI agent The AI agent is the model that answers your customers. You define its name, personality, and instructions, and you enable or disable it per channel — some teams run AI-first on the widget but human-only on email, for example. See [AI agent](/ai-agent). ### Knowledge base The knowledge base is what the agent is grounded in: crawled [websites](/knowledge-base/websites), written [articles](/knowledge-base/articles), and uploaded [documents](/knowledge-base/documents). The agent answers from this content rather than inventing. Capacity is measured in Knowledge Base Articles — every page, file, or written article counts as one. See [Knowledge base](/knowledge-base). ### AI credits and model tiers Each AI-sent message consumes credits based on the model tier the agent runs on: **Essential** costs 1 credit per message, **Pro** costs 4, and **Ultra** costs 8. Messages your human agents send are free. Every plan includes a monthly credit allowance; the full matrix is in [Plans and limits](/workspace/limits). See [Billing](/workspace/billing). ### Escalation and handoff When the agent can't resolve a conversation — or the customer asks for a person — it escalates: the conversation is flagged **Needs human** and handed to your team in the inbox, with the context so far. You control when and how this happens. See [Escalation](/ai-agent/escalation) and [Handoff](/inbox/handoff). ### Help center The help center is a public, self-serve site built from your knowledge-base articles, hosted at `/help/your-slug`. Customers browse it directly, and the agent links to its articles in answers. The help center is rolling out and may not be enabled for your workspace yet. See [Help center](/help-center). --- # AI agent overview > How the Asks AI agent answers customers, the setup checklist, and where each setting lives. The AI agent is the model that answers your customers. It reads the conversation, retrieves the relevant material from your [knowledge base](/knowledge-base), optionally calls tools — [custom actions](/ai-agent/actions), [MCP tools](/ai-agent/mcp-servers), or built-ins like order lookup — and writes a reply grounded in what it found, citing its sources. When it can't help, or the customer asks for a person, it escalates to your team; when the customer's question is settled, it can resolve the conversation on its own. Configure it at [app.asks.app/ai-agent](https://app.asks.app/ai-agent). ## How a reply is produced 1. **Retrieve** — the agent searches your knowledge base and answers from that content rather than inventing. 2. **Act** — if the question needs live data or a side effect, it calls a tool: a custom action against your API, a connected MCP tool, or a built-in. 3. **Respond** — it writes the reply in your configured tone and length, in the customer's own language, citing the sources it used. 4. **Escalate or resolve** — it hands off to a human when your [escalation rules](/ai-agent/escalation) fire, and closes conversations it's confident are solved (on by default). After a human has handled a conversation, it can be [handed back to the AI](/inbox/handoff), which picks up with the full context. ## Finding your way around The AI agent section starts with **Get Started** and the **Playground**, then groups the rest: **Train** (Knowledge, Guidance, Escalation & Handoff, Data Collection), **Tools** (Actions, MCP Servers), and **Evaluate** (Evals, Deploy). ## The master switch The **AI Agent Status** card on the [Get Started page](https://app.asks.app/ai-agent) controls whether the agent responds at all — the same toggle also appears on the [Deploy page](https://app.asks.app/ai-agent/deploy). Off means no AI replies on any channel; everything else — knowledge, guidance, actions — stays configured and waits. The agent's **name** is set on the [Guidance page](/ai-agent/guidance); customer-facing branding — colors, launcher, avatar — comes from your [widget settings](/channels/widget). ## AI disclosure Every message the agent sends carries an "AI Agent" label in the chat. There is no setting for this — customers should know when they're talking to an AI, and Asks enforces that transparency for every workspace. ## Setup checklist The [Get Started page](https://app.asks.app/ai-agent) tracks five setup steps with a progress bar. Each step links to its page; you can mark steps done as you go. Connect knowledge base articles, websites, and documents so the agent has something to answer from. Pick the model tier, tone, response length, and custom instructions. See [Model & guidance](/ai-agent/guidance). Define when the AI hands off to a human. See [Escalation & human handoff](/ai-agent/escalation). Talk to your agent exactly the way a customer would before going live. See [Playground & evals](/ai-agent/testing). Turn the agent on where you want it to answer. ## Deploy per channel The agent is enabled per channel, not globally. On the [Deploy page](https://app.asks.app/ai-agent/deploy) you toggle AI responses independently for the chat widget, WhatsApp Business, Instagram, Facebook Messenger, Telegram, Slack, and the public API — or enable and disable all at once. Channels you haven't connected yet prompt you to connect them first, and deploying is gated until the knowledge and guidance steps are complete. Some teams run AI-first on the widget but human-only elsewhere. ## AI usage Every AI-sent message consumes credits based on the model tier — 1, 4, or 8 credits per message. The [Subscription page](https://app.asks.app/subscription) breaks the last 30 days of consumption down by tier and shows the credit history, so you can see where your monthly allowance goes. Allowances per plan are in [Plans and limits](/workspace/limits). ## Configure the agent Model tier, agent name, tone, response length, and custom instructions. When and how the AI hands conversations to your team. Let the agent call your HTTP APIs mid-conversation. Give the agent extra tools from external MCP servers. Conversational lead capture, saved to the customer record. Chat with your agent before customers do, and measure answer quality. --- # Model & guidance > Choose the AI model tier, name the agent, set tone and response length, and add custom instructions. The [Guidance page](https://app.asks.app/ai-agent/guidance) controls how the agent thinks and how it sounds: the name it goes by, which model tier it runs on, the tone and length of its replies, and any standing instructions of your own. ## Identity The **Identity** card sets the **agent name** — the persona the agent adopts in its replies, used in its instructions for things like how it introduces itself. Customer-facing branding — the avatar and colors customers see in chat — comes from your [widget settings](/channels/widget), not from here. ## AI model tiers Each tier trades credits for capability. The tier applies to every AI-sent message, on every channel, and the selected tier shows a short list of what it's good at. | Tier | Credits per message | Best for | | --- | --- | --- | | **Essential** | 1 | Fast, efficient responses for standard support | | **Pro** | 4 | Enhanced reasoning with deeper context understanding | | **Ultra** | 8 | Flagship intelligence for mission-critical conversations | Essential and Pro are available on every plan; Ultra requires Premium. Monthly credit allowances per plan are in [Plans and limits](/workspace/limits). Start on Essential and move up only if answer quality on your real questions demands it — an Ultra reply costs eight times an Essential one. The [Playground](/ai-agent/testing) shows the active tier while you compare. ## Response style Two settings shape every reply; a one-line description under each select updates as you choose. **Tone** | Option | Behavior | | --- | --- | | Professional | Formal and business-appropriate language | | Friendly | Warm and approachable while remaining helpful | | Casual | Relaxed and conversational tone | **Response length** | Option | Behavior | | --- | --- | | Concise | Brief, to-the-point responses | | Balanced | Moderate detail with clear explanations | | Detailed | Comprehensive responses with full context | ## Custom instructions A free-text field, up to 2,000 characters, appended to the agent's standing guidance. Be specific about your brand voice, policies, and restrictions — vague instructions produce vague behavior. Instructions that work well: ```text - Mention our 30-day money-back guarantee whenever pricing comes up. - Never discuss competitor products; steer back to what we offer. - For technical questions beyond the docs, suggest booking a call with support instead of guessing. ``` Custom instructions steer style and policy — they don't add facts. The agent still answers from your [knowledge base](/knowledge-base), so put product information there, not here. Save with the action bar at the bottom of the page; changes apply to the next AI reply. Related: [Playground & evals](/ai-agent/testing), [Escalation & human handoff](/ai-agent/escalation). --- # Escalation & human handoff > When and how the AI hands conversations to your team — handoff rules, business hours, off-hours behavior, notifications, and automations. Escalation is how a conversation moves from the AI to a person. When a trigger fires, the agent tells the customer a human will assist, the conversation lands in your [inbox](/inbox) flagged **Needs human**, and the AI stays quiet until someone takes over or closes the escalation. Configure it at [app.asks.app/ai-agent/escalation](https://app.asks.app/ai-agent/escalation). The page runs top to bottom through four sections — **Handoff rules**, **Availability**, **After handoff**, and **Automation** — and everything saves together with the action bar at the bottom. Only owners and admins can edit; other roles see the page read-only. ## Handoff rules The **Automatic handoff** card leads with the **Enable handoff** toggle. It's on by default; with it off, the AI keeps handling every conversation itself. **Handover message.** What the customer is told when the AI hands off during business hours — used for keyword and reply-limit handoffs, and whenever the AI doesn't write its own transfer message. Up to 1,000 characters; the default reads "I'm transferring you to a human agent who can better assist you." **Trigger keywords.** Keywords are matched as whole words or phrases anywhere in the customer's message (two characters minimum), then handed off immediately. Prefer full phrases over broad single words — a keyword like "refund" would intercept questions your knowledge base can answer. Add your own, or click **Add suggested** for the defaults: *speak to human, talk to agent, human agent, real person, live agent, speak to a manager*. With no keywords at all, the AI still hands off based on its own judgment. **Hand off after too many AI replies.** A safety net: if a conversation runs this many AI replies without resolution, it's handed off automatically. Choose 3, 5, 7, or 10 — or leave it disabled. **Sentiment.** The agent can also monitor customer sentiment and escalate when a customer turns angry. This trigger is off by default and doesn't have a dashboard control — enable it via the [API](/api) or contact support. ## Business hours The **Human Availability (Business Hours)** card holds a workspace-scoped, timezone-aware schedule: per-day open hours (overnight ranges close the next day) plus holidays, evaluated in the IANA timezone you pick, with a live line showing whether you're currently open and when you next reopen. These hours are the single source of truth for availability — your SLA policies use them too. With business hours disabled, your workspace is treated as always open. ## Off-hours behavior In the **Off-hours handoff** card, turn on **Use an off-hours message** and an escalation outside business hours still hands the conversation off — but instead of promising a live transfer, the agent sends your off-hours message telling the customer when the team will be back. The message (up to 1,000 characters) supports the `{{next_open}}` token, replaced with your next opening time — for example "Monday, Jun 22 at 9:00 AM (America/Toronto)". The default reads: ```text Our team is currently offline. I've passed this to a human agent who will get back to you when we reopen ({{next_open}}). ``` Optionally, turn on **Ask for contact info** to have the agent invite the customer to leave an email off-hours when it doesn't already have one. Off-hours handling only takes effect once business hours are enabled above — otherwise the workspace counts as always open and the off-hours message never sends. ## After handoff The **Team notifications** card helps your team pick up escalations quickly: - **AI summary on handoff** — posts a concise AI-written summary of the conversation as an internal note the moment it's escalated. - **Notify these emails on handoff** — a list of addresses that get an email on every handoff. The card warns you when the list is empty, because then no one is told the AI handed off. ## Automation Two workspace-level automations run when a conversation goes quiet — for AI-handled and human-handled conversations alike. **Auto Follow-up** sends a check-in when the customer hasn't replied: set the delay (a value in minutes, hours, or days), the maximum number of follow-ups, whether to send only during business hours, and an optional closing message; AI-handled conversations get a dynamic AI-written check-in, human-handled ones your static text. **Auto-resolve** closes conversations that stay silent for a further timer after the final follow-up. Like everything else on the page, they save with the action bar. ## What escalation looks like in the inbox Escalated conversations carry a **Needs human** badge in the [inbox](/inbox) and its customer panel, and the inbox status filter has a **Needs human** option so your team can work the queue directly. When a human is done, the conversation can be handed back to the AI, which resumes with the full context. See [Human handoff](/inbox/handoff) for the agent-side workflow. Test your rules before going live: open the [Playground](/ai-agent/testing), type one of your trigger keywords, and confirm the agent hands off the way you expect. --- # Custom actions > Let the AI agent call your HTTP APIs mid-conversation — order lookups, account checks, ticket creation. A custom action is an HTTP request the agent can make during a conversation. You define the request and tell the agent when to use it; the agent collects the inputs you specify from the customer, calls your API, and uses the response in its reply — on every channel and in the [Playground](/ai-agent/testing). Manage actions at [app.asks.app/ai-agent/actions](https://app.asks.app/ai-agent/actions). Plans allow 5 actions , 15 , or 50 . The full matrix is in [Plans and limits](/workspace/limits). You don't have to build the form by hand. In the action editor, describe the action in one sentence — "Look up an order's delivery status by tracking number" — and **Describe it and we'll draft it** generates a full draft: name, description, inputs, and request. Review it and verify the endpoint before saving. ## Anatomy of an action What the action is called in your dashboard. The tool name the AI sees is derived from it at creation and stays fixed — renaming the action later doesn't change it. The description the model reads: when to invoke the action, what it returns, how to use it. This is the single biggest lever on whether the agent calls it at the right moment. The parameters the agent collects before calling — each with a name, type, description, required flag, and optionally a fixed list of allowed values. GET, POST, PUT, PATCH, or DELETE against an https URL template. Static values plus `{{variable}}` placeholders. Body mode is none, JSON, or form. Individual header values can be marked secret — they're encrypted, never shown again, and left blank on edit to keep the stored value. Bearer token, API-key header (you name the header), or basic credentials. Secrets are encrypted at rest and never returned to the dashboard. ## Variable templating Collected inputs are inserted into the request with `{{variable}}` placeholders — in the path, query string, headers, or body. They are never allowed in the scheme or host: the destination of a request is fixed at design time, so a manipulated conversation can't redirect calls to another server. Built-ins `{{conversation_id}}`, `{{channel}}`, `{{customer_id}}`, and `{{workspace_locale}}` are also available. ## Safety rails and advanced settings - **Write methods require a domain allowlist.** POST, PUT, PATCH, and DELETE actions must list at least one allowed domain; requests outside it are refused. Write actions are also rate-limited and audit-logged. - **Timeouts** — 1 to 30 seconds per call, 10 seconds by default. - **Response filtering** — optional JSONPath filters (like `$.order.status`) limit what the model sees from the response; empty means the full response. - **Links off by default** — URLs from the response only appear in replies if you enable "Allow links from the response in replies". - **Save to memory** — store a response value under a key that later actions in the same conversation can reference. - **Thinking message** — optional text shown to the customer while the action runs, like "Checking your order…". Widget only. ## Manage and monitor Each action card has an **Enable action** switch — pause an action without deleting it — plus badges for disabled and write actions, a call counter, and the status of the last call. **Recent calls** opens the last 20 invocations across all conversations with status, duration, and any error. Deleting an action deletes its stored credentials and call history with it. ## Worked example: order status Name it *Delivery status* and describe it as: "Look up an order's delivery status by order number. Use when the customer asks where their order is. Returns status, items, and tracking link." One collected parameter: `order_number`, type text, required — "The customer's order number, e.g. #1234". `GET https://api.example.com/orders/{{order_number}}` with an API-key header for auth. Add response filters like `$.order.status` and `$.order.tracking_url` so the model sees only what it needs. Use the editor's built-in test run with a sample order number, check the response, then save. Testing a write method performs a real request, behind a confirmation. The agent can call the action immediately. Verify in the [Playground](/ai-agent/testing): ask "where is my order?" and confirm the agent asks for the order number, calls the action, and answers from the response. For tools that live outside your own API, see [MCP servers](/ai-agent/mcp-servers). --- # MCP servers > Connect external MCP servers so the AI agent can use their tools in customer conversations. The Model Context Protocol (MCP) is an open standard for exposing tools to AI models. Connect an MCP server — your own or a vendor's — and the Asks agent discovers its tools and can call the ones you enable during customer conversations, on every channel and in the [Playground](/ai-agent/testing). Manage servers at [app.asks.app/ai-agent/mcp-servers](https://app.asks.app/ai-agent/mcp-servers). Plans allow 1 server , 3 , or 10 . See [Plans and limits](/workspace/limits). This page is about the agent **consuming** external MCP tools. The reverse — exposing your Asks agent **as** an MCP server that other AI apps can call — is covered in [MCP endpoint](/api/mcp). ## Add a server Give it a name (for example "Acme CRM tools") and the server URL, such as `https://mcp.example.com/mcp`. Only `https://` URLs work, and the server must be reachable on the public internet — localhost and private networks are not supported. **No authentication**, **Bearer token**, or **API key header**. For an API key you also name the header (for example `x-api-key`). Secrets are encrypted at rest and never returned to the dashboard — and changing the server URL clears the stored secret so it's never sent to a new host. Asks connects to the server and discovers its tools with an MCP `tools/list` call (up to 40 tools per server). On success you'll see how many tools were found and that they're now live in customer conversations; all of them start enabled. ## Manage tools Each connected server shows its status — **connected**, **error**, or **disabled** — with a "Last checked" line and, once the agent has called it, when it was last used. The tools list reads "Tools (N enabled / N available)" with a switch per tool: disable any tool you don't want the agent calling; only enabled tools are offered to the model. The **Enable server** switch pauses the whole server — its tools stop being offered — without deleting anything. **Refresh** re-runs discovery after the server's tool list changes, and removing a server cuts the agent's access to its tools immediately and deletes the stored secret. After connecting, open the [Playground](/ai-agent/testing) and ask a question that should hit one of the new tools. If the server shows an **error** badge instead, the card tells you what to fix — rejected credentials, a URL that isn't an MCP endpoint (most end in `/mcp`), a timeout, or a server that isn't publicly reachable — then hit Refresh. ## How the agent uses MCP tools Enabled tools join the agent's toolbox alongside [custom actions](/ai-agent/actions) and built-ins. The tool's own name and description tell the model when to call it — so a well-described server needs no extra prompting. If a tool call fails mid-conversation, the agent answers without it rather than exposing the error to the customer, and the outage shows up on the server card as an **error** status with the last error message. Prefer custom actions when the capability is a plain HTTP call against your own API; reach for MCP when a system already speaks the protocol or ships many tools at once. --- # Data collection > Have the AI agent gather leads and customer details conversationally and save them to the customer record. Data collection turns the agent into a lead-capture channel that doesn't feel like a form. You define the data points you want; the agent works them into conversations at the moment you choose, saves each answer to the customer record as it arrives, and exports everything as CSV. Configure it at [app.asks.app/ai-agent/data-collection](https://app.asks.app/ai-agent/data-collection); settings save with the action bar at the bottom. ## Turn it on and set the approach The **Enable data collection** switch is the master control — the agent only asks when it's on and at least one field is enabled. (If you define fields while it's off, the page warns you that collection is off.) Four settings shape how it asks: - **Reason for collecting** (up to 500 characters) — the agent shares this if the customer asks why. For example: "So our team can follow up and give you more personalized support." - **When to ask** — **Immediately**, **After helping first** (the default: never lead with it), or **On clear intent** (only once the customer shows buying, demo, or follow-up intent). - **How to ask** — **Subtle** weaves the request in naturally and keeps it optional; **Direct** asks plainly. - **Limit to specific channels** — by default the agent collects on every channel; restrict it where identity is already known. The list covers Widget / Chat page, WhatsApp, Messenger, Instagram, Telegram, Slack, Discord, Email, and API — deselect everything and the page warns that the agent won't collect anywhere. ## Define the fields Each field describes one data point, up to 15 per workspace: | Setting | Meaning | | --- | --- | | Key | Lowercase letters, numbers, and underscores (`company_size`), auto-generated from the label. The reserved keys `email`, `phone`, and `name` map onto the customer record itself; everything else is stored alongside it. | | Label | Human-readable name shown in your dashboard. | | Description | Tells the agent what to ask for and how to recognize the answer. | | Type | Text, Email, Phone, Number, or Choices (a fixed option list, like `0-10 \| 10-50 \| 50+`). | | Required | The agent prioritizes getting this. | | Enabled | Off keeps the field but stops the agent asking for it. | Deleting a field stops future collection, but values already collected stay on customer records and in CSV exports. ## How the agent behaves The agent follows fixed rules you don't have to configure: - It asks for at most **one** missing item per message, paced by your **When to ask** setting. - It never re-asks for something the customer already provided in the conversation — or that's already on the customer record. - It saves each value the moment the customer provides it, mid-conversation. - It never asks for sensitive data — passwords, full card numbers, government IDs — and if the customer declines, it respects that and moves on. ## Where the data goes Collected values land on the customer record: reserved keys fill the customer's email, phone, and name; custom fields are stored with the profile. You'll see them on the customer's profile page and in the inbox right rail during conversations. Each capture also fires a `lead.captured` [webhook](/api/webhooks) for your own systems. The **Captured leads** card on the page shows recent captures — a count for the last 30 days, what was collected, and a link to each conversation (customers without a name show as Anonymous). **Export CSV** downloads the full list for all time, the last 30 days, or the last 7 days — one column per field, plus name, email, and phone. Ask for the minimum. One or two required fields with clear descriptions convert far better than a six-field wish list — the agent asks one at a time, so every extra field stretches the conversation. Related: [Customers](/inbox/customers), [Webhooks](/api/webhooks). --- # Playground & evals > Chat against your live agent configuration in the Playground, and measure answer quality with evals. Before the agent talks to customers, talk to it yourself. The Playground runs the same pipeline as production — knowledge retrieval, [custom actions](/ai-agent/actions), [MCP tools](/ai-agent/mcp-servers), escalation rules — so what you see is what customers get. ## The Playground Open [app.asks.app/ai-agent/playground](https://app.asks.app/ai-agent/playground) and start chatting. Nothing here is visible to customers. - **The chat** — styled exactly like your live widget, down to multi-bubble replies, with suggested starter questions to get going and attachment upload from the composer. - **The toolbar** — the agent's status dot, name, and active model tier badge, plus **History**, a dropdown of past playground conversations you can revisit, resume, or delete, and **New chat** for a clean slate. - **Response details** — an optional rail (toggle it on from the toolbar) showing what the agent did behind the scenes for its latest reply: a thumbs up/down to rate it, every **tool call** with expandable arguments and results, the **sources cited**, and a **Setup** snapshot of the live configuration — guidance tier and tone, escalation on or off, knowledge — each linking to its page. Test the edges, not the happy path: ask something outside your knowledge base, type an escalation keyword, request an order lookup. Then adjust [guidance](/ai-agent/guidance) or [escalation rules](/ai-agent/escalation) and re-run in the same conversation. ## Evals Evals put a number on answer quality instead of a gut feeling. At [app.asks.app/ai-agent/evals](https://app.asks.app/ai-agent/evals) you create **datasets** — collections of test questions with expected outcomes — and execute **runs** against them to track pass rates. Each run picks the model tier to test, so you can compare tiers on the same questions; leave a question's expected output empty and it's flagged for manual review instead of auto-judging. Every run has a detail page: per-question verdicts with the judge's reasoning, latency and token counts, the full tool-call trace, and the option to override a verdict by hand. Re-running the same dataset after a knowledge base or guidance change tells you whether quality moved, and in which direction. ## What the agent understands The Playground and every channel share the same input handling, so you can test these directly: - **Images** — the agent sees image attachments and can answer about them (a screenshot of an error, a photo of a product). - **Voice notes** — audio attachments up to 25 MB are transcribed and treated as the customer's message. - **Documents** — PDFs and similar files are read as part of the conversation. - **Any language** — the agent detects the language of the customer's latest message and replies in it, translating your templates and instructions as needed. No configuration required. Once the Playground behaves the way you want, enable the agent on real channels from the [deploy page](https://app.asks.app/ai-agent/deploy). --- # Knowledge base overview > What the knowledge base is, the source types it holds, and how Asks turns your content into grounded answers. The knowledge base is everything your AI agent is grounded in. When a customer asks a question, the agent answers from this content — your website, your articles, your uploaded files — not from general internet knowledge. If something isn't in the knowledge base (or connected live, like your Shopify catalog), the agent won't claim to know it. You manage it at [app.asks.app/knowledge-base](https://app.asks.app/knowledge-base). The sidebar splits it into three source types, with an articles meter at the bottom. ## Source types Crawl your public site. Choose exactly which pages to include, and keep them in sync automatically. Write answers directly in the dashboard — canonical policies, public help articles, or internal-only guidance. Upload PDFs, Word files, spreadsheets, text files, and images. Asks extracts the text, including OCR for scans. What counts as an article, what each plan includes, and what happens at the limit. **Shopify catalog** — if your store is connected through the [Shopify channel](/channels/shopify), products and collections are answered live from Shopify at question time. They are not stored in the knowledge base and never use knowledge base articles. Store policies are answered live by default too; workspaces that chose to crawl their policy pages instead hold them as regular crawled pages. ## How training works Every source goes through the same pipeline: 1. **Extract** — Asks pulls the plain text out of the source: crawled page content, article body, or text extracted from a file. 2. **Index** — the text is split into chunks and indexed for retrieval. 3. **Retrieve** — for each customer question, the agent searches the index and pulls in only the most relevant chunks. 4. **Answer** — the agent writes its reply from those chunks and records which knowledge base items it drew on. The agent retrieves per question, so it always works from the latest indexed version of your content — there is no separate "publish to the agent" step. On Premium, indexing adds **contextual chunking** — each chunk is stored with a short document-level context note, which improves retrieval on long or ambiguous content. It runs automatically; there is nothing to configure. ## Articles The meter at the bottom of the knowledge base sidebar shows how many of your plan's **Knowledge Base Articles** you've used. Every item counts as one article, whatever its type — a written article, an uploaded file, or a crawled web page. Deleting an item frees its slot immediately. Plans include 300 (Starter), 1,000 (Business), or 3,000 (Premium) articles. See [Articles & limits](/knowledge-base/limits) for the full breakdown, extra-article add-ons, and what happens when you hit the limit. Each section — Articles, a website's pages, Documents — has its own search box, so you can check what the knowledge base already holds before adding more. ## When re-training happens - **Articles** are re-indexed the moment you save. Only articles that are **Published** with **AI Agent enabled** are indexed — drafts never reach the agent. - **Documents** are extracted and indexed at upload. - **Websites** re-index when you press **Sync**, when you save a new page selection, or on the source's auto-refresh schedule (weekly or monthly on Starter; daily available on Business and Premium). Pages whose content hasn't changed are skipped, so re-syncs are fast and never use new articles. After adding or changing content, ask the agent a question that content should answer — in the [Playground](/ai-agent/testing) or your live widget — and check that the reply draws on the new source. --- # Websites > Crawl your site into the knowledge base — review pages before crawling, sync on a schedule, and manage every page. Website sources let the agent answer from your site. Add a URL, pick which pages to include, and Asks crawls them into the knowledge base. Manage them at [app.asks.app/knowledge-base/websites](https://app.asks.app/knowledge-base/websites). Website URLs must be `https` — plain `http` URLs (and URLs with embedded credentials) are rejected. The site must be publicly reachable; pages behind a login can't be crawled. The one exception is a password-protected Shopify storefront — see [Password-protected Shopify stores](#password-protected-shopify-stores). ## Add a website Click **Add website** and enter the top-level URL (for example `https://example.com`). Asks discovers subpages from there — via `sitemap.xml` by default. The dialog splits its settings across a **Settings** and an **Advanced** tab: | Setting | Tab | What it does | Default | | --- | --- | --- | --- | | Use sitemap.xml | Settings | Discover pages from the site's sitemap automatically | On | | Auto-refresh | Settings | Re-sync cadence: never, daily (Business and Premium), weekly, or monthly | Weekly | | Crawl Depth | Advanced | Maximum link depth from the root URL (1–10) | 3 | | Allowed Domains | Advanced | Comma-separated domains to stay within; empty allows all subdomains of the root | Empty | | Storefront password | Advanced | Password of a password-protected Shopify store, so Asks can read the site | Empty | Saving opens the **Choose pages to include** picker. Asks maps the site's links first — without crawling anything — so you decide exactly which pages go in before any crawling starts. The link map covers up to 5,000 URLs per site, and a **re-map** button next to the search box refreshes it on demand. On Shopify stores, product, collection, cart, and checkout pages appear greyed out with a note: they're answered live through your [Shopify connection](/channels/shopify) and never use knowledge base articles, so they can't be selected here. Policy pages are excluded the same way by default. Machine-facing files (sitemaps, AI-crawler manifests) are auto-excluded too. If you change your mind while adding a new site, **Discard website** removes the source without crawling anything. Save your selection and the first sync starts immediately. The page count grows live while it crawls; the row shows page count and last-synced time when it finishes. Each crawled page counts as one [Knowledge Base Article](/knowledge-base/limits) — that's the only plan limit that applies, and re-crawling pages you already have never uses new articles. Each crawl ingests at most 2,000 pages per website (the same on every plan; the picker enforces the same cap on selections), and a URL already indexed under another website in your workspace is skipped rather than counted twice. ## Password-protected Shopify stores Development and pre-launch Shopify stores sit behind a storefront password. Asks can still crawl them: enter the password on the config dialog's **Advanced** tab — it's in Shopify under **Online Store → Preferences** — and Asks reads past the password page. If a crawl runs into a password page it can't get past, the website row shows **Password-protected store** (or **Store password not accepted** if the saved password stopped working) with an **Enter password** prompt. The review picker shows the same notice and lists the store's real pages once the password is saved. ## Syncing and re-crawls Press **Sync** on a website row to re-crawl it, or let auto-refresh handle it on schedule. Re-syncs are incremental: every page's content is hashed, and pages whose content hasn't changed are skipped — nothing is re-indexed. Only genuinely new pages use new articles; changed pages refresh in place. Every sync also refreshes the site's link map, so pages added to your site since the last sync become selectable in the picker. Syncs remove pages as well as add them: a healthy full crawl deletes pages that have disappeared from the site, and a selected-pages sync deletes pages you deselected. Removed pages free their article slots immediately. Your plan sets how often each website can re-sync — weekly on Starter, daily on Business and Premium. The same frequency applies to the auto-refresh schedule and the manual Sync button (which shows when the next sync is available). A newly added website is exempt for its first 24 hours, so you can crawl, review pages, and re-sync freely while setting it up. Workspace-wide, crawls are also capped at 30 syncs per hour; beyond that, syncs are refused with "Too many website syncs in a short window" until the window passes. **Sync history** (in the row's ⋯ menu) lists the last 50 syncs with status, start time, duration, pages crawled, and any error message, plus the source's success rate. If a sync goes wrong, the row says so: "Last sync incomplete" when it stopped early (for example on the article limit), "Last sync failed", or "Last sync finished with warnings". ## Managing pages Click **View pages** on a website to open its page list. From there you can: - **Search** pages by URL or title. - **Re-crawl** or **delete** pages individually or in bulk (up to 50 per action). - **Open a page** to see exactly what was extracted — a read-only view of the synced content with its URL, extracted size, an **Open original page** link, a **Re-crawl this page** action, and **Delete page**. Page content is synced from the website, so it can't be edited. Deleting a page stops the agent answering from it, but a future full sync may re-add it if it's still on the website — deselect it in **Choose pages** to keep it out for good. **Choose pages** (in the website's ⋯ menu) opens the same picker as at setup, seeded with your current selection; clearing the selection returns the source to automatic crawling. ## Deleting a website **Delete** in the ⋯ menu removes the source and all its crawled pages, and frees the articles they used. This can't be undone; the site can always be re-added and re-crawled later. ## Related - [Knowledge base overview](/knowledge-base) - [Articles & limits](/knowledge-base/limits) - [Shopify channel](/channels/shopify) --- # Articles > Write knowledge directly in the dashboard — public help articles, internal-only guidance, drafts, and folders. Articles are knowledge you write yourself, in the dashboard, with no source site or file behind them. Use them for the answers you want stated exactly one way: return policies, shipping rules, pricing exceptions, or guidance that exists nowhere else. Manage them at [app.asks.app/knowledge-base/content](https://app.asks.app/knowledge-base/content). ## Write an article Click **+ New content** on the Articles page and pick a type — **Public article** or **Internal article** — to open the editor with that type pre-selected (you can change it later in the details rail). Write the title and body; the body supports rich text. An optional description gives readers — and the agent — a one-line summary. **Content Type** sets the audience: - **Public article** — written for customers. Can appear in your [Help Center](/help-center). - **Internal article** — guidance the agent can use, but customers never see the article itself. Good for edge-case handling, escalation rules of thumb, or facts you want answered without publishing a page about them. Assign a **Folder** to keep the list organized — folders nest, and you can rename or delete them from the Articles page. The page shows the folder tree alongside a search box, filters (status, type, audience, AI Agent), and a **Group by** control that arranges the list by folder, status, type, or date. **Status** is the workflow gate: **Draft** means not ready, **Published** means ready for use. Only published articles with **AI Agent enabled** turned on are indexed for the agent — drafts never reach it, so you can work on an article safely over time. Saving a published article re-indexes it immediately; there is no separate training step. ## Visibility controls Three switches decide who sees an article and how it's used: | Control | Effect | | --- | --- | | Status: Published | Article is ready for use; drafts are never indexed | | AI Agent enabled | The agent may use this article when answering | | Public visibility | The article is visible to customers (public articles only) | **Public visibility** is what connects articles to your Help Center: published public articles with the switch on are the ones your [Help Center](/help-center) serves. Internal articles can't be made publicly visible — the switch is disabled for them. Want the agent to know something without publishing it anywhere? Use a published **internal article** with AI Agent enabled and Public visibility off. The agent answers from it; the article itself stays private. ## When to use articles - **Canonical answers** — when the agent must phrase something one exact way, write it as an article rather than relying on a crawled page. - **Policies** — returns, refunds, warranties, shipping cutoffs. Short, declarative articles retrieve cleanly. - **Gaps** — anything customers ask that your site doesn't cover. Analytics surfaces these as [knowledge gaps](/analytics/insights). - **Internal-only guidance** — context the agent needs that you'd never put on your website. Each written article counts as one Knowledge Base Article against your plan's limit, like any other source — see [Articles & limits](/knowledge-base/limits). A single article can hold up to 2 MB of extracted text — the same per-item guardrail as every other source. Pasting an extremely large document into one article is rejected at save; split it up, or [upload it as a document](/knowledge-base/documents) instead. ## Related - [Knowledge base overview](/knowledge-base) - [Help Center](/help-center) - [Testing your agent](/ai-agent/testing) --- # Documents > Upload PDFs, Word files, spreadsheets, text files, and images — Asks extracts the text, with OCR for scans and images. Documents are files you upload directly: price lists, product manuals, policy PDFs, spreadsheets, even photos of a printed menu. Asks extracts the text and indexes it like any other knowledge. The files themselves are never shown to customers — only the agent reads them. Manage them at [app.asks.app/knowledge-base/documents](https://app.asks.app/knowledge-base/documents). ## Accepted file types | Type | Formats | Notes | | --- | --- | --- | | PDF | `.pdf` | Scanned PDFs work too — pages without a real text layer are read via OCR (up to 20 pages per document) | | Word | `.docx`, `.doc` | | | Spreadsheets | `.xlsx`, `.xls` | Cell text is extracted | | Text | `.txt`, `.md`, `.csv` | | | Images | PNG, JPEG, WebP | Text in the image is extracted via OCR | Each file can be up to **10 MB**, uploaded **one file at a time**. Unsupported types are rejected at upload with an error. ## Upload a document Click **Upload** on the Documents page, then drag a file into the drop zone or browse for it. Extraction runs as part of the upload — text is pulled from the file (via OCR where needed), checked against your plan's article limit (each file counts as one Knowledge Base Article), and indexed. When the dialog confirms, the document is live for the agent. The document appears in the list with its **extracted size** — how much usable text was pulled from the file — alongside the raw file size and upload date. A search box filters the list as it grows. Click a document to open it: a read-only view of the extracted text with the file's details, a **Download original file** action, and **Delete document**. The extraction can't be edited — to change a document, upload a new file. ## Extracted text and your article limit Every uploaded file counts as **one Knowledge Base Article** against your plan's limit, regardless of file size. The extracted-size column is informational — it shows how much usable text the agent got out of the file (a 10 MB PDF full of images might extract to a few hundred kilobytes of text). One flat guardrail applies per item: a single file can hold up to 2 MB of extracted text. See [Articles & limits](/knowledge-base/limits). Deleting a document removes it from the index and frees its article slot immediately. There is no replace flow: uploading a file again creates a new document (and uses a new article), so to update a file, delete the old version first. For content that changes often, prefer a [website source](/knowledge-base/websites) or an [article](/knowledge-base/articles) over re-uploading files — websites re-sync on a schedule, and articles re-index on save. OCR reads what's visible. Very low-resolution scans or decorative images with no readable text may extract little or nothing — an image that yields no text is stored with an extracted size near zero and skipped by indexing. Check the extracted size after upload if the agent seems unaware of a document's contents. ## Related - [Knowledge base overview](/knowledge-base) - [Articles & limits](/knowledge-base/limits) --- # Articles & limits > What counts as a Knowledge Base Article, what each plan includes, and what happens when you reach the limit. Your knowledge base is measured in **Knowledge Base Articles**. Every item you add counts as exactly one article, whatever its type: - an **article** you write, - an **uploaded file** (PDF, DOCX, …) — one file is one article, regardless of file size, - a **crawled web page** — one page is one article. Importing 10 URLs and uploading 3 files uses 13 articles. Your plan sets how many articles the knowledge base can hold, and you can add, edit, or remove them at any time — deleting an item frees its slot immediately. A Shopify catalog answered [live](/channels/shopify) uses no articles at all. ## Limits by plan | Limit | Starter | Business | Premium | | --- | --- | --- | --- | | Knowledge Base Articles | 300 | 1,000 | 3,000 | Need more articles on any plan? Add **+100-article blocks at $19/month each** from [Billing](https://app.asks.app/settings/workspace/subscription). For the full plan matrix — credits, seats, and everything else — see [Plans & limits](/workspace/limits). Your plan also sets how often each website source can re-sync — weekly on Starter, daily on Business and Premium. The frequency applies to both the auto-refresh schedule and the manual Sync button; a newly added website syncs freely for its first 24 hours while you set it up. Beyond that, website crawls run under flat operational caps that are identical on every plan — up to 2,000 pages per crawl, 30 crawl syncs per workspace per hour, 10,000 pages per day workspace-wide, and 5,000 discovered URLs in the review-pages picker — which exist to keep crawls fast and predictable, not to meter your knowledge. Each individual item can hold up to 2 MB of extracted text (far more than any normal page or document). Editing an existing article or re-crawling a page you already have never uses a new article — only genuinely new items count. Uploading a file again is different: it creates a new document and uses a new article, so to update a file, delete the old version first (its slot frees immediately). ## The usage meter The bottom of the knowledge base sidebar shows a live meter: articles used against your plan's limit. It turns amber at 80% ("Almost full") and red at 100% ("Article limit reached"), with a shortcut to upgrade. ## What happens at the limit - **Uploads and article saves** that would exceed the limit are rejected with an article-limit error. Nothing partial is stored. - **Website syncs** stop early: pages indexed before the limit stay, newly discovered pages are skipped, and the sync is marked incomplete — "Stopped early: knowledge base article limit reached. Upgrade your plan or add extra articles to index more pages." Pages you already have still refresh normally, and Asks emails you so a quietly truncated crawl doesn't go unnoticed. - **Existing content keeps working.** The agent still answers from everything already indexed; you only lose the ability to add more. To get back under the limit, delete items you no longer need (slots free immediately), upgrade your plan, or add an extra-articles block. Website re-syncs refresh the pages you already have without using new articles, so a scheduled re-crawl of a stable site won't creep your usage up. ## Related - [Plans & limits](/workspace/limits) - [Knowledge base overview](/knowledge-base) - [Websites](/knowledge-base/websites) --- # Channels overview > Every surface your customers can reach you on, and how each one connects to Asks. Channels are where conversations start. Your AI agent, your team inbox, and your knowledge base are shared across all of them — connect a channel and its messages flow into the same [Inbox](/inbox), answered by the same agent with the same knowledge. You manage channels in the dashboard under [Channels](https://app.asks.app/channels/widget). **Availability** — the website widget, the Chat Page, and Shopify are live for every workspace today. The messaging channels are rolling out product-wide: they already appear under **Channels** in your dashboard with a **Coming soon** or **Launching soon** badge, and each one's connect flow unlocks for everyone as it goes live. ## All channels | Channel | What it is | How it connects | | --- | --- | --- | | [Website widget](/channels/widget) | A chat launcher on your own site — the flagship channel | Embed script | | [Chat Page](/channels/chat-page) | A hosted chat link at `app.asks.app/c/your-slug` — no website needed | Hosted page | | [Shopify](/channels/shopify) | Store-aware answers plus a one-click widget install on your storefront | App install | | [WhatsApp](/channels/whatsapp) | Reply on your WhatsApp Business number | Meta embedded signup | | [Instagram](/channels/instagram) | Answer DMs to your Instagram professional account | Instagram login | | [Facebook Messenger](/channels/facebook) | Answer Messenger conversations on your Facebook Page | Meta login | | [Telegram](/channels/telegram) | A Telegram bot that speaks for your business | Bot token | | [Slack](/channels/slack) | Answer DMs and mentions in a Slack workspace | OAuth ("Add to Slack") | | [Discord](/channels/discord) | A Discord bot in your server | Bot token | | [Email](/channels/email) | Turn a support mailbox into conversations | Forwarding address | ## One agent, per-channel control The AI agent is switched on per channel. Under [AI agent → Deploy](https://app.asks.app/ai-agent/deploy) each channel has its own toggle, so you can let the agent answer on the widget while keeping email human-only, or roll it out one channel at a time. Channels without the agent enabled still deliver every message to your [Inbox](/inbox) for your team to answer. Escalation rules, business hours, and handoff behavior are also shared — configure them once under [Escalation](/ai-agent/escalation) and they apply wherever the agent is deployed. ## Where to start Install the chat widget on your site — the fastest path to your first conversation. Share a hosted chat link in your bio, on QR codes, or in email signatures — zero install. Connect your store for live product, policy, and order-status answers. --- # Website widget > Install the Asks chat widget on your site with one script tag, as a floating launcher or an inline embed. The website widget is the flagship channel: a chat launcher on your own site where visitors talk to your AI agent, and your team can step in from the [Inbox](/inbox). A widget is created for you during onboarding — this page covers turning it on and installing it. How it looks and behaves is covered in [Widget customization](/channels/widget-customization). You manage the widget at [Channels → Website Widget](https://app.asks.app/channels/widget). The page header carries the master toggle: flip it and the status pill switches between **Live** and **Off**. While the widget is off it doesn't load on your site, and the install snippets on the Deploy tab dim with a note asking you to enable the widget first. ## Install the widget Open the **Deploy** tab. A switcher offers three surfaces — **Widget**, **Embed**, and **Chat Page**. Pick **Widget**, copy the embed code, and paste it into your site before the closing `` tag: ```html ``` The snippet on the Deploy tab already contains your real widget key — copy it from there rather than editing this example. Paste the embed code before the closing `` tag of your HTML file. It works on any static site or site builder that lets you add custom HTML. For Next.js, add the snippet to `app/layout.tsx` (App Router) or `pages/_document.tsx`, and consider using `next/script`. For a plain React app, add it to `public/index.html`. Go to **Appearance → Theme Editor → Footer** (`footer.php`) and paste the code before ``. A child theme or a header/footer-scripts plugin keeps the snippet safe across theme updates. When your store is [connected](/channels/shopify), the Deploy tab changes entirely: the surface switcher disappears and a single Shopify card takes its place — your storefront is the install target, and there is no snippet to paste. Select **Add to theme** to open your store's theme editor with the Asks widget app embed ready to activate under **Theme settings → App embeds**. It works with all Shopify themes; once the embed is on, the card reads "Widget is on your Shopify storefront." with **Open theme editor** and **View store** links. **Verify it works** — open your site in a new tab and look for the launcher in the corner. Send a test message; it appears as a conversation in your [Inbox](https://app.asks.app/inbox), and if the agent is enabled for the widget under [AI agent → Deploy](https://app.asks.app/ai-agent/deploy), you get an instant reply. ## Inline embed mode Instead of a floating launcher, you can render the chat inside a section of your page — useful for a dedicated contact or support page. Pick the **Embed** surface on the Deploy tab and paste the snippet where the chat should appear: ```html
``` The chat fills the container (600px tall by default). Size it with the container itself, or with the widget's max width and height under **Style → Window size**. ## Programmatic control The loader exposes a small API on `window.AsksWidget`: - `AsksWidget.open()` / `AsksWidget.close()` — open or close the floating panel, for example from your own "Chat with us" button. - `AsksWidget.init({ widgetKey, containerId })` — mount manually instead of through the script tag's data attributes. For inline mode, `targetSelector` accepts any CSS selector as an alternative to `containerId`. - `AsksWidget.version` — the build identifier of the script actually running on the page. The script tag also accepts optional identity hints for logged-in visitors — `data-customer-email`, `data-customer-name`, and `data-shopify-customer-id`. They personalize the conversation but are never treated as authentication. The Shopify theme embed sets them automatically for signed-in customers. The widget renders inside a shadow DOM at the highest z-index, so your site's CSS can't restyle or bury it — and the widget's styles never leak into your page. ## Your widget key The widget key identifies your widget to the loader script — it's the `data-widget-key` value baked into every snippet on the **Deploy** tab. It's public by design (it ships in your page source), and it's the same key the [widget API](/api/widget) uses. ## Allowed domains You can restrict which sites the widget accepts messages from by setting a domain allowlist on the widget. With domains listed, browser requests from any other domain are refused; entries match the exact host and its subdomains, and can be written as bare hosts (`example.com`), full URLs, or wildcards (`*.example.com`). With no domains listed, the widget works anywhere it's embedded. The allowlist is managed through the [widget API](/api/widget). ## Next steps - [Widget customization](/channels/widget-customization) — name, colors, theme, launcher, conversation starters, languages, and behavior. - [Chat Page](/channels/chat-page) — the same chat as a hosted link, no install required. - [AI agent → Deploy](https://app.asks.app/ai-agent/deploy) — turn AI answers on or off for the widget. --- # Widget customization > Configure the widget's content, style, behavior, and languages with a live preview of what customers will see. Everything about how the widget reads, looks, and acts lives at [Channels → Website Widget](https://app.asks.app/channels/widget), in three tabs: **Content**, **Style**, and **Behavior**. The right side of the page is a live preview that updates as you type; a floating save bar appears whenever you have unsaved changes. The same configuration drives the floating widget, the inline embed, and the hosted [Chat Page](/channels/chat-page). ## The three tabs ### Content Every piece of text a visitor reads, grouped by the surface it appears on. Opening a section jumps the live preview to the matching view, so you always see what you're editing. | Section | Settings | | --- | --- | | Home screen | Widget name; header text (leave empty to show your logo); the home headline and subheadline; the **Welcome Card** — show or hide it, and set its title and subtitle; **Spaces** — whether the widget offers the **Home** and **Messages** views | | Conversation | Chat opening message (the first message the AI sends); **conversation starters** — up to 5 click-to-send prompts, reorderable, with a **Keep showing after first message** toggle; message input placeholder; **Footer & disclaimer** — a footer line (for example a reply-time expectation) and a dismissible one-time notice at the top of the chat | | Launcher teaser | A small message bubble next to the closed launcher: show or hide it, its text (leave empty to reuse the chat opening message), and a delay in seconds after page load | ### Style How the widget looks, from theme to launcher: - **Color theme** — **Light**, **Dark**, or **Custom** . The widget keeps your saved theme regardless of the visitor's device settings. Custom unlocks per-token colors — surfaces (background, card, AI message bubble, border), text (primary, secondary, link), accent text, and input colors — each with a contrast warning when a pair falls below the WCAG AA ratio of 4.5:1. - **Primary color** — your accent, used inside the chat for buttons, your messages, links, and active tabs. A warning appears if the color is too light to read on white. A separate toggle applies it to the header. - **Profile picture** — JPG, PNG, or SVG up to 1MB; defaults to your workspace logo. - **Branding** — a **Show Branding** switch and a **Remove Asks branding** switch control the "Powered by Asks" mark. - **Launcher** — the floating button always uses your primary color, and shows the Asks mark by default. Upload your own **launcher icon** to replace it (square images with a transparent background work best — PNG or SVG, up to 1MB), and set the size (**Small**, **Input only**, or **Classic**) and position (right or left). - **Shape & type** — roundness (S / M / L / Full) and text size (Small / Medium / Large). - **Window size** — max width 320–640px and max height 400–800px, used by both the floating window and the inline embed. ### Behavior How the widget acts during a visit, in three groups: - **Engagement** — **Auto-open the widget** on page load, with an optional delay in seconds, and **Launch directly into chat** to skip the home screen. - **Chat experience** — **Show typing indicator** while a reply is being written, and **Allow file uploads** with a configurable max file size in MB (10 by default; up to 10 files per message). - **Feedback** — end-of-chat ratings are a workspace-level setting, not a widget one. The tab links to the [Ratings analytics page](https://app.asks.app/analytics/ratings), where one toggle covers every channel; see [Analytics → Ratings](/analytics/ratings). ## Localization The Behavior tab also carries **Localization** — the language of the widget chrome: buttons, labels, timestamps, and system messages. Pick a default language and add any of eight: English, Spanish, Portuguese, French, German, Italian, Dutch, and Indonesian. When a visitor's browser language matches a language you've enabled, the widget displays in it; otherwise it uses your default. Your own content — the opening message, starters, and titles — is never machine-translated; only the built-in chrome switches language. The setting applies to the floating widget, the inline embed, and the [Chat Page](/channels/chat-page) alike. The live preview is exactly what customers will see — switch it between the widget, embed, and Chat Page surfaces, and between desktop and mobile, before you save. With a Shopify store connected, the preview locks to the floating widget, since your storefront is the only install target. ## Related - [Website widget](/channels/widget) — install the widget on your site. - [Chat Page](/channels/chat-page) — the hosted surface that shares this configuration. - [Analytics → Ratings](/analytics/ratings) — the workspace-level rating setting and where ratings land. --- # Chat Page > A hosted chat page at app.asks.app/c/your-slug — share a link and customers can talk to you with nothing to install. The Chat Page is your chat as a standalone, hosted page at `https://app.asks.app/c/your-slug`. There is nothing to embed and no website required — put the link in a bio, behind a QR code, or in an email signature, and anyone who opens it can start a conversation with your AI agent and your team. The Chat Page is a surface of the widget channel, so the widget's master toggle must be **Live** for the hosted page to load — while it's off, the link shows "Chat page not found." You don't need the widget installed on any site, though: keep the toggle on, leave the snippet unpasted, and run the Chat Page alone. ## Turn it on Go to [Channels → Website Widget → Deploy](https://app.asks.app/channels/widget/deploy) and pick the **Chat Page** surface. Your hosted page URL is shown with **Copy link** and **Open** buttons. Under **Who can access**, choose the page's access scope: - **Anyone** — the page is public; anyone with the link can chat. - **Invited** — reserved for invite links; for now this keeps the page private. - **Nobody** — the page is off. This is the default. Set it to **Anyone** to go live. Until then, visitors who open the link see "This chat isn't available." Copy the URL and put it wherever customers find you — link-in-bio, QR codes on packaging or receipts, email signatures, social profiles. **Verify it works** — open the link in a private browser window and send a message. It arrives in your [Inbox](https://app.asks.app/inbox) as a widget conversation, and the reply streams back onto the page. ## What visitors see The Chat Page shares the widget's content and style configuration — the opening message, conversation starters, theme and colors, text size, logo, and branding you set under [Widget customization](/channels/widget-customization) all apply. So do the Behavior settings for file uploads and the typing indicator, and the [Localization](/channels/widget-customization#localization) languages: the page chrome renders in the visitor's browser language when it matches one you've enabled. The header shows your workspace name with "Online · replies instantly" when the AI agent is enabled for the widget, or "We'll reply as soon as we can" when it isn't. The left rail lists the visitor's conversations and offers **New conversation**, so one customer can keep separate threads. When conversation ratings are enabled for your workspace on the [Ratings analytics page](https://app.asks.app/analytics/ratings), the page invites the visitor to rate the conversation at the end. ## Conversation history Visitors don't sign in. The page keeps an anonymous visitor identity in the browser's local storage, so a returning visitor on the same browser and device picks up their conversation where they left off. Clearing site data or opening the link in a private window starts a fresh visitor with no history. ## Troubleshooting ### The link shows "This chat isn't available" Access isn't set to **Anyone**. Change **Who can access** on the Deploy tab — the change applies immediately. ### The link shows "Chat page not found" Either the widget's master toggle is off — the hosted page requires the widget channel to be **Live** — or the URL is wrong. Check the toggle on the [Website Widget page](https://app.asks.app/channels/widget), then copy the link again from the Deploy tab. ### A customer says their history is gone History lives in the visitor's browser. A different device, a different browser, private mode, or cleared site data all start a new anonymous visitor. --- # WhatsApp > Connect a WhatsApp Business number through Meta's Embedded Signup and answer customers on WhatsApp. The WhatsApp channel connects a WhatsApp Business number to your workspace. There are two ways in: Meta's official Embedded Signup for a number on the Cloud API, or **coexistence mode** for a number you already use in the WhatsApp Business app — both run from the Asks page, and you stay on it the whole time. Once connected, customer messages arrive as conversations in the [inbox](/inbox), the AI agent replies, and you manage your business profile, message templates, and number health from the channel page. You can connect more than one number; each becomes its own channel. **Availability** — this channel is rolling out and may not be enabled for your workspace yet. It will appear under **Channels** in your dashboard as soon as it's available. ## Prerequisites - A Meta (Facebook) Business account. - A phone number you control. For the Cloud API path it must **not** be registered with the consumer WhatsApp app — Meta sends a verification code to it during signup. A number already on the **WhatsApp Business app** connects through coexistence mode instead, with no verification code. ## Connect WhatsApp Go to [app.asks.app/channels/whatsapp](https://app.asks.app/channels/whatsapp) and click **Connect WhatsApp Business**. A Facebook login popup opens. Sign in with your Facebook business account, then choose an existing WhatsApp Business Account or create one, and add your phone number. Meta sends a verification code to the number. Asks subscribes webhooks, registers your number, and pulls your business profile. You can receive messages immediately. ### Already using the WhatsApp Business app? Connect the same number without giving up your phone. Click **Connect your app** on the channel page, sign in with Facebook, and pair the app by scanning a QR code — no verification code, no re-registration. You keep chatting from the app while Asks answers from the inbox, and replies you send from your phone are mirrored into the same Asks conversation. During signup you can bring over your contacts and up to 6 months of chat history; sync status shows on the channel's **Overview** tab. Coexistence needs app version 2.24.17 or newer, and the app must be opened at least every 14 days or Meta drops the connection. A few app features — broadcast lists, disappearing messages, view-once — are disabled while connected. **Verify it works** — message your business number from a personal WhatsApp account. The conversation should appear in your inbox, and the AI agent's reply should arrive back in WhatsApp. ## After you connect The channel page has four tabs: - **Overview** — connection status, quality and conversation stats, and the **Refresh**, **Disconnect**, and **Reconnect** actions. For coexistence numbers it also shows the **Business app connected** badge and the contact and chat-history sync status. - **Business Profile** — edit what customers see on your WhatsApp profile: about (139 characters), description, contact email, address, websites, and business vertical. The profile photo must be JPEG or PNG, up to 5 MB. The display name itself is managed in WhatsApp Manager. - **Templates** — create message templates in the **Marketing**, **Utility**, or **Authentication** category. Templates support a body with numbered variables (`{{1}}`, `{{2}}`, …), an optional header (text or media), footer, and buttons. Every template is submitted to Meta for review and can only be used once **Approved**. Approved templates can't be edited at all — Meta doesn't even allow changing an approved template's category — so delete the template and create a new one. - **Quality & Health** — Meta's signals about your number: quality rating (High/Medium/Low), messaging limit tier, and throughput, plus a feed of recent account events. Refreshed daily and on every quality update from Meta. ## How messaging works WhatsApp uses a **24-hour customer service window**. You and the AI agent can send free-form replies for 24 hours after the customer's last message. The inbox shows the time remaining above the composer. Outside the window, free-form messages are rejected by Meta — you must send an **approved template** instead. The composer offers **Send template** when the window has expired; templates can also be sent inside the window. Media is supported both ways: images, video, audio (voice notes are transcribed for the AI agent), documents, and stickers, with uploads up to 100 MB. Emoji reactions work in both directions, and delivery and read receipts show on your outbound messages. When the AI agent offers quick-reply choices, they're delivered as native WhatsApp reply buttons (up to three) or a list. Conversation pricing follows Meta's category-based model. ## Troubleshooting ### My templates keep getting rejected Meta reviews every template against its category rules. Check the rejection reason shown under the template's status, and leave "allow category change" on so Meta can reclassify instead of rejecting. ### I can't type a reply in an old conversation The 24-hour window has closed. Send an approved template to reopen the conversation; once the customer responds, free-form replies work again. ### My quality rating dropped Meta lowers quality when customers block or report your number. Watch the **Quality & Health** tab, and keep outbound templates relevant. ### What happens when I disconnect? Asks unsubscribes from your WhatsApp Business Account and revokes its access. Conversations stay in your inbox, and **Reconnect** runs Embedded Signup again. --- # Instagram > Connect an Instagram professional account so your AI agent answers DMs, within Meta's messaging windows. The Instagram channel connects your Instagram account's direct messages to Asks. Customers DM your account; the AI agent answers, and conversations land in the [inbox](/inbox). The integration covers DMs only — comments and mentions are not part of it. **Availability** — this channel is rolling out and may not be enabled for your workspace yet. It will appear under **Channels** in your dashboard as soon as it's available. ## Prerequisites - An Instagram **professional account** — Business or Creator. Personal accounts can't connect; switch the account type in the Instagram app first. ## Connect Instagram Go to [app.asks.app/channels/instagram](https://app.asks.app/channels/instagram) and start the connection. You're redirected to Instagram's official Business Login. Asks asks for basic profile access and messaging permissions — enough to handle DMs, nothing more. Asks subscribes webhooks and starts routing DMs to your inbox immediately. Access tokens refresh automatically, so there's nothing to maintain. **Verify it works** — DM your Instagram account from another account. The message should appear as a conversation in your inbox, with the AI agent's reply showing up in the Instagram thread. ## How messaging works Instagram enforces Meta's messaging windows, and Asks applies them for you: - **Within 24 hours** of the customer's last message — the AI agent and your team can reply freely. - **From 24 hours to 7 days** — only a **human agent** may reply (Meta's human-agent window). The AI agent never uses this window; conversations needing a response after 24 hours are your team's to answer from the inbox. - **After 7 days** — the conversation can't be replied to at all until the customer writes again. Story mentions arrive as conversations (marked as a story mention), and replies to your stories arrive as regular DMs. Media in DMs is supported — images, video, audio, and reels all land in the inbox. The thread stays in sync with Instagram: emoji reactions, message edits, and read receipts carry over, and if a customer unsends a message it's redacted in Asks too. Replies your team sends from the Instagram app or Meta Business Suite are mirrored into the same Asks conversation, so the record stays complete wherever you answer. When the AI agent offers quick-reply choices, they appear as native chips in the DM. You can connect more than one Instagram account; each becomes its own channel. ## Disconnecting **Disconnect** on the channel page unsubscribes Asks and revokes its access; conversations stay in your inbox. If you instead remove Asks from your Instagram account settings (deauthorize), the channel is disconnected automatically and your workspace is notified. A data-deletion request from Instagram permanently deletes the channel and its conversations. ## Troubleshooting ### "Personal accounts can't connect" Your Instagram account is a personal account. Switch it to Business or Creator in the Instagram app (Settings → Account type), then connect again. ### The AI stopped replying in a conversation If the customer's last message is more than 24 hours old, that's Meta's policy at work — only a human agent may reply until day 7. Answer from the inbox. ### I can't reply at all After 7 days with no customer message, Meta closes the conversation. It reopens as soon as the customer writes again. ### Comments on my posts don't show up Expected. The integration handles DMs only. --- # Facebook Messenger > Connect one or more Facebook Pages so your AI agent answers Messenger conversations. The Facebook Messenger channel connects your Facebook Pages to Asks. People who message a Page through Messenger reach your AI agent, and every conversation lands in the [inbox](/inbox). You can connect several Pages; each becomes its own channel. **Availability** — this channel is rolling out and may not be enabled for your workspace yet. It will appear under **Channels** in your dashboard as soon as it's available. ## Prerequisites - A Facebook business account. - Admin access to each Facebook Page you want to connect. ## Connect Facebook Go to [app.asks.app/channels/facebook](https://app.asks.app/channels/facebook) and start the connection. You're sent to Facebook Login for Business. In Meta's login flow, select one or more Facebook Pages. You must be an admin of each. Every Page you grant is connected as its own channel. Asks subscribes each Page's webhooks and starts routing Messenger conversations to your inbox. Page access tokens don't expire, so there's nothing to refresh. **Verify it works** — open your Page in Messenger from a personal account and send a message. It should appear as a conversation in your inbox, with the AI agent's reply arriving in Messenger. ## How messaging works Messenger follows the same Meta messaging windows as [Instagram](/channels/instagram), and Asks applies them for you: - **Within 24 hours** of the customer's last message — the AI agent and your team can reply freely. - **From 24 hours to 7 days** — only a **human agent** may reply (Meta's human-agent window). The AI agent never uses this window. - **After 7 days** — the conversation can't be replied to until the customer writes again. Your Page's own inbox keeps working alongside Asks: replies your team sends from Meta's Page inbox or Business Suite still reach the customer as usual, and they're mirrored into the same Asks conversation, so the record stays complete wherever you answer. Media works both ways — customers can send images, video, audio, files, and stickers, and you can send media back from the inbox. Emoji reactions, message edits, and delivery and read receipts sync from Messenger into the inbox. New conversations open with a **Get Started** button and greeting that Asks configures on the Page for you, and when the AI agent offers quick-reply choices they appear as native Messenger chips. ## Troubleshooting ### One of my Pages isn't connected Only Pages you granted during login are connected. Run the connection again and select the missing Page — existing Pages are unaffected. "Connect another Page" on the channel page starts the same flow. ### The AI stopped replying in a conversation If the customer's last message is more than 24 hours old, Meta's policy allows only human-agent replies until day 7. Answer from the inbox. ### I can't reply at all After 7 days with no customer message, Meta closes the conversation. It reopens when the customer writes again. ### What happens when I disconnect? Disconnecting a Page's channel unsubscribes Asks from that Page and stops routing its conversations. Other connected Pages and existing inbox history are unaffected. **Reconnect** restores it. If you instead remove Asks from the Page in Facebook's settings, the channel disconnects automatically and your workspace is notified. --- # Telegram > Connect a Telegram bot so your AI agent answers customers in Telegram direct messages. The Telegram channel connects a bot you own to your workspace. Customers message the bot in a direct chat; your AI agent answers, and every conversation lands in the [inbox](/inbox) where your team can step in at any time. **Availability** — this channel is rolling out and may not be enabled for your workspace yet. It will appear under **Channels** in your dashboard as soon as it's available. ## Prerequisites - A Telegram account. - A bot created with [@BotFather](https://t.me/BotFather) — you create it during setup below. Asks only needs the bot's HTTP API token. ## Connect Telegram Open [t.me/BotFather](https://t.me/BotFather) in Telegram and send `/newbot`. BotFather asks for a display name, then a username ending in `bot`. When it finishes, it replies with the bot's **HTTP API token** — a string like `123456789:AA...`. Copy the full token from BotFather's message. If you lose it later, send `/token` to BotFather to reveal it again. Go to [app.asks.app/channels/telegram](https://app.asks.app/channels/telegram), paste the token, and connect. Asks validates the token with Telegram and registers the bot's webhook automatically — there is nothing to host or configure on your side. Once connected, the channel appears as `@yourbotname` with a **Connected** badge. The channel page shows the bot's name, a `t.me` link, and conversation counts. **Verify it works** — open the `t.me` bot link from the channel page, tap **Start**, and send a message. It appears as a new conversation in your inbox, and the AI agent replies in the Telegram chat. ## How messaging works - **Direct messages only.** The bot answers private chats. Messages in groups, supergroups, and broadcast channels are ignored. - **Customers start the conversation.** Telegram bots can't message a person first — a customer must open the bot and tap **Start** before it can reply. Put the `t.me` link where customers can find it. - **No messaging window.** Unlike WhatsApp, Instagram, or Facebook, Telegram has no reply deadline. You and the AI agent can reply to any conversation at any time. - **Media works both ways.** Photos, video, audio, voice notes, documents, and stickers arrive in the inbox (up to about 20 MB per file), and you can send images, video, audio, and documents back. - **The thread stays in sync.** Messages edited in Telegram update in the inbox, the bot shows a typing indicator while the AI composes, and if a customer blocks the bot the conversation is flagged so your team knows replies won't arrive. - Messages from other bots are ignored. You can connect more than one bot; each becomes its own channel. Asks also monitors each bot in the background and flags the channel if its token is revoked or the webhook drifts. ## Troubleshooting ### The token is rejected Copy the entire token from BotFather, including the numeric prefix and the colon. Send `/token` to BotFather to see it again. If you regenerated the token with `/revoke`, the old one no longer works — reconnect with the new token. ### The bot doesn't reply in a group Expected. The Telegram channel handles direct messages only. ### Can I message a customer who never wrote in? No. Telegram doesn't allow it — bots can only reply to people who have started a chat with them. ### What happens when I disconnect? Asks removes the bot's webhook and marks the channel disconnected. Existing conversations stay in your inbox. Reconnecting re-registers the webhook with the same bot. --- # Slack > Add Asks to a Slack workspace so your AI agent answers questions in DMs, mentions, and channels. The Slack channel installs an Asks bot into a Slack workspace. People DM the bot or @mention it in a channel; your AI agent answers in place, and every exchange shows up as a conversation in the [inbox](/inbox). **Availability** — this channel is rolling out and may not be enabled for your workspace yet. It will appear under **Channels** in your dashboard as soon as it's available. ## Prerequisites - A Slack workspace where you're allowed to install apps. If your Slack workspace requires admin approval for new apps, get that first. ## Connect Slack Go to [app.asks.app/channels/slack](https://app.asks.app/channels/slack) and click **Add to Slack**. You're sent to Slack's authorization screen. Pick the Slack workspace, review the requested permissions, and allow. Slack returns you to Asks with the channel connected. The bot answers DMs immediately. To use it in a channel, invite it there (`/invite @yourbot`) and @mention it in messages. **Verify it works** — in Slack, open a DM with the bot and ask it a question your [knowledge base](/knowledge-base) covers. The reply should arrive in Slack and the conversation should appear in your Asks inbox. ## How messaging works By default the bot is conservative: it replies to **direct messages** and **@mentions** only. You can widen this per connection on the channel's settings page: - **Slack integration active** — the master switch. When off, Slack messages are not received or replied to; the workspace stays connected, and turning the switch back on resumes from the next message. - **Reply to everyone in thread** — the bot keeps answering follow-ups in a thread it's already part of, without needing a fresh @mention. - **Reply to all messages in channel** — the bot answers every message in channels it's been invited to. Use with care; this can get noisy. In channels, replies post in the message's thread. In DMs, replies post directly in the conversation. There are no messaging-window restrictions on Slack. Files and screenshots shared with the bot are captured into the conversation. Asks also pulls the sender's Slack name, email, and avatar, so conversations in the inbox show who's asking. You can install Asks into more than one Slack workspace; each becomes its own channel. The bot ignores messages from other bots and its own posts, so it can't get into reply loops. It also skips edits, deletions, join notices, and other system messages — only plain messages written by people are handled. ## Troubleshooting ### The bot doesn't reply in a channel Check three things: the bot is invited to the channel, you @mentioned it (or **Reply to all messages in channel** is on), and **Slack integration active** is enabled on the channel's settings page. ### The bot replies to too much Turn off **Reply to all messages in channel**. With it off, the bot only responds when @mentioned (plus in threads, if **Reply to everyone in thread** is on). ### Someone uninstalled the app from Slack Asks detects the uninstall, marks the channel as needing attention, and emails your team an alert. Reconnect from [app.asks.app/channels/slack](https://app.asks.app/channels/slack) with **Add to Slack**. Past conversations stay in your inbox. --- # Discord > Connect a Discord bot so your AI agent answers in servers and DMs over a persistent gateway connection. The Discord channel connects a bot you create in the Discord Developer Portal. Asks holds a persistent gateway connection to Discord — there is no public webhook to expose — and answers where the bot is present. Conversations appear in the [inbox](/inbox) like any other channel. **Availability** — this channel is rolling out and may not be enabled for your workspace yet. It will appear under **Channels** in your dashboard as soon as it's available. ## Prerequisites - A Discord account with access to the [Discord Developer Portal](https://discord.com/developers/applications). - Permission to add bots to the server where you want the agent. ## Connect Discord In the [Developer Portal](https://discord.com/developers/applications), click **New Application** and name it — this name is what customers see. Open the **Bot** tab. Enable **Message Content Intent** — without it Discord withholds the text of ordinary server messages, and the channel will show an error shortly after connecting. Then click **Reset Token** and copy the bot token. Use the invite URL with your application ID (it's also shown on the channel page after you connect): ```text https://discord.com/oauth2/authorize?client_id=YOUR_APPLICATION_ID&scope=bot+applications.commands&permissions=309237730304 ``` The permission set covers messaging only. Go to [app.asks.app/channels/discord](https://app.asks.app/channels/discord), paste the bot token, and connect. Asks validates the token and opens the gateway connection. **Verify it works** — @mention the bot in a server channel (or DM it) with a question your [knowledge base](/knowledge-base) covers. The reply should arrive in Discord and the conversation should appear in your Asks inbox. ## How messaging works - **DMs** to the bot are always answered. - **Server channels** default to mention-only: the bot replies when it's @mentioned or when someone replies to one of its messages. On the channel's settings page, **Reply mode** can be switched to reply to every message in channels the bot can see, and **Reply in thread** controls whether answers post in threads. - **Attachments** sent to the bot (up to 25 MB each) are captured into the conversation. - There are no messaging-window restrictions on Discord. - Messages from other bots and webhooks are ignored, so the bot can't get into reply loops. System messages (joins, pins) are skipped. The channel page shows a live count of the servers the bot is in, along with the invite URL. You can connect more than one bot; each becomes its own channel. ## Troubleshooting ### The channel shows an error right after connecting Connecting only validates the token, so intent problems surface a moment later, when Discord closes the gateway connection. Usually the **Message Content Intent** is off (gateway close code 4014) — enable it on the application's **Bot** tab in the Developer Portal, then reconnect. An invalid or reset token surfaces the same way, with its own error message (close code 4004). ### The bot went offline If you reset the token in the Developer Portal, the old token stops working and the channel errors. Reconnect with the new token from [app.asks.app/channels/discord](https://app.asks.app/channels/discord). ### The bot ignores messages in a channel By default it only answers @mentions and replies to its own messages. Mention it directly, or set **Reply mode** to reply to every message. ### What happens when I disconnect? Asks closes the gateway connection and marks the channel disconnected. Conversations stay in your inbox; reconnecting reopens the connection. --- # Email > Turn your support address into an Asks channel with a single forwarding rule — no DNS changes required. The Email channel turns an address like `support@yourcompany.com` into a channel. You keep your address and your mail provider; you add one forwarding rule to a hidden Asks address, and inbound mail becomes conversations in the [inbox](/inbox). The AI agent can answer email too, and replies thread correctly in the customer's mail client. **Availability** — this channel is rolling out and may not be enabled for your workspace yet. It will appear under **Channels** in your dashboard as soon as it's available. ## Prerequisites - A support address you control (e.g. `support@yourcompany.com`). - Access to that mailbox's forwarding settings — Gmail, Google Workspace, Microsoft 365, or any provider that can auto-forward. ## Connect email Go to [app.asks.app/channels/email](https://app.asks.app/channels/email), enter your **Support email address** and an optional **Display name** (e.g. "Support"), and click **Connect email**. Asks mints a unique ingest address for this channel, in the form `inbound+@inbound.asks.app`. Copy it from the channel page — this is where your provider will forward mail. Customers never see it. The channel page shows instructions for Gmail, Google Workspace, Microsoft 365, and other providers. For Gmail: **Settings → See all settings → Forwarding and POP/IMAP → Add a forwarding address**, paste the hidden address, confirm, then choose **Forward a copy of incoming mail**. In Google Workspace, an admin can instead add a routing rule for the whole address. When you connect, Asks sends a probe email to your support address. Once your forwarding rule passes it back, the channel flips to **Verified**. Use **Check status** on the channel page to refresh. **Verify it works** — send an email to your support address from a personal account. It should appear as a conversation in your inbox, and the reply you send from Asks should land back in the personal account's thread. You can connect more than one support address — **Add another email address** on the channel page — and each becomes its own channel. ## How replies work - Replies from the Asks inbox carry a per-conversation reply address (`reply+@inbound.asks.app` as the Reply-To), so customer responses thread back into the same conversation. Standard mail threading headers are set as well. - Outbound mail is sent from Asks's sending domain with your display name as the sender name. Optionally, verify your own domain on the channel's **Branded Domain** tab (publish the DNS records shown, then click **Verify**) to send from your own address. - There are no messaging-window restrictions — reply whenever you like. - Attachments work both ways. Inbound attachments over 20 MB each are skipped while the message itself still arrives; large outbound files are delivered as download links. CC recipients on inbound mail are captured, and you can CC or BCC replies. - Automated mail is filtered to prevent loops: out-of-office and other auto-responders, bulk and mailing-list messages are dropped, and mail your provider flags as spam is stored without triggering an AI reply. - If a reply hard-bounces or the recipient marks it as spam, the message shows a failed badge in the inbox and the address is suppressed from further sends. ## Settings On the channel's settings tab: **Email channel active** (master switch — when off, mail is received but no replies are sent), **AI agent replies** (let the AI answer inbound email), **Auto-reply** (an automatic acknowledgement — it fires only on the first email of a new conversation, and never when the AI agent is about to answer), **Reply-from address**, and **Signature** (appended to every outbound reply). ## Troubleshooting ### The channel is stuck on "Awaiting forwarding verification" The forwarding rule isn't live yet. Gmail requires you to confirm the forwarding address before it forwards anything, and some providers delay new rules. Re-check the rule, then click **Check status**. ### Replies go out from an Asks address, not mine That's the default shared sender. Verify your own domain under **Branded Domain** to send from your address. ### A customer's reply opened a new conversation Replies thread by the reply token and message headers. If a customer starts a fresh email instead of replying, it becomes a new conversation by design. ### My out-of-office test didn't create a conversation Expected. Auto-generated mail — out-of-office replies, auto-responders, bulk sends — is dropped to prevent reply loops. Test with a normal, hand-written email instead. --- # Shopify > Connect your Shopify store so the agent answers with live products, policies, carts, and order status. Connecting Shopify makes your agent store-aware. It searches your live product catalog, quotes your actual policies, helps customers build a cart, and looks up order status — all against your store at answer time, so answers stay current without re-crawling anything. ## Connect your store There are two ways in: - **From onboarding** — paste your store URL into the [onboarding wizard](https://app.asks.app/onboarding) and Asks detects Shopify storefronts automatically, including on custom domains. Product, policy, and cart answers work from this detection alone, before you install anything. - **From the App Store** — install the Asks app from the Shopify App Store, then select **Connect to Asks Dashboard** in your Shopify admin. You're redirected to the dashboard to pick which workspace the store belongs to. This full connection is what unlocks the one-click widget install, order-status answers, and Shopify billing. Only workspace owners and admins can connect or disconnect a store. Manage the connection under **Integrations → Shopify** in the sidebar ([app.asks.app/integrations/shopify](https://app.asks.app/integrations/shopify)): connection status, store domain, last sync, a **Disconnect Store** action, and per-feature switches for **Product Search**, **Policy Search**, **Cart Management**, and **Pixel Tracking** — the pixel tracks customer browsing on your storefront so the agent has real-time context about what they're looking at. ## What the agent can do | Capability | What the agent does | | --- | --- | | Product search | Searches your live catalog and answers with product names, prices, links, images, and per-variant availability | | Store policies | Answers shipping, returns, refunds, privacy, and terms questions from your store's actual policies and FAQs | | Cart help | Views and edits the customer's cart — add, update, remove — and shares the checkout link. The agent never places the order itself | | Order status | Looks up payment status, fulfillment status, items, and tracking links for "where is my order" questions | Order-status answers require the app connection with order read access. They are deliberately guarded: an order number alone is never enough — the customer must also provide the matching email or phone number, and verification happens server-side before any detail is shared. A customer who gives only their email or phone gets their own recent orders back. For customers signed in to your storefront, the widget receives their identity from the theme embed, which smooths this verification along. The agent's Shopify access is read-and-assist only. It does not create, modify, cancel, or refund orders, edit inventory, or generate discount codes. ## Answers stay current Products and policies are fetched from your storefront live, at answer time — a price change or a new policy is reflected in the next answer, with no re-crawl. For the same reason, your catalog and policy pages are excluded from [knowledge base](/knowledge-base) website crawls, so they never spend your knowledge base articles; crawls keep only your narrative pages and blog. The knowledge base still matters for everything your storefront data doesn't cover — guides, sizing, brand story. ## Widget on your storefront With the store connected, the widget's [Deploy tab](https://app.asks.app/channels/widget/deploy) becomes a dedicated Shopify install: the usual surface switcher is replaced by a single Shopify card, since your storefront is the install target. Select **Add to theme** — it opens your theme editor with the Asks widget app embed ready to activate under **Theme settings → App embeds**. It works with all Shopify themes, and the card confirms with "Widget is on your Shopify storefront." once the embed is enabled, alongside **Open theme editor** and **View store** links. See [Website widget](/channels/widget) for how the Deploy tab works without a connected store. **Verify it works** — open your storefront, start a chat from the widget, and ask about a real product. The answer should quote the live price and link to the product page. ## Billing through Shopify When Asks is installed from the Shopify App Store, your subscription is billed through Shopify rather than by card. You pick a plan in the dashboard as usual, approve the charge in your Shopify admin, and manage the subscription from Shopify's billing settings — the dashboard's billing page points you there. Plans and pricing are the same either way; see [Billing](/workspace/billing). ## Troubleshooting ### Product answers work but order status doesn't Order status needs the App Store installation with order read access — storefront auto-detection alone can't see orders. Also check that the customer verified with the email or phone on the order. ### The agent stopped answering product questions Check the **Product Search** toggle on the [integration page](https://app.asks.app/integrations/shopify), and that the store still shows **Connected**. ### I'm asked to replace or move a store Connecting a store when the workspace already has one prompts "Replace connected store?" — confirming swaps the connection. Connecting a store that's attached to another of your workspaces prompts "Move store to this workspace?" — confirming transfers it, and the previous workspace loses its Shopify features. ### What happens when I disconnect? The agent loses product search, policies, cart management, and order lookups, and pixel tracking data is cleared. Conversations and your knowledge base are unaffected. --- # Inbox overview > One shared inbox for every conversation your AI agent and team handle, across all channels. The inbox at [https://app.asks.app/inbox](https://app.asks.app/inbox) is where every conversation lands — widget, chat page, WhatsApp, Instagram, Telegram, email, and the rest. It has three panes: the conversation list on the left, the transcript in the middle, and the customer panel on the right. Everything updates in realtime. New messages appear as they arrive, conversations move to the top of the list, and a "Reconnecting — live updates paused" banner appears if your connection drops. ## Finding conversations - **Search** — press `⌘K` (or `Ctrl K`) to jump to the search box. Search is full-text across conversations and message bodies; results show a highlighted snippet, and opening one scrolls the transcript to the matching message. - **Status filter** — All Status, Open, Needs human, Closed — plus **SLA at risk** and **SLA breached** when [SLA tracking](/inbox/tickets) is on. - **Channel filter** — All Channels, plus each channel your workspace has connected: Widget (always there), WhatsApp, Instagram, Facebook, Telegram, Slack, Discord, and Email. Channels you never connected don't clutter the list. - **Unreads** — a toggle that narrows the list to conversations with unread customer messages. Replies from the AI or your team don't count as unread. **Needs human** is an assignment state, not a status: the AI agent escalated the conversation to your team's queue and won't pick it back up. Configure when that happens in [Escalation](/ai-agent/escalation). ## The conversation list Each row shows the customer's name, channel, when the last message arrived, and a two-line preview. Rows also carry: - the ticket number (`#123`) - a **Closed** badge on closed conversations — open ones carry no status badge - priority, when it's anything other than Normal - the conversation's first tag - an amber **Needs human** badge on escalated conversations - an SLA countdown chip while a target is running — see [SLA policies](/inbox/tickets) Right-click a row and choose **Pin conversation** to keep it easy to find — pinned rows get a tinted background. Right-click again to unpin. ## The customer panel The right pane shows who you're talking to and everything Asks knows about them: | Section | What's in it | | --- | --- | | Header | Name, avatar, a **Profile** button, and a stats strip: Convos, Since, Last seen. | | Conversation | Ticket number and start date, channel, the **Assignee**, the assigned **Team**, SLA due dates when tracked, CSAT stars when the customer left a rating, and the ticket's status, priority, and tags. | | AI Agent | How the AI is handling it: resolution state, sentiment (Positive / Neutral / Negative / Angry — correctable), an **AI summary** you can generate or regenerate, detected language, editable topics, and **Data captured** through [data collection](/ai-agent/data-collection) or Actions. | | Customer | Email, phone, and channel handles (Instagram, Telegram, Discord, Facebook, Slack), plus widget visitor context — location, device, last page — and customer tags. | | Store | The customer's Shopify orders (track or open in Shopify) and their recent storefront browsing. | | Past conversations | The customer's previous tickets — click one to open it, or **View all** for the full profile. | | Notes | Team notes on the customer, editable in place. | | Activity | A timeline of contacts, profile updates, captured leads, customer notes, escalations and resolutions, and ratings. | The **Assignee** is one of: the **AI Agent**, a team member, **Needs human**, or **Unassigned**. Click it to reassign right from the panel — assign the AI, pick a teammate, or unassign. The transcript header has the fuller takeover and transfer controls — see [Takeover & collaboration](/inbox/handoff). The panel is yours to arrange. **Customize panel** collapses, hides, or reorders every section except Conversation, and the layout sticks per device. A header button hides the whole panel when you want the transcript full-width. ## Related - [Takeover & collaboration](/inbox/handoff) — replying, taking over from the AI, internal notes. - [Tickets, tags & SLAs](/inbox/tickets) — statuses, priorities, and response-time targets. - [Customers](/inbox/customers) — the full directory behind the customer panel. --- # Takeover & collaboration > Take over from the AI, work conversations with your team, and reply on any channel. The AI agent handles conversations until you step in. This page covers taking over, working with teammates, and what the reply composer can do on each channel. ## Taking over When a conversation is assigned to the AI, the transcript header shows **Take over from AI**. Click it and the conversation is yours: the AI stops replying and the composer unlocks. Escalated and unassigned conversations show a **Takeover** button instead — claiming works the same way. To route conversations elsewhere, open the **Transfer** menu in the header: - **Transfer to Agent** — hand the conversation to a teammate. - **Hand back to AI** — return it to the AI agent, which resumes answering. - **Unassign** — release it without an owner. Drafts survive transfers. If a teammate takes over while you're mid-reply, Asks preserves your draft and restores it if the conversation comes back to you. **Close** ends a conversation (with a confirmation dialog); **Reopen** brings a closed one back and assigns it to you. A closed conversation's composer is replaced by a **Handle conversation** button until someone picks it up. ## The reply composer - **Public reply vs internal note** — flip the **Internal** switch to write a note only your team can see. The composer turns amber so you can't mistake a note for a reply. Internal notes stay in the transcript, marked with a lock icon. - **Canned responses** — type `/` in the composer or click the canned-responses button to search your saved replies. Responses can include template variables such as `{{customer.name}}`, `{{ticket.number}}`, `{{agent.name}}`, `{{conversation.status}}`, and `{{workspace.name}}`, filled in when you insert them. A canned response can also carry actions — set the conversation's status or priority, or add tags — which apply only after your reply sends successfully. Manage them at [https://app.asks.app/settings/workspace/canned-responses](https://app.asks.app/settings/workspace/canned-responses); see [Tickets, tags & SLAs](/inbox/tickets). - **Attachments** — attach up to 10 files per message, 16 MB each. Images, video, audio, PDFs, and common document types are supported. Drag files onto the transcript ("Drop files to attach") or paste from your clipboard; media attachments open a preview where you can add a caption before sending. - **Sending** — `Enter` sends; `Shift Enter` adds a newline. ## Copilot Copilot is the AI assist menu in the composer — the wand button, or `⌘ J` (`Ctrl J`). It drafts; you decide. Nothing it writes is ever sent on its own. - **Suggest reply** — drafts a response grounded in your [knowledge base](/knowledge-base) and the conversation so far, and drops it into the composer for you to edit. - **Rewrite** — **Improve writing**, **Make friendlier**, **More formal**, or **Make shorter** rework whatever you've typed. - **Summarize conversation** — opens a summary of the whole thread in a dialog, with a copy button — useful before a transfer. `⌘ J` picks for you: with an empty composer it suggests a reply; with a draft in progress it polishes what's there. ## The transcript - **Pinned messages** — right-click any message and choose **Pin message**; pinned messages collect in a strip above the transcript so decisions and order numbers stay in reach. - **Media** — images and videos open in a conversation-wide lightbox gallery, PDFs preview in-app, and audio messages play inline. - **AI activity** — an "AI is typing…" indicator shows while the AI composes, and the thread marks when the AI escalated or resolved the conversation. ## Email conversations When the conversation came in over [email](/channels/email), the composer grows email fields: - a **Subject** line, pre-filled as `Re:` plus the original subject - a **Cc/Bcc** toggle that reveals Cc and Bcc inputs (comma-separated addresses) - inbound emails render their HTML bodies; click **Show quoted history** on a message to expand the full quoted thread ## WhatsApp and Meta conversations Messaging platforms limit when businesses can send free-form replies, and the composer surfaces this: - **WhatsApp** — a banner above the composer counts down the 24-hour customer service window. While it's open, free-form replies are allowed. Once it expires, the banner offers a **Send template** button to reopen the conversation with an approved template. A template button also lives in the composer toolbar at all times. See [WhatsApp](/channels/whatsapp). - **Instagram and Facebook** — the banner shows the standard 24-hour window, then a human-agent extension of up to 7 days during which your team (but not the AI) can still reply. After that, the customer has to write first. There is no template mechanism on Meta channels. - **Delivery status** — outbound messages show per-message status on every channel that reports it — WhatsApp, Instagram, Facebook, email, Telegram, Slack, and Discord. Failed sends show the error with a retry button. ## Related - [Escalation](/ai-agent/escalation) — when the AI hands conversations to your team. - [Tickets, tags & SLAs](/inbox/tickets) — statuses, canned responses, and response-time targets. --- # Tickets, tags & SLAs > How conversations and tickets relate, and how to organize your queue with tags, canned responses, and SLA policies. Every conversation in Asks has a lightweight ticket behind it. The conversation tracks the dialogue; the ticket tracks the work — status, priority, tags, and SLA deadlines. There is no separate tickets area: everything lives in the [inbox](/inbox), and a ticket link opens its conversation there. ## Conversations vs tickets Tickets are created automatically when a conversation starts. They're numbered sequentially per workspace and shown as `#123` on inbox rows and in the customer panel. | | Values | What it tracks | | --- | --- | --- | | Conversation status | Open, Closed | The state of the dialogue with the customer. | | Ticket status | Open, In progress, Closed | Your team's workflow on that conversation. | | Ticket priority | Low, Normal, High, Urgent | Urgency. Defaults to Normal. | **In progress** is set automatically when a teammate takes over; the status control itself offers Open and Closed. Edit ticket status, priority, and tags in the customer panel's Conversation section. Resolving or closing a conversation closes its ticket. ## How AI resolve and reopen work The AI agent can resolve conversations itself: when a customer confirms they're done, it sends a friendly closing message, closes the conversation — recorded as resolved — and closes the ticket. Conversations that go quiet are eventually closed as resolved automatically as well. Resolving is safe and reversible. If the customer writes again — minutes or weeks later — the conversation reopens automatically. Closed tickets are never reopened; instead a fresh ticket is created and linked to the previous one, so each round of work keeps its own record and SLA clock. ## Tags Tags are workspace-controlled labels for categorizing conversations. Manage them at [https://app.asks.app/settings/workspace/tags](https://app.asks.app/settings/workspace/tags): each tag has a name and an optional color, and can be deactivated when you retire it. In the inbox, you pick from this predefined list — tags can't be free-typed on a conversation, which keeps reporting clean. Separately, the AI assigns topics as it analyzes conversations; those appear in [analytics](/analytics/insights) and in the customer panel's AI Agent section, where you can edit them — they never mix into your tag list. ## SLA policies SLA policies set response-time targets for your team. Manage them at [https://app.asks.app/settings/workspace/sla-policies](https://app.asks.app/settings/workspace/sla-policies). Each policy defines: - **First response**, optional **Next response**, and **Resolution** targets, in minutes - an optional **priority** — a policy targets one priority (or every ticket when left blank), so create one policy per priority to give urgent tickets tighter targets - a **default policy** flag, used when no other policy matches - a **business hours only** toggle — pause the clock outside working hours, so a ticket that arrives Friday night isn't breached by Saturday morning. The hours, days, and closed dates themselves are configured once per workspace and follow your workspace timezone. - an **at-risk threshold** — the percentage of time remaining that flips a ticket to at risk (default 25%) Tickets are scored **on track**, **at risk**, or **breached**. When a ticket becomes at risk or breached, the assignee — or, when unassigned, the workspace owners and admins — gets an email alert (controlled by their notification preferences), and the `sla.at_risk` and `sla.breached` [webhooks](/api/webhooks) fire. SLA state shows throughout the inbox: countdown chips on list rows and in the transcript header, due dates in the customer panel, and the **SLA at risk** / **SLA breached** list filters. ## Canned responses Canned responses are reusable replies your team inserts with `/` in the inbox composer. Manage them at [https://app.asks.app/settings/workspace/canned-responses](https://app.asks.app/settings/workspace/canned-responses). Each has a **name**, the reply **content**, an optional **shortcut** (like `/refund`), and a **visibility** — personal, team, or workspace. A canned response can also carry attachments, staged with the reply when you insert it. Content supports `{{variable}}` tokens, filled in at insert time: | Root | Examples | | --- | --- | | `customer` | `{{customer.name}}`, `{{customer.email}}`, `{{customer.phone}}` | | `ticket` | `{{ticket.number}}`, `{{ticket.status}}`, `{{ticket.priority}}`, `{{ticket.tags}}` | | `conversation` | `{{conversation.status}}`, `{{conversation.priority}}` | | `agent` | `{{agent.name}}`, `{{agent.email}}` | | `workspace` | `{{workspace.name}}` | A canned response can also carry actions — set status, set priority, add tags — that run after the reply sends. Actions are currently configured through the [API](/api). ## Related - [Takeover & collaboration](/inbox/handoff) — using canned responses and notes in the composer. - [Plans & limits](/workspace/limits) — what each plan includes. --- # Customers > A directory of everyone who has contacted you, deduplicated across channels, with a full profile per customer. The customers directory at [https://app.asks.app/customers](https://app.asks.app/customers) lists everyone who has contacted you, across every channel. A person who messages you on WhatsApp and later emails you is one customer, not two: Asks matches identities by email, phone number, Shopify customer ID, and channel identifiers, and merges what it learns into a single record. ## The directory The page opens with four numbers: **Total customers**, **New this week**, **Identified** (customers with a known email or phone), and **Avg CSAT**. Below, the table shows each customer with their channels, location, conversation count, CSAT, and when they were last seen; a status dot marks whether they're Active, Inactive, or Archived. Search by name, email, or phone, and filter by status. Click a row to open the profile. ## The customer profile Each profile page brings together everything Asks knows about one person: - **Stats** — conversations, messages, CSAT, and overall sentiment. - **Conversations** — their full conversation history; click through to any of them in the inbox. - **Activity** — a timeline of contacts, profile updates, collected data, and notes. - **Details** — email, phone, first and last seen, and a Shopify link when their store account is connected. - **Channels** — which channels they've used, with conversation counts per channel. - **Context** — location, device, language, and the last page they were on when chatting through the widget. - **Store activity** — the customer's recent Shopify storefront browsing (last seven days), when your store's pixel is connected. - **Collected data** — answers the AI agent gathered during conversations, like order numbers or company size. This is populated by [data collection](/ai-agent/data-collection). - **Tags** and **Notes** — label the customer and leave notes for your team. Customer tags are free-typed; unlike conversation tags, they aren't limited to a workspace list. ## Editing a customer Click **Edit Customer** to update the contact fields: name, email, phone, status, and tags, plus an avatar. Contact details also fill in automatically — when the AI collects an email mid-conversation or a channel provides a profile, the customer record updates without your involvement. The customer panel in the [inbox](/inbox) is a compact view of this same record. Open the full profile from there with the **Profile** button. ## Related - [Data collection](/ai-agent/data-collection) — teach the AI what to ask for. - [Inbox overview](/inbox) — where these customers' conversations live. --- # Help center > Publish a public, searchable help center from your knowledge base — on the web and inside the chat widget. The help center is your public self-serve knowledge site, hosted at `https://app.asks.app/help/your-slug`. Customers browse collections of articles, search for answers, and leave feedback on whether an article helped — often without ever starting a conversation. **Availability** — the help center is rolling out and may not be enabled for your workspace yet. It will appear in your dashboard sidebar as soon as it's available. ## How it fits together Help center articles are your knowledge base's **public articles**. Any article with type "Public" and status "Published" in the [knowledge base](/knowledge-base/articles) can be added to a help center collection. There is one source of truth: editing the article in the knowledge base updates the help center (and the AI agent's knowledge) at the same time. The structure is collections and articles: - **Collections** group related articles. Each has a name, slug, description, an icon (an emoji works well), and a published toggle. Drag to reorder collections, and reorder articles within each collection. - **Articles** render with their title, description, body, and last-updated date, plus a was-this-helpful feedback prompt. - **Search** is built in — customers can search from the home page or any article. ## Managing your help center Manage everything from [https://app.asks.app/help-center](https://app.asks.app/help-center), which has two pages: On **Collections**, create collections and assign published public articles to them. A live preview panel shows the public site as you work; **View Help Center** opens it in a new tab (the button reads **Preview Help Center** while your help center isn't live yet). Articles themselves are written in the [knowledge base](/knowledge-base/articles). On **Settings**, set the **name**, the **slug** (which determines the public URL `/help/your-slug`), a **description**, and the **Live** toggle. Visitors get a 404 until Live is on — but your team can open a draft preview at any time. While Live is off, the site renders for workspace members with a banner: "Draft preview — only your team can see this." Turn on Live to publish it to everyone. Publish a collection only when it has articles in it. Empty collections make a help center feel abandoned; three collections with five solid articles each beat ten stubs. ## In the chat widget The help center also powers the widget's **Help** space. Enable it in your [widget settings](/channels/widget-customization): turn on the Help space, and optionally set its title and subtitle. Visitors can then browse and search your articles inside the widget — and start a conversation if they don't find what they need. ## Related - [Knowledge base articles](/knowledge-base/articles) — where help center articles are written. - [Widget customization](/channels/widget-customization) — enabling the Help space. --- # Analytics overview > See how your support is performing — volume, AI resolution, handoffs, and CSAT — with period-over-period deltas. Analytics at [https://app.asks.app/analytics](https://app.asks.app/analytics) shows how your support is performing at a glance. Pick a date range and every number compares itself to the previous period of the same length, so you see direction, not only totals. ## Date range The picker offers Today, Yesterday, Last 7 days, Last 28 days, Last 30 days, Last 90 days, This month, Last month, and a custom range. The default is Last 30 days. Delta badges on the KPI tiles compare against the immediately preceding period — for Last 30 days, that's the 30 days before it. How far back you can look depends on your plan: **90 days** on Starter, **365 days** on Business, and **unlimited** on Premium. See [Plans & limits](/workspace/limits). ## Overview KPIs - **Conversations** — total conversations in the period. - **Messages** — total messages, with the average per conversation. - **AI resolution rate** — the share of AI-handled conversations the agent resolved on its own. - **Transferred to human** — conversations the AI handed to your team. - **CSAT** — average rating out of 5, once [ratings](/analytics/ratings) come in. Below the tiles, the overview breaks the period down: conversations and messages per day, a resolution breakdown (confirmed resolved, assumed resolved, small talk, unresolved), busiest weekdays and hours, channels, languages, countries, devices, and conversation-length distributions. A **Conversation pages** table shows where widget conversations start on your site — each page URL with its conversation count and share; it appears once page data exists. ## Sub-pages The analytics sidebar leads to five deeper views: What customers keep talking about. How customers feel, over time. CSAT scores, reasons, and written feedback. The conversations that matter, surfaced automatically. How your human agents perform after handoff. Topics, Sentiment, AI Insights, and Team are available on the Business plan and above; Ratings is available on every plan. ## Knowledge gaps At the bottom of the AI Insights page, the **Knowledge Gaps** block lists questions the AI couldn't answer, grouped into topics overnight, with sample customer questions and a gap rate (unanswered questions divided by AI conversations — mature setups trend below 15%). Each gap comes with an **Add answer → retrain** action that drafts a knowledge base article for you and retrains the agent on it in one step. After you publish, a **View impact** trend shows unanswered volume before and after the article was added; gaps you'd rather not fix can be dismissed. See [Topics & AI insights](/analytics/insights). ## Related - [Topics & AI insights](/analytics/insights) — topics, sentiment, insights, and team performance. - [Ratings & CSAT](/analytics/ratings) — turning on end-of-chat ratings and reading the results. --- # Topics & AI insights > Automatic analysis of every conversation — what customers talk about, how they feel, and which conversations need your attention. Asks analyzes every conversation automatically. When a conversation closes, the AI reads it and extracts a summary, topics, sentiment, language, and anything noteworthy; conversations that never formally close are picked up once they've been idle for a day. Nothing here requires manual tagging — the pages below fill up as conversations happen, and update as new ones arrive. These four pages — Topics, Sentiment, AI Insights, and Team — are available on the Business plan and above. ## Topics Topics answer "what do customers keep talking about?" The page charts daily conversation volume for the six biggest topics, and the **All topics** table lists every topic with its volume and change versus the previous period. There are two kinds: - **Custom topics** — you define up to 12 active topics, each with a name and a plain-language description ("Shipping delays — customers asking where their order is"). The AI classifies every new conversation against them. New topics apply to new conversations, not retroactively. - **AI-detected topics** — themes the AI spots on its own, ranked by volume. Useful for finding topics you haven't defined yet. ## Sentiment Sentiment answers "how do customers feel?" Conversations are classified Positive, Neutral, Negative, or Angry. The page shows counts per class, sentiment over time, and a list of recent negative conversations you can open directly in the inbox. Angry is detected in realtime during the conversation — it's also what can trigger [escalation to a human](/ai-agent/escalation). ## AI Insights AI Insights is a feed of the conversations that matter, surfaced automatically. With no setup, the AI flags **feature requests**, **bug reports**, **competitor mentions**, **churn risks**, and **safety issues** as it analyzes conversations. Each item shows what was flagged, a quote from the conversation, and a link to it; mark items Reviewed or Dismissed as you work through the feed. Tabs filter the feed to **All**, **Alerts** (your custom alerts only), or **Flagged** (the built-in detectors). You can add your own detectors: **Manage alerts** lets you define up to 10 alerts in plain language — "customers threatening to cancel", "mentions of our enterprise plan" — and the AI matches every new conversation against them. Each alert shows its match count and last match, and has a switch to pause it without deleting it. The **Knowledge Gaps** block at the bottom of this page groups the questions the AI couldn't answer and lets you fix each one by publishing a drafted article — see the [analytics overview](/analytics). ## Team Team answers "how do humans perform after the AI hands off?" It shows: - **First response after handoff** — median and p90 time from handoff to the first human reply. Stats need at least 5 handoffs in the period; smaller samples are suppressed. - **SLA performance** — if your workspace uses [SLA policies](https://app.asks.app/settings/workspace/sla-policies), attainment per metric (First response, Next response, Resolution) with met versus breached counts, a live line of open conversations currently at risk or breached, and a per-policy attainment table. - **Agents** — per-agent messages, resolved conversations, and CSAT. - **AI health** — the agent's own reliability: success rate, failed turns, model failover, judge interventions, and reply latency. Counts reflect when conversations are analyzed, not when they happen: closed conversations are analyzed immediately, and open ones after about a day of inactivity. A busy conversation from this morning may not show up in Topics yet. ## Related - [Analytics overview](/analytics) — KPIs, charts, and plan retention. - [Ratings & CSAT](/analytics/ratings) — what customers say when you ask. --- # Ratings & CSAT > Ask customers to rate conversations when they wrap up, and see scores, reasons, and written feedback. Ratings measure how conversations actually went. When enabled, customers are asked to rate the conversation out of 5 as it wraps up — in the chat widget, on the chat page, and via star links in the resolved email. High ratings submit in one tap; low ratings ask why. Results live at [https://app.asks.app/analytics/ratings](https://app.asks.app/analytics/ratings), available on every plan. ## Turn it on Ratings are off by default. The switch lives on the Ratings page itself: the **Conversation rating** card at the top of [https://app.asks.app/analytics/ratings](https://app.asks.app/analytics/ratings). Flip it on and save — the setting applies to the whole workspace and covers all three surfaces at once: the chat widget, the chat page, and the resolved email. Only owners and admins can change it. Each customer is asked once per conversation. A 4- or 5-star rating submits immediately; a rating of 3 or below adds a follow-up step asking why, with an optional written comment. ## The Ratings page Four numbers up top: - **Average rating** — out of 5, with a delta versus the previous period. - **Ratings received** — how many customers rated. - **Response rate** — ratings received divided by customers asked (conversations resolved in the period). - **AI vs human** — average rating split by who handled the conversation. Below: the rating distribution from 5 stars down to 1, **Why customers were unhappy**, ratings over time, and a recent-feedback list with each rating's stars, reason, channel, and written comment — click through to the conversation in the inbox. ## Rating reasons When a customer leaves a rating of 3 or below, they can pick a reason: **Wrong answers**, **Didn't understand**, **Slow or stuck**, **Needed a human**, or **Other**. The reasons chart tells you where to act — "Wrong answers" points at [knowledge base](/knowledge-base) gaps, "Needed a human" at [escalation](/ai-agent/escalation) settings. Watch response rate alongside the average. A 4.8 from 2% of customers says less than a 4.3 from 30%. ## Ratings in the inbox A conversation's rating also appears where you work: the [inbox](/inbox) customer panel shows a **CSAT** row with the stars and the customer's written feedback, and each customer's average CSAT appears in the [customers directory](/inbox/customers) and on their profile. ## Related - [Widget customization](/channels/widget-customization) — everything else about how the widget looks and behaves. - [Analytics overview](/analytics) — CSAT alongside your other KPIs. --- # Team & roles > Invite teammates, understand what owners, admins, and members can do, and transfer ownership safely. Every workspace has one owner and any number of admins and members. Manage all of it at [https://app.asks.app/settings/workspace/team](https://app.asks.app/settings/workspace/team). ## Roles | Capability | Owner | Admin | Member | |---|---|---|---| | Inbox, knowledge base, agent, channels | Yes | Yes | Yes | | Invite members | Yes | Yes | No | | Billing, plan changes, add-ons | Yes | Yes | No | | SAML SSO and verified domains | Yes | Yes | No | | Change a member's role | Yes | No | No | | Transfer ownership | Yes | No | No | | Delete the workspace | Yes | No | No | A few rules keep the owner seat safe: - There is exactly one owner. The owner role can't be granted through an invite or a role change — only through [ownership transfer](#transfer-ownership). - Nobody can remove the owner, and the owner can't leave the workspace. Everyone else can leave at any time. - Admins can't remove themselves; ask the owner or another admin. Workspaces with [SAML SSO](/workspace/security) can also fill seats automatically: users signing in through the IdP join with the default role configured there — member or admin, never owner. ## Invite by email Open [Settings → Workspace → Team](https://app.asks.app/settings/workspace/team), enter the person's email, pick **Admin** or **Member**, and send. Email invites expire after 7 days. Outstanding invites appear in a **Pending invites** list on the same page, where you can resend or cancel each one. The email links to `app.asks.app/invite/`. If they don't have an Asks account yet, they create one first — the invite is tied to the email address it was sent to. ## Invite by link For onboarding several people at once, create a shareable invite link instead. The link always grants the **Member** role and has no use cap — anyone who opens it while it's valid can join, up to your seat limit. Links expire after 30 days, and you can regenerate or revoke a link at any time — anyone who already joined keeps their seat. Anyone with the link can join, so treat it like a password. Revoke the link once your team is in, and use email invites when someone needs the Admin role. ## Member limits Seats are counted per workspace: Starter includes 10 members, Business 25, and Premium 50. Each **extra member** add-on ($25/month) raises the limit by one. The full matrix is in [Plan limits](/workspace/limits); manage add-ons at [https://app.asks.app/subscription](https://app.asks.app/subscription). ## Transfer ownership Only the current owner can transfer ownership, and only to an existing member. On the team page, choose the member who should become the new owner. Asks emails the current owner a 6-digit confirmation code, valid for 15 minutes. Enter it to complete the transfer. The previous owner stays in the workspace as an admin. ## Multiple workspaces One account can belong to many workspaces — each with its own agent, team, plan, and billing. Switch between them with the workspace switcher in the sidebar, or pick **Create workspace** there to set up a new one through the onboarding wizard. To join another company's workspace, accept their email invite, open their invite link while signed in, or paste a link into **Join workspace** in the same switcher menu. --- # Plans & billing > What each plan includes, how AI credits work, and how to manage add-ons, top-ups, and invoices. Asks has three plans, billed monthly or yearly. Everything below is managed at [https://app.asks.app/subscription](https://app.asks.app/subscription) — your plan, payment method and invoices, and add-on quantities. ## Plans | | Starter | Business | Premium | |---|---|---|---| | Monthly | $39/mo | $149/mo | $349/mo | | Yearly (save 20%) | $372/yr ($31/mo) | $1,428/yr ($119/mo) | $3,348/yr ($279/mo) | | AI credits per month | 500 | 4,000 | 10,000 | **Starter** is the full product: the AI agent with training and instructions, every channel, the inbox, and the knowledge base. **Business** adds the developer and operations layer: [API access and webhooks](/api), SLA tracking, AI handoff summaries in the inbox, and advanced analytics with a longer history. **Premium** adds the top end: the Ultra model tier, custom widget theme and branding removal, [SAML SSO](/workspace/security), the [agent-as-API and MCP surface](/api/agent-chat), and AI evals. Every limit — members, knowledge base articles, actions, history — is in the [plan limits matrix](/workspace/limits). ## AI credits Credits are consumed only by messages the AI sends. Replies from your human agents are always free, and your allowance resets every month on your billing anniversary — on yearly plans too, so a yearly subscription still gets fresh credits each month. The cost per AI message depends on the model tier your agent runs: | Tier | Credits per AI message | Available on | |---|---|---| | Essential | 1 | All plans | | Pro | 4 | All plans | | Ultra | 8 | Premium | A 500-credit month is 500 AI replies on Essential, or 125 on Pro. Pick the tier under [AI agent settings](/ai-agent). ## Add-ons Recurring add-ons extend a plan without upgrading it. Adjust quantities on the subscription page; each unit is priced per month: | Add-on | Price | What one unit adds | |---|---|---| | Extra member | $25/mo | +1 team seat | | Extra AI credits | $35/mo | +1,000 credits per month | | Extra knowledge base articles | $19/mo | +100 articles | | Remove Asks branding | $99/mo | Removes "Powered by Asks" from the widget (included in Premium) | ## Top-ups and auto-recharge If you run out of credits mid-cycle, buy a one-time top-up at $40 per 1,000 credits — no plan change needed. Top-up credits don't expire with the cycle: they sit in a separate balance that rolls over and is only drawn after your monthly allowance is spent. Or turn on **auto-recharge**: set a threshold and a recharge amount, and when your balance falls below the threshold Asks automatically buys that many credits at the same $40 per 1,000 rate. If you reach for top-ups most months, the next plan tier is cheaper per credit. Top-ups and auto-recharge are available on card (Stripe) billing only. On Shopify billing, add the recurring **extra AI credits** add-on instead. Auto-recharge is the safety net for agents in production — the AI never goes silent because the credit balance hit zero. ## Plan changes and cancellation Upgrades — a higher tier, or switching monthly to yearly — apply immediately, with a prorated charge for the remainder of the current cycle. Downgrades — a lower tier, or yearly to monthly — are scheduled for the end of the current period, and you can undo a scheduled downgrade any time before it takes effect. You can also cancel the subscription yourself from the subscription page, on both card and Shopify billing. Cancellation always takes effect at the end of the period you've paid for — no refund for the remainder, and the workspace keeps full access until then. While a cancellation is scheduled, the subscription page shows a banner with a **Resume** button; resume before the period ends and nothing changes. ## Trial New workspaces get a 7-day free trial with the limits of the plan you pick. The trial starts when you complete checkout — you choose a plan and add a card, nothing is charged during the 7 days, and the subscription converts to paid automatically when the trial ends unless you cancel first. Cancel any time before then from the subscription page. The trial is offered once per user, not once per workspace. ## Where you're billed - **Card (Stripe)** — the default. Payment methods and invoices are handled through the Stripe billing portal, opened from the subscription page. - **Shopify billing** — if you installed Asks through the Shopify App Store, charges appear on your Shopify invoice instead, at the same prices. Plans and recurring add-ons work the same; one-time top-ups and auto-recharge are card-billing only. - **Invoiced (sales contract)** — some workspaces are billed directly under a contract. The plan and add-ons are set by the contract; contact us to change them. Plan changes, add-ons, and top-ups require the **owner** or **admin** role — see [Team & roles](/workspace/team). --- # Security > Account security with 2FA and session control, SAML SSO for the workspace, and data controls. Security in Asks lives at two levels: your personal account (password, 2FA, sessions) and the workspace (single sign-on, domains, deletion). Account settings apply to you everywhere; workspace settings apply to everyone in that workspace. ## Your account **Password.** Set or change your password under [Settings → Account → Security](https://app.asks.app/settings/account/security). If you signed up with Google you may not have a password yet — use "Forgot password?" on the sign-in page to set one. **Social sign-in.** You can sign in with Google. If Google is linked to your account, it appears on the same settings page. **Two-factor authentication.** Asks supports TOTP two-factor authentication with any authenticator app (Google Authenticator, 1Password, Authy). Enable it under Settings → Account → Security by scanning the QR code and confirming a code. Enabling 2FA also generates a set of one-time recovery codes — download them and store them somewhere safe; you can regenerate the set later with your password. Disabling 2FA requires your password and signs out your other sessions. **Active sessions.** [Settings → Account → Sessions](https://app.asks.app/settings/account/sessions) lists every device signed in to your account. Revoke any session you don't recognize — it signs that device out immediately — or use **Revoke all other sessions** to sign out everything except the device you're on. Turn on 2FA before inviting your team. Owners and admins with 2FA keep a guaranteed sign-in path even when SSO is enforced (see below). ## SAML SSO SAML SSO lets a workspace require sign-in through your identity provider. Asks implements SP-initiated SAML 2.0 and works with any compliant IdP — Okta, Microsoft Entra, Google Workspace, and others. Configure it at [Settings → Workspace → Security](https://app.asks.app/settings/workspace/security): Add Asks as a SAML application in your identity provider. The settings page shows the SP values (ACS URL and entity ID) to paste into the IdP. Provide the IdP entity ID, the SSO URL, and the signing certificate. You can also map the email and name attributes if your IdP uses non-standard names, and choose the default role new users get. Add your company domain and prove ownership with a DNS TXT record. Just-in-time provisioning is gated by verified domains: users signing in through your IdP with an email on a verified domain get a workspace seat automatically, with the default role you chose. With **Enforce SSO** on, members must sign in through the IdP — password sign-in is rejected for this workspace. Two safety valves apply when SSO is enforced. Owners and admins with 2FA enabled keep a break-glass password sign-in, and the sole owner is never locked out. Every break-glass sign-in and every SSO configuration change is recorded in an audit log and alerts the workspace owner and admins; contact support if you need a copy of the log. SSO settings can only be changed by owners and admins, and only the owner can delete the SSO connection — see [Team & roles](/workspace/team). ## Data controls **Workspace export.** The Danger Zone at [Settings → Workspace → Danger Zone](https://app.asks.app/settings/workspace/danger-zone) offers a workspace data export as JSON — take one before any destructive change. **Leaving a workspace.** Admins and members can leave a workspace from the same Danger Zone page. The owner can't leave — transfer ownership first ([Team & roles](/workspace/team)). **Workspace deletion.** The owner can delete a workspace from the Danger Zone. This permanently removes conversations, the knowledge base, channels, and settings for every member. Workspace deletion is irreversible. There is no grace period or restore — export anything you need first. **Email preferences.** Every non-essential email Asks sends carries an unsubscribe link, and you can manage notification categories under Settings → Account → Notifications. --- # Plan limits & quotas > The complete matrix — every plan limit, add-on price, and platform quota in one place. This page is the single reference for every number in Asks. Other docs link here instead of repeating figures. ## Plan matrix | | Starter | Business | Premium | |---|---|---|---| | Price (monthly) | $39/mo | $149/mo | $349/mo | | Price (yearly, save 20%) | $372/yr ($31/mo) | $1,428/yr ($119/mo) | $3,348/yr ($279/mo) | | AI credits per month | 500 | 4,000 | 10,000 | | Team members | 10 | 25 | 50 | | Knowledge Base Articles | 300 | 1,000 | 3,000 | | Website re-sync frequency | Weekly | Daily | Daily | | Custom actions | 5 | 15 | 50 | | Inbound MCP servers | 1 | 3 | 10 | | Analytics history | 90 days | 365 days | Unlimited | | Max AI model tier | Pro | Pro | Ultra | | API access and webhooks | — | Yes | Yes | | SLA tracking | — | Yes | Yes | | AI handoff summaries | — | Yes | Yes | | Advanced analytics (Topics, Sentiment, AI Insights, Team) | — | Yes | Yes | | Agent-as-API (exposed MCP) & AI evals | — | — | Yes | | Contextual chunk indexing | — | — | Yes | | SAML SSO | — | — | Yes | | Remove Asks branding & custom widget theme | — | — | Yes | Every knowledge base item — a written article, an uploaded file, or a crawled page — counts as one Knowledge Base Article — see [What counts as an article](/knowledge-base/limits). AI credits are spent per AI-sent message: Essential 1, Pro 4, Ultra 8; human replies are free ([details](/workspace/billing)). ## Add-ons Raise a limit without changing plans. Quantities are adjusted at [https://app.asks.app/subscription](https://app.asks.app/subscription). | Add-on | Price | Per unit | |---|---|---| | Extra member | $25/mo | +1 seat | | Extra AI credits | $35/mo | +1,000 credits/month | | Extra knowledge base articles | $19/mo | +100 articles | | Remove Asks branding | $99/mo | Widget branding off (included in Premium) | | One-time credit top-up | $40 | +1,000 credits, once | | Auto-recharge | $40 per charge | +1,000 credits, charged automatically when your balance falls below your threshold | Top-ups and auto-recharge are available on card (Stripe) billing only; top-up credits roll over and are spent after the monthly allowance. On Shopify billing, use the recurring extra-credits add-on instead — see [Plans & billing](/workspace/billing). ## Platform limits These apply on every plan: | Limit | Value | |---|---| | File upload size | 16 MB per file, 10 files per upload (widget uploads default to 10 MB per file, adjustable per widget) | | Knowledge base article size | 2 MB of extracted text per article | | Audio transcription | 25 MB per audio file | | WhatsApp media | 100 MB per file | | Website crawl | 2,000 pages per crawl, 10,000 pages per day (workspace-wide) | | Website crawl frequency | 30 crawl syncs per workspace per hour | | Website link map | 5,000 URLs per site | | API — read requests | 120/min per key | | API — write requests | 60/min per key | | API — agent chat | 20/min per key | An article that exceeds 2 MB of extracted text is rejected — split it into smaller documents. API limits are per key over a rolling 60-second window; a workspace-wide aggregate cap also applies across all keys — 360 read, 180 write, and 60 agent-chat requests per 60 seconds. See the [API reference](/api) for rate-limit headers and error codes. Running out of AI credits pauses AI replies only — your team can keep answering from the [inbox](/inbox), and a [top-up or auto-recharge](/workspace/billing) restores the agent immediately. --- # API overview > The Asks REST API — base URL, first request, pagination, idempotency, rate limits, and errors. The Asks REST API lets you talk to your AI agent, manage conversations, customers, tickets, and knowledge, and receive events by webhook — all scoped to your workspace. ``` https://api.asks.app/v1 ``` Requests and responses are JSON (UTF-8). The workspace is resolved from your API key, never from the URL. Every resource carries an `object` field (`"conversation"`, `"customer"`, …), and the version lives in the path (`/v1`). ## Quick start Go to [app.asks.app/integrations/api-keys](https://app.asks.app/integrations/api-keys) and select **Create API Key**. Give it a name, pick an environment and access level, and copy the key — it is shown only once. See [Authentication](/api/authentication). ```bash curl https://api.asks.app/v1/me \ -H "Authorization: Bearer ask_live_YOUR_KEY" ``` The response confirms the workspace, environment, and scopes your key resolves to. ## Authentication Pass your key as a Bearer token on every request: `Authorization: Bearer ask_live_…`. Keys carry scopes that limit what they can do — details in [Authentication](/api/authentication). ## Pagination List endpoints use cursor pagination and return a list envelope: ```json { "object": "list", "data": [], "has_more": true, "next_cursor": "cm9…" } ``` Page size, 1–100. Defaults to 20. The previous page's `next_cursor` (an item `id`). Pass it to fetch the next page while `has_more` is `true`. A few small lists (channels, tags, webhook endpoints, agent search) return everything at once with `has_more: false`. ## Idempotency Retry `POST` requests safely by sending an `Idempotency-Key` header with any unique string. The first 2xx response is cached for 24 hours; replays return the original response with an `Idempotent-Replayed: true` header. ```bash curl https://api.asks.app/v1/conversations \ -H "Authorization: Bearer ask_live_YOUR_KEY" \ -H "Idempotency-Key: 4f7a1c2e" \ -H "Content-Type: application/json" \ -d '{ "channel": "api" }' ``` ## Rate limits Limits apply per 60-second window, both per key and per workspace (across all of a workspace's keys): | Tier | Per key | Per workspace | Applies to | | --- | --- | --- | --- | | Read | 120 / min | 360 / min | `GET` requests | | Write | 60 / min | 180 / min | `POST`, `PATCH`, `DELETE` | | Chat | 20 / min | 60 / min | `POST /agent/messages` and `POST /mcp` | Every response carries `RateLimit-Limit`, `RateLimit-Remaining`, and `RateLimit-Reset`. A `429` adds a `Retry-After` header (seconds) — back off and retry after that. ## Errors Errors use standard HTTP status codes and one envelope: ```json { "success": false, "error": { "message": "Insufficient token scope. Required: conversations:write", "statusCode": 403, "code": "insufficient_scope", "details": { "required": ["conversations:write"] } } } ``` | Code | HTTP | Meaning | | --- | --- | --- | | `validation_error` | 400 | Invalid body or parameters. | | `unauthorized` | 401 | Missing, invalid, expired, or revoked key. | | `PLAN_LIMIT_REACHED` | 402 | The workspace has no active plan. | | `insufficient_scope` | 403 | The key lacks the required scope. | | `forbidden` | 403 | Action not allowed (for example, plan doesn't include API access). | | `PLAN_LIMIT_REACHED` | 403 | A plan limit is reached — out of AI credits, or a setting the plan doesn't include. | | `not_found` | 404 | Resource not found in this workspace. | | `conflict` | 409 | Conflicting state (agent disabled, duplicate tag, …). | | `rate_limited` | 429 | Rate limit exceeded — retry after `Retry-After`. | Schema validation failures (`400`) return the message and status code without a `code` field; `validation_error` appears on specific checks such as passing a `conversation_id` from another channel. Treat `code` as optional and match on the status first. ## OpenAPI spec A machine-readable description of every endpoint is available at [docs.asks.app/openapi.json](/openapi.json), or unauthenticated from the API itself: ```bash curl https://api.asks.app/v1/openapi.json ``` ## Where to go next API keys, environments, and scopes. Use your trained agent from your own code. Receive events with signed deliveries and retries. Expose your agent to Claude Code, Cursor, and other AI clients. Endpoints for conversations and messages. Endpoints for customer records. --- # Authentication > Authenticate to the Asks API with a workspace API key, and limit what each key can do with scopes. The API authenticates with a workspace API key, passed as a Bearer token. Every request is scoped to the key's workspace — a key can never read or write another workspace's data. **Plan requirement** — API keys and the REST API are available on the Business plan and above. If a workspace downgrades, its keys are kept but every request returns `403` until the plan is upgraded again. See [plans and limits](/workspace/limits). ## Create a key Go to [app.asks.app/integrations/api-keys](https://app.asks.app/integrations/api-keys) and select **Create API Key**. A key has: - **Key name** — a label for your own reference ("Production backend", "Zapier"). - **Environment** — Live or Test. Live keys start with `ask_live_`, test keys with `ask_test_`. - **Access** — **Read & write** (the `read` + `write` scopes) or **Read only** (the `read` scope). The full key is shown once, at creation. Copy it immediately — Asks stores only a SHA-256 hash, so it can never be shown again. **Test keys are not a sandbox.** The environment is a label for organizing your keys — a `ask_test_` key authenticates against the same workspace and the same production data as a `ask_live_` key. There is no isolated test dataset. Use test keys to separate integrations, not to experiment on throwaway data. ## Authorize a request Send the key in the `Authorization` header: ```bash curl https://api.asks.app/v1/me \ -H "Authorization: Bearer ask_live_YOUR_KEY" ``` `GET /v1/me` returns the workspace, environment, and scopes the key resolves to — useful as a connectivity check. ## Scopes Scopes limit what a key can do. The dashboard's access presets map to the coarse `read` and `write` grants; finer per-resource scopes exist for keys minted for a single purpose (the [MCP server page](https://app.asks.app/integrations/mcp), for example, mints keys with `agent:chat` + `agent:read`). | Scope | Grants | | --- | --- | | `*` | Everything. | | `read` | Every read action (any `…:read`). | | `write` | Every write action — and reads. | | `conversations:read` / `conversations:write` | Read vs. create and update conversations (also covers tags and canned responses). | | `messages:write` | Send messages into a conversation. | | `customers:read` / `customers:write` | Read vs. create and update customers. | | `channels:read` | List connected channels. | | `tickets:read` / `tickets:write` | Read tickets. The `tickets:write` scope is accepted on keys, but the ticket endpoints are read-only today. | | `knowledge_base:read` / `knowledge_base:write` | Read knowledge base articles. The `knowledge_base:write` scope is accepted on keys, but the knowledge base endpoints are read-only today. | | `agent:read` / `agent:write` | Read vs. update the agent configuration; `agent:read` also allows knowledge search. | | `agent:chat` | Send messages to the AI agent (`POST /agent/messages` and MCP tool calls). | | `webhooks:manage` | Manage webhook endpoints and read the event log. | How checks work: - `*` satisfies everything. - `read` satisfies any `…:read`; `write` satisfies any write-type action (`write`, `chat`, `manage`) and any read. - A resource wildcard such as `conversations:*` satisfies any action on that resource. A request missing the required scope returns `403` with code `insufficient_scope`; the missing scope is listed in `error.details.required`. ## Key lifecycle - **Revoke** a key at any time from the [API Keys page](https://app.asks.app/integrations/api-keys). Revoked keys fail immediately. - Keys can carry an optional **expiry**; an expired key behaves like a revoked one. - A missing, malformed, expired, or revoked key returns `401` with code `unauthorized`. Treat API keys like passwords. Never ship them in client-side code or commit them to source control. If a key leaks, revoke it and create a new one — the old key stops working the moment it is revoked. --- # Agent chat API > Send messages to your trained AI agent from your own code and get structured replies in one round-trip. `POST /v1/agent/messages` runs one synchronous turn against your AI agent — the same agent, knowledge base, and guardrails that answer on the widget and messaging channels. Use it to put your agent inside your own product: an in-app assistant, a support bot on a channel Asks doesn't cover, or an internal tool. Each call creates or continues a conversation on the **API channel**, so every exchange lands in your [inbox](/inbox) like any other conversation. ## Prerequisites - An API key with the `agent:chat` scope ([Authentication](/api/authentication)). - The agent must be **enabled** and **deployed on the API channel** — otherwise the endpoint returns `409`. Enabling the [MCP server](/api/mcp) turns the API channel on; you can also set it directly with `PATCH /v1/agent` and `"deployed_channels": { "api": true }` (scope `agent:write`). - AI credits. Each reply is charged by the agent's model tier: Essential 1, Pro 4, Ultra 8 credits. Out of credits returns `403` with code `PLAN_LIMIT_REACHED`; a workspace with no active plan returns `402` with the same code. Calls use the **chat rate tier**: 20 requests per minute per key, 60 per workspace. ## Send a message ```bash curl https://api.asks.app/v1/agent/messages \ -H "Authorization: Bearer ask_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": "What is your return policy?", "customer": { "email": "sam@example.com", "name": "Sam" } }' ``` The customer's message. Continue an existing API-channel conversation. Omit to start a new one. Passing a conversation from another channel returns `400`. Optional identifying info — `email`, `phone`, `name`, `external_id`. Used when starting a new conversation to create or match a [customer record](/inbox/customers), so API conversations dedupe against the same person on other channels. Optional attachments passed to the agent. ## The response ```json { "object": "agent_response", "conversation_id": "cmc1a2b3c…", "messages": ["We accept returns within 30 days of delivery…"], "quick_replies": ["Start a return", "Talk to a human"], "buttons": [{ "text": "Return portal", "url": "https://example.com/returns" }], "images": [], "sources": ["Returns & refunds policy"], "escalated": false, "credits_used": 1, "model_tier": "essential" } ``` - `messages` — the reply, as one or more message bubbles. Render them in order. - `quick_replies` and `buttons` — suggested follow-ups and link buttons, when the agent produced them. - `sources` — titles of the knowledge base content the reply cited. - `escalated` — `true` when the agent handed the conversation to a human. Stop expecting AI replies and route the customer to your human channel; the conversation is already flagged in the Asks inbox. Pair this with the `agent.escalated` [webhook](/api/webhooks) to notify your team. - `credits_used` — credits charged for this turn (0 when no billable reply was produced). `messages` can come back empty with `credits_used: 0` — for example when abuse protection blocks the conversation or a human takes it over mid-turn. Treat an empty array as "no reply", not as an error. ## Multi-turn conversations Pass the returned `conversation_id` on the next call and the agent keeps the full history: ```js const API = "https://api.asks.app/v1"; const headers = { Authorization: `Bearer ${process.env.ASKS_API_KEY}`, "Content-Type": "application/json", }; async function ask(message, conversationId) { const res = await fetch(`${API}/agent/messages`, { method: "POST", headers, body: JSON.stringify({ message, conversation_id: conversationId }), }); if (!res.ok) throw new Error(`Asks API ${res.status}`); return res.json(); } const first = await ask("Do you ship to Canada?"); const followUp = await ask("How much does it cost?", first.conversation_id); ``` Store the `conversation_id` against your own user/session so a returning user continues the same thread. **Verify it works** — after your first call, open the [inbox](https://app.asks.app/inbox) and filter by the API channel. Your message and the agent's reply appear as a normal conversation your team can take over. ## Errors to handle | Status | Meaning | | --- | --- | | `402` | No active plan on the workspace (code `PLAN_LIMIT_REACHED`). | | `403` | AI credit limit reached (code `PLAN_LIMIT_REACHED`), or the key lacks `agent:chat` (code `insufficient_scope`). | | `409` | Agent disabled, or the API channel not enabled. | | `429` | Chat rate limit hit — retry after `Retry-After` seconds. | Full request and response schemas are in the [Agent reference](/api/reference/agent). --- # Webhooks > Receive Asks events on your server in real time — event types, signed deliveries, verification, and retries. Webhooks push events to your server as they happen — a new message, an escalation, a captured lead — so you can react without polling. Deliveries are signed, retried on failure, and logged so you can inspect and replay them. ## Create an endpoint Create endpoints from the dashboard at [app.asks.app/integrations/webhooks](https://app.asks.app/integrations/webhooks), or via the API with the `webhooks:manage` scope: ```bash curl https://api.asks.app/v1/webhook_endpoints \ -H "Authorization: Bearer ask_live_YOUR_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/asks/webhooks", "enabled_events": ["message.created", "agent.escalated"] }' ``` The response includes the signing `secret` (`whsec_…`) exactly once — store it securely. The URL must be HTTPS and is validated against internal, loopback, and metadata addresses at registration and again at every delivery. ## Event types Subscribe to specific events, or `["*"]` for all: | Event | Fires when | | --- | --- | | `conversation.created` | A conversation is created. | | `conversation.updated` | A conversation changes (status, assignment, …). | | `conversation.closed` | A conversation is closed. | | `message.created` | A message is added to a conversation. | | `customer.created` | A customer is created. | | `customer.updated` | A customer is updated. | | `lead.captured` | The agent captures lead contact details. | | `ticket.created` | A ticket is created. | | `ticket.updated` | A ticket is updated. | | `ticket.resolved` | A ticket is resolved. | | `sla.at_risk` | A ticket approaches an SLA target. | | `sla.breached` | A ticket misses an SLA target. | | `agent.escalated` | The AI agent escalates to a human. | The `sla.*` events fire when [SLA tracking](/inbox/tickets) is enabled for the workspace. Their `data` is the ticket resource plus two extra fields: `sla_metric` (`first_response`, `next_response`, or `resolution`) and `sla_due_at` (the target that was at risk or missed). The dashboard's **Test** action (or `POST /webhook_endpoints/{id}/test`) sends a synthetic `ping` event. ## Deliveries Events arrive as a `POST` with a JSON envelope; `data` carries the event's payload (for `message.created`, a `message` object shaped like the REST resource): ```json { "id": "cmc1a2b3…", "type": "message.created", "created_at": "2026-07-06T12:00:00.000Z", "data": { "object": "message", "id": "cmc1a2b4…" } } ``` | Header | Value | | --- | --- | | `Asks-Signature` | `t=,v1=` — verify this (below). | | `Asks-Event-Id` | The event id (matches `id` in the body). | | `Asks-Event-Type` | The event type. | | `Asks-Webhook-Id` | The delivery id. | | `User-Agent` | `Asks-Webhooks/1.0` | Respond with any 2xx within 10 seconds to acknowledge. Anything else counts as a failure. ## Verify the signature The `Asks-Signature` header is Stripe-style: `t=,v1=`, where the HMAC is `HMAC-SHA256(secret, "{t}.{raw body}")`. Verify against the raw request body and reject deliveries older than 300 seconds: ```js import { createHmac, timingSafeEqual } from "node:crypto"; export function verifyAsksSignature(rawBody, header, secret, tolerance = 300) { const parts = Object.fromEntries( header.split(",").map((kv) => kv.split("=")), ); const t = Number(parts.t); if (!t || !parts.v1) return false; if (Math.abs(Date.now() / 1000 - t) > tolerance) return false; const expected = createHmac("sha256", secret) .update(`${t}.${rawBody}`) .digest("hex"); const a = Buffer.from(parts.v1, "hex"); const b = Buffer.from(expected, "hex"); return a.length === b.length && timingSafeEqual(a, b); } ``` Compute the HMAC over the exact raw body bytes. Parsing and re-serializing the JSON changes the bytes and breaks verification — read the raw body before your framework's JSON middleware touches it. ## Retries and auto-disable - Failed deliveries retry with exponential backoff starting at 1 minute — up to 8 attempts per delivery. - After 15 consecutive failed deliveries, the endpoint is automatically disabled and the workspace is notified by email. Re-enable it with `PATCH /webhook_endpoints/{id}` and `"status": "enabled"`, which also clears the failure counter. - Inspect attempts with `GET /webhook_endpoints/{id}/deliveries` and replay one with `POST /webhook_endpoints/{id}/deliveries/{deliveryId}/retry`. ## Roll the secret If a signing secret leaks, `POST /webhook_endpoints/{id}/roll_secret` generates a new one (returned once). The old secret stops working immediately, so update your verifier in the same deploy. ## Event log An event is recorded whenever at least one enabled endpoint subscribes to its type — whether or not the delivery succeeded. Events no endpoint listens for are not stored. Browse the log with `GET /events`. All management endpoints are documented in the [Webhook endpoints reference](/api/reference/webhook-endpoints). --- # MCP server > Expose your Asks agent as a remote MCP server so Claude Code, Cursor, and other AI clients can talk to it. The MCP server exposes your workspace's AI agent **as** a remote [MCP](https://modelcontextprotocol.io) server. Any MCP-capable client — Claude Code, Cursor, Codex, Claude Desktop — gets a tool that asks your agent questions and receives answers grounded in your knowledge base. This is the opposite direction of [MCP servers for your agent](/ai-agent/mcp-servers), where your Asks agent *consumes* external MCP servers as tools. This page is about other AI clients consuming *your* agent. ``` POST https://api.asks.app/v1/mcp ``` The endpoint speaks JSON-RPC 2.0 over plain JSON POST (no SSE stream or session to manage). Authentication is a Bearer API key; calling tools requires the `agent:chat` scope. ## Enable it Go to [app.asks.app/integrations/mcp](https://app.asks.app/integrations/mcp) and turn on the **MCP server**. You can rename the tool (snake_case, e.g. `ask_acme`), edit its description — that's what tells client LLMs when to call it — and optionally expose a read-only `search_knowledge` tool. The MCP server page generates an API key with the `agent:chat` and `agent:read` scopes and fills it into ready-to-copy snippets. For Claude Code: ```bash claude mcp add --transport http asks https://api.asks.app/v1/mcp \ --header "Authorization: Bearer ask_live_YOUR_KEY" ``` For Cursor, add to `.cursor/mcp.json`: ```json { "mcpServers": { "asks": { "url": "https://api.asks.app/v1/mcp", "headers": { "Authorization": "Bearer ask_live_YOUR_KEY" } } } } ``` Any generic MCP client works the same way: HTTP transport, URL `https://api.asks.app/v1/mcp`, and an `Authorization: Bearer …` header. Enabling the MCP server also deploys the agent on the API channel, so MCP conversations appear in your [inbox](/inbox) like any other channel. Disabling it turns the channel back off. ## The tools Asks your agent a question and returns the reply. The tool name and description are configurable on the MCP server page. Arguments: `message` (required), `conversation_id` (continue a previous exchange), and `response_format` (`concise` or `detailed`). Optional and off by default. Read-only semantic search over your published, AI-enabled knowledge base. Arguments: `query` (required) and `top_k` (1–20, default 8). Each `send_message` result includes a `conversation_id`; clients pass it back to keep multi-turn context, exactly like the [agent chat API](/api/agent-chat). ## Billing and limits Every `send_message` call is a normal agent turn: it consumes AI credits by the agent's model tier (Essential 1, Pro 4, Ultra 8 per reply) and creates a real conversation. The endpoint uses the chat rate tier — 20 requests per minute per key, 60 per workspace. ## Troubleshooting ### Tool calls "succeed" but contain an error message Failures inside a tool call follow MCP semantics: the JSON-RPC response succeeds, and the tool result carries `isError: true` with a plain-text explanation — for example "This assistant has reached its usage limit. Please try again later." when the workspace is out of AI credits, or "This assistant is currently unavailable." when the agent is disabled. Client LLMs read these as failed tool calls; your own integration should check `isError`, not just the HTTP status. ### The client connects but tool calls fail Tool calls need the `agent:chat` scope — a key without it gets JSON-RPC error `-32001` on `tools/call`. The handshake (`initialize`, `tools/list`) deliberately works with any valid key, so a connection test can pass while calls fail — use the key minted on the MCP server page. ### "MCP is not enabled for this workspace" The toggle at [app.asks.app/integrations/mcp](https://app.asks.app/integrations/mcp) is off, or the workspace no longer has a Premium plan (a downgrade turns the MCP server off automatically). ### GET requests return 405 Expected. The server is stateless JSON-RPC over POST only — there is no SSE stream. Point clients at the HTTP (not SSE) transport. --- # Widget developer guide > Embed script attributes, SPA installs, inline mode, sessions, domain allowlisting, and CSP for the Asks widget. This page covers the widget from the developer's side — the embed script, its attributes, and how it behaves inside your page. For setup and appearance, see [Website widget](/channels/widget) and [Widget customization](/channels/widget-customization). ## The embed script The dashboard's [Deploy tab](https://app.asks.app/channels/widget) generates your snippet: ```html ``` The script auto-initializes when it finds a `data-widget-key`, mounts a floating launcher in a Shadow DOM (your page's CSS can't leak in, and the widget's can't leak out), and talks to `api.asks.app`. The widget key is public by design — it identifies your widget, it doesn't authenticate anyone. ### Supported attributes Your widget key. Without it the script does nothing. Mounts the widget inline into the element with this id instead of a floating launcher. You control the container's size: ```html
``` Optional identity hints for logged-in visitors, forwarded when a conversation starts so the [customer record](/inbox/customers) matches. These are personalization hints only — the backend never treats them as authentication.
### Manual initialization The script also exposes a global for cases where you can't set attributes: ```js window.AsksWidget.init({ widgetKey: "YOUR_WIDGET_KEY", containerId: "asks-widget-embedded", // or targetSelector: ".chat-slot" identity: { email: "sam@example.com", name: "Sam" }, }); ``` ### Programmatic control The global also lets you open and close the floating panel from your own UI — a "Chat with us" link, a help menu item: ```js window.AsksWidget.open(); window.AsksWidget.close(); ``` Both are no-ops until the widget has mounted. `window.AsksWidget.version` returns the build identifier of the loaded script — include it when reporting a widget issue. ## Single-page apps Load the script once — in your root HTML or root layout — not per route. The widget survives client-side navigation on its own, and `init` is idempotent (re-running it clears and remounts rather than duplicating). In React or Next.js, do not mount and unmount the script with a component that re-renders per page. Don't render the snippet inside a component that unmounts on navigation. Each remount tears down the widget and the visitor's open conversation UI state with it. ## Sessions There is nothing to implement. When a visitor starts or resumes a conversation, the backend issues a signed session token bound to that workspace, conversation, and customer; the widget presents it on subsequent calls. Tampering with conversation or customer ids breaks the signature and the request is rejected. You never handle credentials, and the identity attributes above stay untrusted hints. ## Allowed domains Your widget configuration can carry a domain allowlist. When it's set, the backend checks the browser's `Origin`/`Referer` on widget traffic and rejects other domains with `403`. An entry matches its exact host and any subdomain (`example.com` covers `shop.example.com`). An empty list allows all domains. This deters embedding your widget key on someone else's site; it is a browser-origin check, not an authentication boundary — scripted abuse is separately contained by per-visitor rate limits. ## Content-Security-Policy If your site enforces a strict CSP, allow: | Directive | Value | Why | | --- | --- | --- | | `script-src` | `https://cdn.asks.app` | The `embed.js` bundle. | | `connect-src` | `https://api.asks.app wss://api.asks.app` | All widget API traffic, plus the live-messaging socket (`wss:`). Without the socket origin, replies still arrive but only on refresh — no live updates or typing indicators. | | `img-src` | `https://storage.googleapis.com` | Uploaded media: your workspace logo and launcher icon, agent avatars, and image attachments in conversations. | | `media-src` | `https://storage.googleapis.com` | Audio/video attachments in conversations. | | `font-src` | `data:` | The widget's font is inlined as a `data:` URI. | Styles live inside the widget's Shadow DOM, so no external stylesheet origin is needed. The font is registered through a small inline `