# Biel.ai docs
> Ask AI assistant for technical documentation
This file contains all documentation content in a single document following the llmstxt.org standard.
## View analytics
Click **Analytics** in the top navigation bar, then choose your **Project** and date range using **From** and **To**. Use the **Assistant**, **Search**, and **MCP** tabs to switch views. **Download report** opens the browser's print dialog, where you can save a PDF.

The **Analytics** view tracks project activity for a selected period, organized into Assistant, MCP, and Search tabs:
:::important
Only **Administrator**, **Maintainer**, or **Editor** roles can view analytics. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
## Assistant analytics {#chatbot-analytics}
* **Chats:** Total number of chat sessions.
* **Messages:** Total number of messages exchanged.
* **Unique users:** Distinct saved IP addresses, plus one user for each chat without a saved IP address.
* **Helpful** and **Not helpful:** Positive and negative feedback counts.
* **Satisfaction:** Percentage calculated from feedback, treating answers without feedback as positive.
* **Daily chat activity:** Graph showing chat activity over time.
* **Key pages driving conversations:** URLs where assistant conversations originated, with occurrence counts.
* **Top countries driving conversations:** Geographic distribution showing which countries users are chatting from.
* **Frequently asked questions** *(Professional, Business, and Enterprise plans)*: Most common questions asked to your assistant, grouped by semantic similarity. Analyzed daily.
* **Content gaps** *(Professional, Business, and Enterprise plans)*: Questions the assistant couldn't answer, grouped by semantic similarity. Analyzed daily.
## MCP analytics
Use this tab to understand how people use your documentation through connected MCP clients.
* **Chats via MCP:** Conversations created through **Ask**. **Find docs** and **Get docs** calls do not create chat sessions.
* **Messages via MCP:** Total **Ask**, **Find docs**, and **Get docs** calls. Each call counts once, including separate document pagination calls.
* **Unique users:** Users of **Ask** conversations, estimated from IP addresses. Retrieval calls do not contribute to this count.
* **Daily MCP activity:** Calls over time, separated by action.
* **Top MCP clients:** Editors and agents making MCP calls, with message counts and percentage shares. Client names are supplied by the clients themselves.
* **MCP actions:** Counts and shares for **Ask** (`biel_ai`), **Find docs** (`biel_search`), and **Get docs** (`biel_get_document`).
## Search analytics
* **Unique users:** Number of distinct users who performed searches.
* **Searches:** Total number of search queries.
* **Searches clicked:** Percentage of searches where users clicked on a result.
* **Click position:** Average rank of clicked results. Lower positions indicate that people find useful results nearer the top; it remains unavailable until clicks include a result rank.
* **Daily search activity:** Graph showing search activity over time.
* **Top search terms:** Most frequently searched terms with occurrence counts.
* **Searches without results:** Queries that returned no results. Use these to identify missing content or indexing gaps.
* **Searches without clicks:** Queries for which no result was opened. This list stays empty until every recorded click in the selected period includes its originating query, so Biel.ai does not report an incomplete list as a content issue.
## Troubleshooting
### FAQs or content gaps not showing
- **Plan requirement**: These features require a Professional, Business, or Enterprise plan.
- **Recently upgraded**: Wait 24 hours — the analysis runs daily.
- **No historical data**: Biel.ai only processes conversations that occur after your upgrade.
- **No conversations**: There were no assistant conversations to analyze from the previous day.
---
## Manage projects
Projects are the core organizational unit in Biel.ai where you configure your assistant's behavior, data sources, and security settings.
## View all projects
The **Projects** dashboard displays a list of all your projects.
Starter, Professional and Business include unlimited projects.
After your trial ends, choose a paid plan to reactivate your projects.

## Project detail page
From the **Projects** dashboard, click on a project name to open its detail page.

Here you can:
### Project information
- View the project ID
- Click **Snippet** to choose **AI Assistant** or **AI Search** and copy its installation code
- Access the project details using the **Settings** button
### Testing and monitoring
- Click **New chat** to open the assistant in a modal and test its answers
- Click **Refresh sources** to recrawl content and check the **Sources loading** or **Sources loaded** status
- Open **Logs** or **View logs** to troubleshoot indexing issues
- Open **Analytics** in the top navigation bar and select this project to review assistant, MCP, and search usage
- Click **Demo** to open the public demo page, when enabled
### Chat management
- View all chat entries and conversation history
- Filter conversations by date, sentiment, status, or metadata
- Find a conversation by entering any four or more characters from its ID; separate multiple IDs with commas
- Click on any chat entry to view its details
### Project actions
- Open **Settings** > **General**, then click **Delete project** at the bottom of the page
### Chat detail view
From the project detail page, click on any chat entry in the conversation list to view its full details.

This view shows detailed information about that specific conversation:
### User information
- Email address (if provided)
- Country and IP address
- Sentiment analysis of the conversation
### Conversation metadata
- URL where the chat originated
- Date and time of the conversation
- Full conversation history
### Actions
- **Download**: Export the chat in PDF, Excel, or CSV format
- **Delete**: Remove the chat entry
### Bulk actions
Select chat entries using the checkboxes, choose an option from **Select action**, and click **Apply**:
- **Archive selected**: Move conversations to the archived list while preserving their history. Set the **Status** filter to **Archived** to view them and use **Unarchive selected** to restore them.
- **Export selected to CSV**, **Export selected to XLS**, or **Export selected to PDF**: Download selected conversations.
- **Delete selected**: Remove selected conversations from the dashboard.
## Project settings
From the project detail page, click the **Settings** button (top right) to open the project settings. The settings layout has a left sidebar with seven groups; each group has its own page with one or more sections.

:::important
Only **Administrator** or **Maintainer** roles can manage project settings. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
The header on every settings page has a **Refresh sources** button:
- **Refresh sources**: Re-crawl all configured sources. After clicking, you're sent to the project's chat-list page where the loading status is visible.
To permanently delete a project and all its data, open **General** and use the **Delete project** section at the bottom of the page.
Each section card has its own **Save** button. On **Sources**, one Save button saves the configuration across all source types. File uploads are saved as soon as they finish. Click **Refresh sources** after changing sources to index the updated content.
### General
Basic project information:
- **Name**: Display name for the project.
- **Demo page**: Enable or disable the public demo page used for testing.
### Sources
Configure the data sources your assistant can answer from. Pick a source type from the chip selector at the top of the page; each chip reveals its own form.
- **URLs**: Index specific web pages.
- **Sitemaps**: Index entire websites using XML sitemaps. The Sitemaps tab also exposes URL-filter regex patterns to control which sitemap URLs get crawled.
- **GitHub**: Index GitHub repositories directly.
- **OpenAPI**: Import API specifications.
- **Confluence**: Connect a Confluence workspace.
- **Files**: Upload documents (PDF, CSV, Excel, Word, TXT, MD). Available once the project has been created.
For detailed configuration, see [Sources](https://docs.biel.ai/customization/data-sources/overview.md).
### Assistant {#chatbot}
Three sections, each with its own **Save** button:
- **Conversation** — the **Welcome message** and suggested questions shown when the chat opens. See [Initial message](https://docs.biel.ai/customization/initial-message.md) and [Suggested questions](https://docs.biel.ai/customization/suggested-questions.md).
- **AI model and instructions** — model selection, prompt configuration (default prompt or custom prompt), think mode, and web search. See [Models](https://docs.biel.ai/customization/models.md), [Custom prompt](https://docs.biel.ai/customization/custom-prompt.md), and [Reasoning modes](https://docs.biel.ai/customization/reasoning-modes.md).
- **Actions** — buttons the assistant can suggest when users need to take a next step. See [Actions](https://docs.biel.ai/customization/actions.md).
### Search
Two sections:
- **Search Filters** — filter chips that narrow search results by URL pattern. See [Search filters](https://docs.biel.ai/customization/search-filters.md).
- **Boost Rules** — rank specific URLs higher in search results. Available with the boost permission.
### MCP
Configure Model Context Protocol integration so AI coding assistants can talk to this project.
- **Enable MCP server**: Allow access through MCP.
- **MCP server name**: Custom name using letters, numbers, hyphens, and underscores, such as `acme-docs`. Leave blank to use the project name.
- **Metadata tag**: Tag used to identify conversations originating from MCP.
Available during your trial and on **Professional** and higher plans. See [MCP server](https://docs.biel.ai/integrations/mcp-server.md).
### Security & Privacy
Two sections:
- **Data Privacy** — toggle PII redaction and IP-address collection. See [Data privacy](https://docs.biel.ai/customization/data-privacy.md).
- **Access Control** — require authentication for API access (Business plan), and restrict which domains the assistant widget runs on.
### Integrations
Connect channel integrations from their cards. Discord and Slack have a **Connect** button that opens authorization. Microsoft Teams provides a downloadable manifest and a setup token. Each integration has its own setup controls.
- **Discord** — see [Discord](https://docs.biel.ai/integrations/discord.md).
- **Slack** — see [Slack](https://docs.biel.ai/integrations/slack.md).
- **Microsoft Teams** — see [Microsoft Teams](https://docs.biel.ai/integrations/microsoft-teams.md).
## Crawl scheduling and limits
Besides the manual **Refresh sources** trigger, Biel.ai recrawls some projects automatically, and applies limits so crawls stay within your plan and finish in a reasonable time.
### Automatic recrawl schedule
Biel.ai recrawls a project's sources automatically based on your team's plan:
| Plan | Automatic recrawl frequency |
| --- | --- |
| Business | Every week |
| Professional, Growth | Every 30 days |
| Other plans | None — trigger crawls manually with **Refresh sources** |
A custom team agreement can override the recrawl interval.
The interval is measured from the start of the last crawl, regardless of whether that crawl succeeded or failed. A project that has never been crawled waits for a manual first crawl, and a project with a crawl already running is skipped until that crawl finishes.
To recrawl a project outside this schedule, or on a plan without automatic recrawl, click **Refresh sources**.
### Source limit enforcement
Plans can limit the total number of indexed pages across all of a team's projects. The **Indexed pages** usage card on the subscription page shows the pages from the last crawl of each project, pooled across the team. If a crawl would exceed the allowance, Biel.ai stops indexing and emails the team. Reduce the content included in your sources or upgrade your plan, then click **Refresh sources** again.
### Crawl time limit
Biel.ai uses a 2-hour soft limit for crawls. Crawls that run significantly longer may be canceled.
If your crawls are consistently hitting this limit, [contact us](https://docs.biel.ai/support.md) for guidance
---
## Manage roles
Biel.ai supports four team roles: **Administrator**, **Maintainer**, **Editor**, and **Viewer**. Each role grants a different level of access to projects, chats, analytics, and team settings.

## Available roles
| Role | Access level |
|------|-------------|
| **Administrator** | Full access to all platform actions. |
| **Maintainer** | Manage projects, sources, chats, analytics, and other members' roles. Cannot save team details, change branding, or create API keys. |
| **Editor** | View all chats, access analytics, delete chats. Cannot create projects or edit settings. |
| **Viewer** | View own chats only. No analytics, settings, or project creation. |
## Assign a role when inviting a team member

The **Invite team members** form is visible to **Administrators** on the **Team** page. Enter the member's email, select a role, and click **Send invitation**. Permissions take effect after they accept. Pending invitations appear below the form.
## Change a team member's role
To update a team member's role:
1. In the [Biel.ai dashboard](https://app.biel.ai), click **Team** in the top navigation bar.
2. Locate the team member in the **Team members** list.
3. Click on their email address.
4. Select the new role from the dropdown and click **Update role**.
Administrators and Maintainers can update other members' roles. You cannot change your own role or demote the team's last administrator.
---
## Manage subscription
:::important
**Administrators** and **Maintainers** can view subscription usage, billing details, and available invoices. Only **Administrators** can manage extra usage or open **Manage billing**. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
Open **Team** in the top navigation bar and click **Manage subscription**. If you do not have an active subscription, the button reads **Upgrade now**.
For a self-service subscription, **Manage billing** lets you change or cancel your plan, view invoices, and update billing details. For a custom plan billed manually, select **Contact us** to request changes.
Your subscription page shows interactions and indexed pages shared across all projects. Extra usage does not change your plan's indexed-page limit or unlock additional models and features.
Starter, Professional and Business include unlimited projects.
When your trial ends without a paid plan, all projects become inactive until you subscribe.
## Extra usage
Keep your assistant running after your included interactions run out. With extra usage enabled, each additional billable interaction costs **$0.05**.
Chat messages, searches, MCP retrieval, and answer continuations share your team's interaction allowance. A question can use multiple interactions. See [Reasoning modes](https://docs.biel.ai/customization/reasoning-modes.md) and [Web search](https://docs.biel.ai/customization/web-search.md).
The **Interactions** card shows your usage, included allowance, extra interactions, and extra charges for the month. For example, **120 extra interactions cost $6.00**.
Bonus interactions are free and are used before paid extra usage. Unused bonus interactions expire at the start of the next UTC calendar month.
### Enable extra usage
Extra usage is **off by default for all subscribers**. An Administrator can enable it from the subscription page by authorizing charges to the saved payment method. Subscribing to a plan does not enable extra usage.
As an Administrator:
1. Open **Team** > **Manage subscription**.
2. In the **Interactions** card, click **Manage limits**.
3. Optionally enter a **Monthly extra usage limit (USD)**. Leave it blank for no monthly cap, or enter **0** to prevent paid extras.
4. Authorize charges to your saved payment method at **$0.05 per additional interaction** and click **Enable extra usage**.
Follow any card-verification instructions from your bank. This step does not charge you. Extra usage stays off until verification succeeds.
### Manage your monthly limit
Click **Manage limits** in the **Interactions** card to change your limit, then select **Save limit**. You do not need to accept the pricing again when changing an enabled limit.
There is **no monthly spending limit by default**. A positive limit controls extra spending across your team. Extra usage pauses when the limit cannot cover the next interaction. The spending period resets at the start of each UTC calendar month.
Set the limit to **0** and click **Save limit** to prevent new paid extras. Interactions already in progress can finish, and charges for usage already consumed remain due.
### Usage alerts
We email administrators at **80%** and **100%** of your monthly allowance, including any bonus interactions and the extra interactions your configured limit permits. If extra usage is off or your limit is **0**, alerts exclude paid extras. With extra usage enabled and no monthly cap, percentage alerts are not sent.
At **80%**, follow the email's link to review your plan or extra usage settings. With extra usage off, reaching **100%** does not automatically stop your assistant or create extra charges. Support can pause interactions above your allowance until the next UTC calendar month. Your included allowance renews then.
With extra usage enabled and a monthly spending limit set, new interactions pause when the limit cannot cover the next interaction. Increase your limit or wait until the next monthly allowance to resume, unless support has paused usage.
### Extra usage payments
Extra usage is billed monthly, or earlier when new extra usage charges reach **$25**. Balances below **$1** carry forward. The **$25** payment threshold is separate from your optional monthly spending limit.
If an extra usage payment fails, your assistant keeps running within your configured monthly limit. Unpaid charges remain due, and further usage may create additional payments. Open **Manage billing** to review your payment details.
Your subscription page lists outstanding extra usage payments. If your bank requires approval, select **Complete payment** for each payment and follow the bank's instructions. For other payment issues, select **Contact support**.
Support may pause paid extra usage while payments are outstanding. You can still use your included interactions, which renew each month. This pause stays in place across monthly resets. Contact support to resume paid extra usage.
---
## Manage team
Open **Team** in the top navigation bar to view team details and members.

* Change the team name.
* Change the team URL slug and timezone.
* Enable or disable **Remove 'Powered by Biel.ai' branding** (whitelabel).
* Invite new members.
* Remove members.
* Manage member roles and permissions.
* Manage your subscription.
Click **Save details** to apply changes to the **Details** card.
:::important
**Administrators** can save team details and change branding. The **Invite team members** form is visible to Administrators. **Administrators** and **Maintainers** can view the Team page and manage other members' roles. You cannot change your own role or remove the team's last administrator. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
---
## Whitelabel
White labeling lets you hide the "Powered by Biel.ai" text, link, and logo from the assistant widget to maintain a consistent brand experience.
:::important
This feature is available on the **Professional** plan and above. Only **Administrators** can save changes to white labeling. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
## Remove Biel.ai branding
1. In [app.biel.ai](https://app.biel.ai), go to **Team** in the top navigation bar.
2. Under **Details**, check **Remove 'Powered by Biel.ai' branding**.

3. Click **Save details**.
To confirm, open any page where you've embedded the Biel.ai widget. The Biel.ai logo should no longer appear.
---
## Administration
Administrative guides for managing Biel.ai.
Projects
Configure assistant settings, sources, and security
Analytics
Track usage, FAQs, and content gaps
Team
Manage members, invitations, and settings
Roles
Assign permissions to team members
Subscription
Billing, invoices, and plan usage
Whitelabel
Remove Biel.ai branding (Professional+)
---
## Add source
Add sources to a project. Supports files, URLs, sitemaps, hosted sites (ZIP), GitHub repositories, OpenAPI specifications, and Confluence spaces. All sources are indexed for search and chat.
Use `multipart/form-data` when uploading binary content (files or site ZIPs). Use `application/json` for everything else, including private GitHub repositories and private Confluence spaces that need credentials.
**Required permission:** `sources_create`
| Source type | Limits / notes |
|-------------|----------------|
| Files (PDF, MD, TXT, DOCX, PPTX, XLSX, CSV, YAML, JSON, RST, HTML, CSS, JS, XML) | 10 MB per file. `multipart/form-data` only |
| URLs | Must be publicly accessible |
| Sitemaps | Must end in `.xml` |
| Hosted sites (ZIP) | 250 MB per ZIP. `multipart/form-data` only. `site_name` is required |
| GitHub repositories | Public repos work via either content type. Private repos require a personal access token (JSON only) |
| OpenAPI specifications | JSON or YAML URL |
| Confluence spaces | Public spaces work via either content type. Private spaces require username + API token (JSON only) |
If a value is wrong, such as a sitemap URL that doesn't end in `.xml`, the request returns `400` with the errors listed by field name. If the values look right but the source still can't be added, such as an unsupported file type or a corrupt ZIP, the request returns `422` with a single `error` message explaining why.
Request
---
## Biel.ai API
Biel.ai is an AI-powered documentation assistant. It indexes your technical documentation and provides AI chat and search capabilities through widgets, MCP servers, and this REST API.
**Base URL:** `https://app.biel.ai`
> The API is available on **Business** and **Enterprise** plans. [Contact us](https://biel.ai/contact) to upgrade.
Chat, search, document retrieval, and answer continuations share your team's included interaction allowance. With [extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage) enabled, interactions beyond that allowance cost $0.05 each.
## Versioning
This document describes **API v2** (`/api/v2/`). If you have an existing v1 integration, see the [migration guide](https://docs.biel.ai/api/migrate-from-v1.md). v1 is scheduled for retirement in **January 2027**.
## Authorization & permissions
Biel.ai uses API key authentication with granular permissions.
- **Public projects**: Widget operations, including reading project configuration, searching, and sending messages, do not require an API key. Project, source, conversation, sync, analytics, and team management operations require one; check each endpoint.
- **Private projects**: All operations require an API key.
> Projects are public by default. Configure this in **Project settings**.
### Available permissions
| Permission | Description | Required For |
|------------|-------------|--------------|
| `projects_read` | Read project details | Getting project information, listing projects |
| `projects_create` | Create projects | Creating new projects |
| `projects_update` | Update project settings | Updating project configuration |
| `projects_delete` | Delete projects | Removing projects |
| `search` | Search and read indexed documents within projects | Searching project content, retrieving indexed document text, tracking search clicks, submitting message feedback |
| `sources_read` | View project sources | Listing project sources, getting source detail |
| `sources_create` | Upload sources | Adding files, URLs, sitemaps, repositories, OpenAPI specs, and Confluence spaces to projects |
| `sources_delete` | Delete sources | Removing sources from projects |
| `sync_create` | Trigger a sync or a single-page re-crawl | Re-crawling project sources, re-crawling one page |
| `sync_read` | Read sync status | Polling sync runs |
| `analytics_read` | Read project analytics | Reading chat, search, MCP, and insights analytics |
| `chats_create` | Create chats and send messages | Interacting with the AI chat |
| `chats_read` | Read conversations | Listing chats, retrieving a conversation |
| `chats_delete` | Delete conversations | Deleting a conversation |
| `teams_update` | Update team settings | Renaming a team, changing its slug, managing members |
> Keys created before v2 may carry legacy permission names (`project_read`, `project_search`, `project_sources_*`, `project_sync`, `chat_create`). They remain valid as aliases of their v2 equivalents, so you don't need to re-issue keys.
### Create an API key
1. In [app.biel.ai](https://app.biel.ai), click **Team** in the top navigation and scroll to **API keys**.
2. Click **Create API key** and enter a **Key name**.
3. Under **Project access**, select the intended project, or **All projects in this team** if the integration needs team-level operations. Select the required permissions.
4. Click **Create API Key** and copy the key. You won't be able to view it again.
### Using your API key
Include the key in the `Authorization` header:
```
Authorization: Api-Key
```
> Read-only keys (`projects_read`, `search`) can be exposed client-side. The `search` permission allows retrieval that consumes interactions. Restrict client-side keys to the intended project and permissions. Keys with write permissions should always be stored server-side.
API Key authentication using the format: `Api-Key `
Create your API key in Team Settings and assign the required permissions for your use case.
Security Scheme Type:
apiKey
Header parameter name:
Authorization
---
## Create a project
Create a new project. The slug is auto-generated. Configure the project with [`PATCH /api/v2/projects/{slug}/`](/api/update-project) after creation.
**Required permission:** `projects_create`
Request
---
## Delete a chat
Delete a conversation.
**Required permission:** `chats_delete`
Request
---
## Delete a project
Permanently delete a project, all its sources, indexed content, and chat history.
**Required permission:** `projects_delete`
Request
---
## Delete source
Remove a source and its indexed content from a project.
**Required permission:** `sources_delete`
Request
---
## Get chat analytics
Aggregate KPIs and daily activity for the AI chat over a date range. MCP-only conversations are excluded. For those, see [`GET /api/v2/projects/{slug}/analytics/mcp/`](/api/get-mcp-analytics).
**Required permission:** `analytics_read`
Request
---
## Get a chat
Retrieve a single conversation, including all of its messages ordered chronologically.
**Required permission:** `chats_read`
Request
---
## Get indexed document text
Read a document's complete indexed text without contacting the original
source site. First search with `source_types=all` and copy a result's
`document_id`. This returns text chunks in reading order with available
page or worksheet references, not a live page or an original binary file.
Responses contain up to `limit` chunks (default 20, maximum 20). When
`next_cursor` is not null, repeat the request using that cursor and the
same `document_id` and `limit`. Continue until `next_cursor` is null.
References and cursors are scoped to the project and its active index.
After an index refresh or a 404, search again for a current reference.
Existing project access, allowed-domain, trial and interaction-limit
checks apply. Each successful read counts as a search interaction and
does not create a chat. Older repository or OpenAPI indexes and older
uploaded files with backticks in their names may require a recrawl (409).
Each successful pagination request counts separately toward your team's interaction allowance.
With extra usage enabled, interactions beyond that allowance cost **$0.05** each. See
[extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage).
**Required permission:** `search` (private projects only).
Request
---
## Get advanced analytics insights
Surface conversation-driven insights for the project: top recurring questions (`faqs`) and content gaps where users asked something the assistant could not answer (`content_gaps`). Each item includes the related chats so you can drill into the original conversations.
**Plan-gated:** requires a plan that includes advanced analytics. When your team does not have access, the endpoint returns 200 with `{ "has_access": false }` and no payload. Treat that as a successful response rather than an error, and prompt the user to upgrade.
**Required permission:** `analytics_read`
Request
---
## Get MCP analytics
Aggregate KPIs and daily activity for conversations that originated from the MCP server.
**Required permission:** `analytics_read`
Request
---
## Get project details
Retrieve project settings, filters, and metadata.
**Required permission:** `projects_read` (private projects only).
Request
---
## Get search analytics
Aggregate KPIs and daily activity for the search experience over a date range. Counts come from [`GET /api/v2/projects/{slug}/search/`](/api/search-project) calls and [`POST /api/v2/projects/{slug}/search/click/`](/api/track-search-click) events.
**Required permission:** `analytics_read`
Request
---
## Get source detail
Retrieve detail for a single source.
**Required permission:** `sources_read`
Request
---
## Get a sync run
Retrieve a specific sync run by UUID. Returns the same shape as [`GET /api/v2/projects/{slug}/sync/`](/api/get-sync-status), but addresses a single run instead of the latest one. Use the `uuid` returned by [`POST /api/v2/projects/{slug}/sync/`](/api/sync-project).
**Required permission:** `sync_read`
Request
---
## Get latest sync status
Inspect the most recent sync run for the project, including overall status, the URLs that were processed, and the event log for the run.
Use this to:
- Detect when an automated [`POST /api/v2/projects/{slug}/sources/`](/api/add-source) followed by [`POST /api/v2/projects/{slug}/sync/`](/api/sync-project) flow has finished (`status` transitions from `running` to `success`/`error`/`warning`).
- Surface failures with actionable context. `events` includes per-URL warnings and errors.
For lightweight polling, prefer [`GET /api/v2/projects/{slug}/`](/api/get-project) and read its `last_sync` summary instead. It returns the same `status` and timestamps without the full event log.
Returns 404 when the project has never been synced.
**Required permission:** `sync_read`
Request
---
## Get a team
Retrieve the team identified by `slug`. The `slug` must match the team that owns the authenticating API key. Requesting any other team returns 404.
Any valid API key authenticates this call, no specific scope is required.
Request
---
## Invite a team member
Send an email invitation to join the team with the given role. The invitee becomes a member once they accept.
**Required permission:** `teams_update`
Request
---
## List chats
List chats for a project. Results are paginated and ordered by `created_at`.
**Required permission:** `chats_read`
Request
---
## List projects
List projects accessible to the API key. Results are paginated.
**Required permission:** `projects_read`
Request
---
## List sources
List all sources associated with a project. Results are paginated.
**Required permission:** `sources_read`
Request
---
## List team members
List the active members of the team. The `slug` must match the team that owns the authenticating API key.
Any valid API key authenticates this call, no specific scope is required.
Request
---
## List teams accessible to the API key
Return the team this API key belongs to. Because every API key is scoped to a single team, the returned array always contains exactly one entry.
Any valid API key authenticates this call, no specific scope is required.
---
## Migrate from API v1 to v2
API v2 replaces v1 as the documented, actively developed API.
v1 keeps working for existing integrations, but it no longer receives new features and is scheduled for
retirement in January 2027.
This guide lists the changes required to move a v1 integration to v2 before that date.
The [v1 reference](https://docs.biel.ai/api-v1/biel-ai-api.md) remains available until v1 is retired.
## What stays the same
- **Authentication.** Send `Authorization: Api-Key `, exactly as in v1. Existing API keys keep working; you don't need to re-issue them.
- **Base URL.** `https://app.biel.ai`.
- **Public project access.** Read operations on public projects still work without an API key.
- **Search.** Request parameters and the response shape of the search endpoint are unchanged; only the base path changes.
## Endpoint mapping
Every v1 endpoint has a direct v2 replacement.
| v1 endpoint | v2 endpoint |
| --- | --- |
| `POST /api/v1/chats/` | `POST /api/v2/projects/{slug}/chats/` |
| `GET /api/v1/projects/{slug}/` | `GET /api/v2/projects/{slug}/` |
| `GET /api/v1/projects/{slug}/search/` | `GET /api/v2/projects/{slug}/search/` |
| `GET /api/v1/projects/{slug}/sources/` | `GET /api/v2/projects/{slug}/sources/` |
| `POST /api/v1/projects/{slug}/sources/` | `POST /api/v2/projects/{slug}/sources/` |
| `DELETE /api/v1/projects/{slug}/sources/{source_uuid}/` | `DELETE /api/v2/projects/{slug}/sources/{source_uuid}/` |
| `POST /api/v1/projects/{slug}/sources/sync/` | `POST /api/v2/projects/{slug}/sync/` |
## Permission renames
v2 renames API key permissions to a consistent `_` scheme.
| v1 permission | v2 permission |
| --- | --- |
| `project_read` | `projects_read` |
| `project_search` | `search` |
| `project_sources_read` | `sources_read` |
| `project_sources_create` | `sources_create` |
| `project_sources_delete` | `sources_delete` |
| `project_sync` | `sync_create` |
| `chat_create` | `chats_create` |
Keys created before v2 may carry the legacy names.
They remain valid as aliases of their v2 equivalents, so no key rotation is needed.
## Breaking changes
### Send a message: project moved to the path
Sending a message now happens under the project, at [`POST /api/v2/projects/{slug}/chats/`](/api/send-message). Remove `project_slug` from the request body and put the slug in the URL instead. The rest of the body (`message`, `chat_uuid`, `url`, `email`, `think_mode`, `metadata`) and the 200/201 response are unchanged.
```bash title="v1"
curl -X POST https://app.biel.ai/api/v1/chats/ \
-H "Authorization: Api-Key $BIEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"project_slug": "my-project", "message": "How do I install the widget?"}'
```
```bash title="v2"
curl -X POST https://app.biel.ai/api/v2/projects/my-project/chats/ \
-H "Authorization: Api-Key $BIEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{"message": "How do I install the widget?"}'
```
### Get project: settings grouped under `config`
The v1 response returned all settings as top-level fields. In v2, feature settings are grouped under a `config` object, and the response adds identity and lifecycle fields (`slug`, `uuid`, `name`, `is_private`, `last_sync`, `created_at`, `updated_at`).
| v1 field | v2 field |
| --- | --- |
| `initial_message` | `config.chat.initial_message` |
| `suggested_questions` | `config.chat.suggested_questions` |
| `think_mode` | `config.chat.think_mode` |
| `filters` | `config.search.filters` |
| `mcp_enabled` | `config.mcp.enabled` |
| `mcp_server_name` | `config.mcp.server_name` |
| `mcp_metadata_tag` | `config.mcp.metadata_tag` |
| `whitelabel` | `whitelabel` (unchanged) |
`slug` is the project identifier used in API paths and the embeddable widget's `project` attribute. Copy it from the project's installation code. The separate `uuid` field identifies the project record.
### Get project: new settings with no v1 equivalent
The `config` object also carries settings that v1 did not have. A v1 integration that reads or writes project settings will encounter them for the first time in v2.
| v2 field | Description |
| --- | --- |
| `config.prompt.use_default` | Whether the built-in system prompt is used. |
| `config.prompt.version` | Version of the built-in assistant prompt. |
| `config.prompt.extend` | Custom instructions appended to the built-in prompt, or used on their own when `use_default` is `false`. |
| `config.chat.actions` | Call-to-action buttons the chat widget renders alongside answers. Each has `name`, `button_text`, and `url`. |
`config.chat.actions` is read-only. Read-only fields are returned in responses but rejected in requests, so an integration that reads a project and sends the whole object back to update it gets a validation error. Send only the fields you want to change.
### Sync: new path and asynchronous response
Sync is its own resource in v2, no longer nested under sources.
- The endpoint moves from `POST /api/v1/projects/{slug}/sources/sync/` to `POST /api/v2/projects/{slug}/sync/`.
- v2 returns `202 Accepted` with a sync run summary (`uuid`, `status`, timestamps) instead of the v1 `200` with a message. Poll [`GET /api/v2/projects/{slug}/sync/`](/api/get-sync-status) or read the project's `last_sync` field to track completion.
- Calling the endpoint while a sync is already running cancels the in-progress run and starts a fresh one. v1 returned `400` in that case. If your integration relied on the `400` to avoid duplicate syncs, check the sync status before triggering a new run.
### Add source: `201` status and typed sources
- Adding a source with [`POST /api/v2/projects/{slug}/sources/`](/api/add-source) returns `201 Created` instead of `200 OK`.
- The `sources` array in the response now contains typed source objects with a `uuid`, which you can poll through [`GET /api/v2/projects/{slug}/sources/{source_uuid}/`](/api/get-source) to track ingestion.
### List sources: paginated response and new source types
- v1 returned a bare JSON array of sources. v2 returns a paginated object, so read the sources from `results` instead of iterating the response directly.
| Field | Description |
| --- | --- |
| `count` | Total number of sources matching the query. |
| `next` | URL of the next page, or `null` on the last page. |
| `previous` | URL of the previous page, or `null` on the first page. |
| `results` | The sources on this page. |
Page size defaults to 20 and is capped at 100. Use the `limit` and `offset` query parameters to page through a project with more sources than that, or follow `next` until it is `null`.
- Source objects now include `created_at`, and the `type` enum adds `repository`, `openapi`, and `confluence`. If your integration validates `type` against a fixed list, update it.
## New in v2
These capabilities have no v1 equivalent:
- **Projects**: create, list, update, and delete projects.
- **Chats**: list chats, retrieve a full conversation, delete a conversation, and submit message feedback.
- **Sources**: add GitHub repositories, OpenAPI specifications, and Confluence spaces, including private ones via a JSON body with credentials.
- **Sync**: poll sync runs and read the event log for a run.
- **Analytics**: read aggregate chat, search, MCP, and insights metrics.
- **Teams**: manage the team that owns the API key, including members and invitations. The team response also reports subscription status and plan (`subscription`) and trial state (`trial`).
- **Search click tracking**: report result clicks to improve search analytics.
- **OpenAPI validation**: check an OpenAPI specification against the same checks Biel runs when it indexes it, so you can catch a spec that would fail to parse before the next sync.
See the [API v2 reference](https://docs.biel.ai/api/biel-ai-api.md) for details.
---
## Re-crawl a single page
Re-crawl one page and replace it in the project's search index, without touching the rest of the index. Returns immediately with `202`; the crawl runs in the background.
Use this when one page changed. To re-crawl every source in the project, use [`POST /api/v2/projects/{slug}/sync/`](/api/sync-project) instead.
## Requirements
- The URL must be on a host Biel.ai already crawls for this project: one of its embed domains, or the host of one of its URL or sitemap sources. Host matching is exact. A URL on any other host returns `400`, which keeps the endpoint from being used as a fetch-anything proxy.
- The project must have been indexed at least once. Run a full sync first, until then this endpoint returns `409`.
A page the index doesn't hold yet is added rather than replaced, and counts against your plan's page limit.
## Result reporting
The `202` means the page was accepted and queued, not that it was indexed. The background job is fire-and-forget: if the page can't be fetched, is excluded by the project's URL filters, or produces no indexable content, the run is dropped and no status is reported back. The next call, or the next full sync, is the retry. Use [`GET /api/v2/projects/{slug}/search/`](/api/search-project) to confirm the new content is in the index.
**Required permission:** `sync_create`
Request
---
## Remove a team member
Remove a member from the team. The `id` is the membership id returned by [`GET /api/v2/teams/{slug}/members/`](/api/list-team-members). The team's last admin cannot be removed.
**Required permission:** `teams_update`
Request
---
## Search project content
Keyword search across indexed project content by default. Set
`search_type=hybrid` to combine keyword matches and semantic similarity.
Source selection is independent: omit `source_types` for web-page snippets,
or supply a comma-separated list of `page`, `file`, `repository`, `openapi`
(or `all`) to retrieve indexed chunks from those source categories without
generating an answer. Document results include source type, full chunk text,
and available page or worksheet references. Non-URL sources have `url: null`.
Explicit source selections also include an opaque `document_id`. Pass it to
`GET /api/v2/projects/{slug}/documents/{document_id}/` to read the complete
indexed text, following continuation cursors for larger documents.
References belong to this project and its current index; search again
after an index refresh. This endpoint does not accept a `limit` parameter;
the MCP search tool limits the results it presents to its caller.
Hybrid retrieval requires an index with embeddings configured. Backend
failures return an error without an automatic keyword fallback.
Existing project access, domain, trial, and interaction-limit checks apply.
URL-based `filter_title` filters exclude results without a matching URL.
Each successful search counts as one interaction toward your team's allowance.
With extra usage enabled, interactions beyond that allowance cost **$0.05** each. See
[extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage).
**Required permission:** `search` (private projects only).
Request
---
## Send a message
Send a message and get an AI response. Returns 201 for new chats, 200 for existing ones.
To append to the latest output-capped assistant response, omit message and send chat_uuid and continue_message_id.
Continuation returns the same user_message_id and assistant messageId with the combined text.
Existing conversations require X-Chat-Restore-Token in addition to project access.
Chat and answer continuations consume interactions from your team's allowance.
With extra usage enabled, interactions beyond that allowance cost **$0.05** each. See
[extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage).
**Required permission:** `chats_create`
Request
---
## Submit feedback for a message
Record a like (`1`) or dislike (`0`) reaction on an AI-generated message.
**Auth:**
- Public projects: no API key required (the widget calls this endpoint client-side).
- Private projects: API key with `search` permission.
Request
---
## Start a sync
Re-crawl all project sources and update the search index. Returns immediately; the crawl runs in the background. Poll [`GET /api/v2/projects/{slug}/sync/`](/api/get-sync-status), or the `last_sync` field from [`GET /api/v2/projects/{slug}/`](/api/get-project), to track completion.
Calling this endpoint while a sync is already running cancels the in-progress run and starts a fresh one.
When only one page changed, use [`POST /api/v2/projects/{slug}/recrawl/`](/api/recrawl-url) instead. It replaces that page in the existing index and leaves the rest of the project untouched.
Rate limits may apply to this endpoint.
**Required permission:** `sync_create`
Request
---
## Track a search result click
Register a click on a search result for analytics. Call this after the user clicks on a result returned by [`GET /api/v2/projects/{slug}/search/`](/api/search-project).
Include the optional `query` and 1-based `position` when they are available to attribute the click to the result list that produced it. Clients that do not provide attribution can continue to send an empty body.
**Required permission:** `search` (private projects only).
Request
---
## Update a project
Update one or more project settings. Only the supplied fields are modified. Feature configuration is grouped under `config` (for example, `config.mcp.enabled`).
**Required permission:** `projects_update`
Request
---
## Update a team member
Change a member's role. The `id` is the membership id returned by [`GET /api/v2/teams/{slug}/members/`](/api/list-team-members).
**Required permission:** `teams_update`
Request
---
## Update team settings
Update the team's `name` and/or `slug`. The `slug` in the path must match the team that owns the authenticating API key. Include only the fields you want to change.
**Required permission:** `teams_update`
Request
---
## Validate an OpenAPI specification
Validate an OpenAPI specification against the same checks Biel runs when it indexes your spec, including `$ref` resolution. A `200` means the next sync will parse the spec; a `422` returns the validation errors it would fail with.
Designed for CI/CD: publish your spec, call this endpoint, and fail the pipeline on a non-2xx status. This catches changes that would break API indexing before Biel's next sync does.
Submit the spec either by `url` (Biel fetches it and resolves relative `$ref`s against it) or inline as `content` (JSON or YAML).
**Required permission:** none. Any valid API key works.
Request
---
## WebSocket API
The WebSocket API enables real-time, streaming chat with your Biel.ai project. Use it when you need token-by-token AI responses instead of waiting for the full response via the [REST API](https://docs.biel.ai/api/biel-ai-api.md).
Chat and answer continuations consume interactions from your team's allowance. With [extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage) enabled, interactions beyond that allowance cost $0.05 each.
**Endpoint:** `wss://app.biel.ai/ws/messages/{projectId}/`
To continue an existing chat: `wss://app.biel.ai/ws/messages/chat/{chatId}/`
## Connect
Open a WebSocket connection to:
```
wss://app.biel.ai/ws/messages/{projectId}/
```
Replace `{projectId}` with your project slug (e.g., `jfvzioa17q`).
## Send a message
Send a JSON message to the WebSocket:
```json
{
"projectId": "your-project-slug",
"from": "user",
"message": "How do I authenticate?",
"url": "https://docs.example.com/auth",
"email": "user@example.com"
}
```
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `projectId` | string | No | Project slug for client bookkeeping; the connection path selects the project. |
| `from` | string | No | Client message label; use `"user"` when included. |
| `message` | string | Yes | The user's message (Markdown supported). |
| `chatId` | string | No | Chat session UUID. Omit for the first message — included in the AI response. |
| `url` | string | No | Page URL where the chat is happening. Used for domain validation. |
| `email` | string | No | Email or ID for conversation tracking. |
| `apiKey` | string | No | API key with `chat_create` permission. Required for private projects. |
| `thinkMode` | boolean | No | Enable reasoning mode for deeper analysis. |
| `retrievalMode` | string | No | Regular-mode retrieval: `auto` or `instant`. Omit for the existing default. Unsupported values are ignored; `thinkMode: true` takes precedence. See [Reasoning modes](https://docs.biel.ai/customization/reasoning-modes.md). |
| `capabilities` | array of strings | No | Include `"activity.v1"` together with a valid `requestId` to receive operational progress updates. |
| `requestId` | string | No | Unique caller-generated identifier for this turn: 1–80 characters from `A-Z`, `a-z`, `0-9`, `.`, `_`, `:`, or `-`. Negotiating servers echo it on answer and status frames. |
| `restoreToken` | string | No | Opaque conversation restore token returned by the server. Retain it with the chat ID and send it on subsequent turns. A chat ID alone is not authorization. |
| `metadata` | string | No | Tag to identify the conversation source. |
## Receive a response
The server sends JSON messages back. Partial messages stream token-by-token; the final message includes sources.
```json
{
"projectId": "your-project-slug",
"chatId": "550e8400-e29b-41d4-a716-446655440000",
"from": "ai",
"messageId": "msg-uuid",
"message": "To authenticate, use the...",
"timestamp": "2026-01-15T10:30:00Z",
"isPartial": false,
"sources": [
{
"title": "Authentication guide",
"url": "https://docs.example.com/auth"
}
]
}
```
| Field | Type | Description |
|-------|------|-------------|
| `projectId` | string | Project slug. |
| `chatId` | string | Chat session UUID. Use this in subsequent messages to continue the conversation. |
| `from` | string | Always `"ai"`. |
| `messageId` | string | Message UUID. |
| `message` | string | AI response content (Markdown). |
| `timestamp` | string | ISO 8601 timestamp. |
| `isPartial` | boolean | `true` for streaming tokens, `false` for the final message. |
| `sources` | array | Source references (only in final message). Each has `title` and `url`. |
| `incomplete` | boolean | `true` if generation could not complete, including output limits or interruption. Only in the final message. |
| `stopReason` | string | Provider stop reason or a classified recovery reason on the final frame. |
| `continuationCount` | integer | Number of automatic continuations for this generation request. |
| `continuationAvailable` | boolean | Whether the latest capped response can be continued through the REST API. |
| `requestId` | string | Turn identifier, when progress was negotiated. May be absent on older servers. |
| `restoreToken` | string | Opaque conversation restore token. Store it with `chatId`; older servers may omit it. |
| `interrupted` | boolean | Optional negotiated marker that generation was interrupted. Keep any useful draft and offer an explicit retry. |
| `isError` | boolean | Optional negotiated error marker. Do not treat an error message as a replacement for an existing draft. |
| `retryable` | boolean | Optional negotiated indication that retry is appropriate. Wait for the connection to recover before sending a retry. |
## Receive progress updates
To request progress, include both the capability and a new turn identifier in your message:
```json
{
"projectId": "your-project-slug",
"from": "user",
"message": "How do I authenticate?",
"capabilities": ["activity.v1"],
"requestId": "turn-1",
"retrievalMode": "auto"
}
```
A supporting server sends status frames alongside the answer stream:
```json
{
"type": "status",
"version": 1,
"requestId": "turn-1",
"sequence": 2,
"stage": "searching_docs",
"state": "started",
"detail": { "searchRound": 1 }
}
```
| Field | Description |
|-------|-------------|
| `type`, `version` | `"status"` and `1` identify this progress extension. |
| `requestId` | Identifies the active turn. |
| `sequence` | Increases within each turn, starting at 1. |
| `stage` | `contextualizing`, `searching_docs`, `reviewing_results`, `preparing_docs`, `searching_web`, `writing_answer`, `checking_sources`, `completed`, `failed`, or `interrupted`. |
| `state` | `started`, `completed`, or `failed`. |
| `detail` | Optional details within the object: `searchRound`, `documentCount`, `reason`, or `retryable`. `reason` can be `generation_failed`, `stream_interrupted`, or `disconnected`. |
Status frames describe actual operations, rather than private model reasoning. They have no `from` or `message` field: handle them separately from chat messages. Only accept supported frames for the active turn and ignore stale or duplicate sequence numbers. Not every operation appears in every answer, and a final `completed` status can arrive after the final answer.
Hide successful progress when the final answer arrives. Preserve a useful interrupted draft and let the user choose whether to retry; do not automatically replay requests. The widget follows this behavior and offers [spinner or loading dots](https://docs.biel.ai/customization/chat-progress.md) as a display option.
### Compatibility
Clients that omit progress negotiation retain the existing answer stream, without status frames. New clients must also accept answers from older servers that omit `requestId`, `restoreToken`, and progress updates. Keep a generic loading indicator in that case. Updating the backend alone does not change an older installed widget's interface.
## Authentication
The WebSocket API uses the same authentication model as the [REST API](https://docs.biel.ai/api/biel-ai-api.md):
- **Public projects** — No API key required. Domain restrictions still apply.
- **Private projects** — Include `apiKey` in the first message payload with `chat_create` permission.
Domain validation is checked on every message using the `url` field. If your project has allowed domains configured, the `url` must match one of them.
## Rate limiting
| Limit | Threshold | Penalty |
|-------|-----------|---------|
| Per chat session | 15 messages/minute | Rejected until window resets |
| Per IP address | 100 messages/minute | IP blocked for 1 hour |
| Burst detection | 10 messages within a 30-second window | Rejected while the burst threshold is met |
## Continue a capped answer
Automatic continuation happens on the backend for both REST and WebSocket clients. For a manual continuation, use the [REST message endpoint](https://docs.biel.ai/api/send-message.md) with `chat_uuid` and `continue_message_id`, omit `message`, and send the stored restore token in `X-Chat-Restore-Token`. The response contains the original assistant message UUID and its complete text including the appended suffix. Replace that message in your UI; do not append a new user or assistant turn.
---
## Accessibility
Both the chat and search widgets ship with keyboard and screen reader support enabled by default. This page describes that behavior and the properties you can use to adjust it.
## Keyboard support
### Chat modal
| Key | Action |
| --- | --- |
| Tab | Moves to the next control. While the modal is open, focus stays inside it. |
| Shift + Tab | Moves to the previous control, also confined to the modal. |
| Esc | Closes the modal. |
| Enter | Sends the message when the input has focus. |
### Search modal
| Key | Action |
| --- | --- |
| Tab and Shift + Tab | Move between controls, confined to the modal. |
| ↓ and ↑ | Move through the search results. |
| Enter | Opens the selected result. |
| Ctrl or Cmd + Enter | Opens the selected result in a new tab. |
| Esc | Closes the modal. |
Set `hide-navigation-buttons` to `true` to hide the on-screen hints for these keys. The shortcuts keep working.
## Focus behavior
When either modal opens, focus moves to its input unless `disable-autofocus` is enabled. Focus stays inside the modal for as long as it is open.
When the modal closes, focus returns to the element that opened it, usually the chat or search button, so keyboard users resume where they left off.
In [embedded mode](https://docs.biel.ai/customization/embedded-mode.md), the assistant is part of the page rather than an overlay. It does not trap focus or respond to Esc, and it is exposed as a labelled region rather than a dialog, since there is no dialog to open or close.
## Disabling Esc to close
If your site already binds Esc to something else, set `escape-close` to `false` on `` or `` directly. The launcher components `` and `` do not expose this property:
```html
```
With `escape-close` set to `false`, the close button and clicking outside the modal continue to work.
## Closing by clicking outside
Both modals close when you click outside them. On `` or `` directly, set `click-outside-close` to `false` to require the close button or Esc instead:
```html
```
Clicks that begin inside the widget are ignored, so selecting text in an answer and releasing the mouse past the edge does not close it.
In embedded mode the assistant is inline content, so it ignores clicks outside as well as Esc.
## Screen reader labels
Both modals expose themselves as dialogs, except the assistant in embedded mode, which is a labelled region. The chat modal is named by its `header-title` and the search modal by its `search-placeholder`, so setting those to something meaningful for your site also improves what screen readers announce:
```html
Ask AI
```
The controls are named by their tooltip text, which you can translate with `close-button-text`, `expand-button-text`, `collapse-button-text`, `refresh-button-text`, `settings-button-text`, and `connect-button-text`. See [Widget customization](https://docs.biel.ai/customization/layout.md) for the full list.
Setting `hide-tooltips` to `true` hides the tooltips visually but keeps these accessible names, so screen reader users are unaffected.
## Color contrast
If you override the widget colors, check the resulting combinations against the [WCAG contrast guidelines](https://www.w3.org/WAI/WCAG21/quickref/#contrast-minimum), particularly for placeholder text and source links, which sit on lighter backgrounds than the rest of the modal. See [Styles](https://docs.biel.ai/customization/styles.md) for the available custom properties.
---
## Actions
Actions are clickable buttons that Biel.ai can add to assistant answers. Each action has a trigger that describes when the button should appear.
For example, you can show a **Contact support** button when a user reports a problem, or a **Book a call** button when they ask about enterprise pricing.
Unlike suggested questions, which appear when the chat opens, actions only appear when their trigger matches the user's message.
## Common uses
Actions give users a clear next step without making them leave the conversation first.
| Button | Appears when |
| --- | --- |
| Open a support ticket | A user reports a problem the assistant cannot resolve. |
| Book a call | A user asks about pricing or enterprise plans. |
| Start a trial | A user asks how to get started. |
## How actions work
1. You create an action with a name, trigger, button label, and URL.
2. When a user sends a message, Biel.ai checks the message against each action's trigger.
3. If a trigger matches, Biel.ai adds the corresponding button to the answer.
4. An answer can contain no actions, one action, or several actions.
5. In the web widget, the action appears as a button. In integrations such as Slack, it appears as a link.
The trigger is sent to the LLM to determine whether the action is relevant, but users never see it.
The URL is attached to the button by Biel.ai. It does not appear in the answer text unless you include it there yourself.
## Action fields
| Field | Description |
| --- | --- |
| **Name** | Internal identifier for the action. Use only letters, numbers, hyphens, and underscores, for example `contact_support`. Each name must be unique within the project. |
| **When to use** | Plain-language description of when the action should appear. Biel.ai uses this as the trigger, so describe the user's intent and situation as specifically as possible. |
| **Button text** | Label shown to the user, for example `Contact support`. |
| **URL** | Address that opens in a new tab when the user clicks the button. The URL can include [conversation placeholders](#pass-conversation-context). |
## Pass conversation context
When an action opens a form or external tool, that destination does not automatically receive the conversation context.
You can include placeholders in the **URL** to pass useful information, such as the conversation ID, the user's latest question, or a link back to the conversation.
For example:
```text
https://support.example.com/new?conversation_id={chat_id}
```
Before showing the button, Biel.ai replaces each placeholder with its value.
You can map these values to any field your destination supports, such as a subject line, hidden form field, or query parameter.
### Available placeholders
| Placeholder | Value |
| ------------ | ---------------------------------------------------------------------------------------------------- |
| `{chat_id}` | The conversation ID. Use the **Conversation ID** filter on the project's **Chats** tab to find it. |
| `{chat_url}` | Direct link to the conversation in the Biel.ai dashboard. The viewer must be signed in to your team. |
| `{question}` | The user's most recent message, up to 500 characters. |
Placeholder values are URL-encoded. Characters such as `&` and `?` in a user's message therefore cannot break the rest of the URL.
If a placeholder has no value, Biel.ai replaces it with an empty value rather than leaving the placeholder text in the URL.
### Example
The following support action passes the user's latest question and a link to the conversation:
```text
https://support.example.com/new?subject={question}&conversation={chat_url}
```
This can help the person receiving the request understand what the user was asking without requiring the user to repeat the context.
## Configure an action
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Open **Assistant** in the left sidebar and, under **Actions**, click **Add action**.
4. Enter the **Name**, **When to use**, **Button text**, and **URL**. Use a name such as `contact-support` without spaces; the button text can be `Contact support`.

5. Click **Save** on the Actions card.
Biel.ai rejects URLs that contain unrecognized placeholders, so placeholder typos are caught when you save the action.
You can add as many actions as you need.
After creating an action, open the assistant on your site and send a message that should match its trigger. Verify that the expected button appears.
## Write effective triggers
The **When to use** field determines whether Biel.ai considers an action relevant. Clear, specific triggers make actions more likely to appear at the right time.
* **Describe the user's intent.** Write `When the user asks to talk to a human, reports a billing problem, or expresses frustration` instead of `Show the support button`.
* **Name the situations the action covers.** Broad triggers can cause buttons to appear too often. For example, `When the user needs help` could match almost any support question.
* **Keep triggers distinct.** If multiple actions have overlapping triggers, Biel.ai may show more than one button. This is useful when both actions are relevant, but avoid overlap when it would confuse the user.
For example, this trigger is too broad:
```text
When the user needs help.
```
A more useful trigger describes the situations that should lead to the action:
```text
When the user reports a bug, says something is not working, or asks to talk to a person.
```
---
## Chat progress
The assistant shows a spinner and the current operation while preparing an answer in Auto, Instant, and Think modes, including chat opened through **Ask AI** in the search widget.
Labels describe operations such as **Searching documentation**, **Searching documentation again**, and **Writing your answer**. They reflect work performed; they do not expose the model's private reasoning. Hovering the spinner does not open a popup. The indicator disappears after successful completion, leaving the answer in the chat.
Progress updates require both a supporting widget version and backend. Older installed widget versions continue using their existing interface. Update your installed widget package to use the options below; a backend update alone does not update it.
## Use loading dots
Set `loading-indicator="dots"` to use the previous bouncing dots animation instead of the spinner and visible progress text:
```html
Ask AI
```
The option works on ``, ``, ``, and ``. On the search widgets, it controls the assistant shown after selecting **Ask AI**.
| Attribute | Default | Description |
| --- | --- | --- |
| `loading-indicator` | `spinner` | `spinner` shows the current operation; `dots` shows bouncing dots without visible progress text. |
| `loading-text` | `Loading…` | Fallback label before a progress update arrives, or when the backend does not provide updates. |
Dots keep progress announcements available to screen readers. Interrupted or failed answers still show their status and **Retry** when available.
## Set the fallback loading text
Use `loading-text` to translate the initial loading label:
```html
```
After the first progress update, the current operation replaces this fallback label. With dots, the label remains available to screen readers without appearing visually.
You can also set these options as JavaScript properties on any of the four widgets:
```javascript
const widget = document.querySelector('biel-button');
widget.loadingIndicator = 'dots';
widget.loadingText = 'Chargement…';
```
## Recover an interrupted answer
If generation fails or the connection interrupts an answer, the widget keeps any text already received. When retry is available, **Retry** sends the last request again after the connection is ready. It creates a new response in the conversation; it does not resume the interrupted response. Requests are not automatically resubmitted.
**Continue generating** serves a different purpose: when an answer reaches its length limit, it asks the assistant to continue from where it left off in the same conversation.
Continuations consume interactions from your team's allowance. With [extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage) enabled, continuations beyond the included allowance cost $0.05 per interaction.
## Customize the indicator
Change the spinner color independently of the rest of the widget with [`--biel-activity-spinner-color`](./styles.mdx). Use [`--biel-loading-dot-color`](./styles.mdx) for loading dots, or target the [spinner CSS part](https://docs.biel.ai/customization/styles.md) for finer control.
---
## Prompt customization
Biel.ai offers two modes for controlling how the assistant responds: **Default prompt** (optimized for technical documentation) and **Custom prompt** (full control).
## Default prompt
The default prompt gives clear, step-by-step technical answers based on your documentation. It asks clarifying questions when a request is unclear and says when the documentation does not contain enough information instead of guessing.
You can extend the default prompt with additional instructions—for example, adding a signature to responses or modifying the tone. Prompt extensions are limited to `6,000` characters.
## Custom prompt
Write your own prompt for full control over the assistant's behavior. Custom prompts are limited to `8,000` characters.
:::warning
Custom prompts may disable built-in safeguards and advanced processing features.
:::
## Configure the prompt
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
1. In the Biel.ai dashboard, select your project.
2. Click **Settings**.
3. Open **Assistant** in the left sidebar and, under **AI model and instructions** > **Define prompt**:

- Select **Use default prompt** and optionally add instructions in **Extend prompt**, or
- Select **Custom prompt** and write your full instructions in **Extend prompt**.
4. Click **Save** on the AI model and instructions card.
### Examples
**Extending the default prompt:**
```
Always start responses with "Hi!"
```
**Custom prompt:**
```
You are a customer support assistant for [Product Name]. Provide clear, accurate answers related to product features, troubleshooting, and usage. Keep responses professional and focused on the product. Only respond based on the information you can extract from CONTEXT and the conversation HISTORY.
```
---
## Dark mode
To enable dark mode in the Biel.ai chat widget, set `data-theme="dark"` on your site's `` tag. The widget detects the attribute and switches automatically, so it always matches your site's active theme.
## Automatic theme switching
The widget follows changes to `data-theme` in real time. If your framework uses a different theme attribute or class, synchronize its theme with `data-theme` on ``. Setting another framework's theme alone does not change the widget palette.
## Force dark mode permanently
If your site is always dark, add the attribute statically:
```html
```
The widget renders in dark mode for every visitor, regardless of their system's `prefers-color-scheme` setting.
## Customize dark mode colors
Dark mode uses the widget's default dark palette. To adjust individual colors (background, text, buttons), override the `--biel-*` CSS variables — see [Styles](https://docs.biel.ai/customization/styles.md) for the full variable list.
---
## Data privacy
Configure how Biel.ai stores chat message text and IP addresses, and whether the widget asks users to accept your terms.
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
## Remove personally identifiable information
Biel.ai can detect and redact names, emails, and phone numbers from chat message text before saving it. Detected values are replaced with redaction placeholders.
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Under **Security & Privacy** > **Data Privacy**, enable **Remove personally identifiable information (PII)**.

4. Click **Save** on the Data Privacy card.
Future conversations automatically redact PII.
## Disable IP address collection
Stop saving user IP addresses with chats and messages. This changes how analytics estimates unique users: chats without a saved IP each count as one user. Country information can still be derived from the request.
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Under **Security & Privacy** > **Data Privacy**, enable **Disable IP address collection**.

4. Click **Save** on the Data Privacy card.
## Require Terms & Conditions acceptance
Require users to accept Terms & Conditions before starting a conversation.

Add these attributes to your ``:
```html
Ask AI
```
Replace `` with your project ID. Update the `terms-description` link to point to your own Terms & Conditions.
---
## Confluence as a data source
Connect a Confluence Cloud space to Biel.ai to index your team's pages and make them searchable through the assistant.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- An existing [project](https://docs.biel.ai/quickstart.md#2-create-a-project).
- An Atlassian account with access to the Confluence pages you want to index.
- Confluence Cloud (Server is not supported).
## 1. Generate a Confluence API token
1. Open your [Atlassian account's API tokens](https://id.atlassian.com/manage-profile/security/api-tokens).
2. Click **Create API token**, enter a name, and select an expiration date. Use a token without scopes for Biel.ai's connection to your site's URL.
3. Click **Create**, then **Copy to clipboard**. You cannot view the token again after closing this screen.
See [Manage API tokens for your Atlassian account](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/) for details.
## 2. Connect Confluence to Biel.ai
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Go to **Settings** > **Sources** > **Confluence**.
3. Enter the space URL, such as `https://yourcompany.atlassian.net/wiki/spaces/DOCS`.
4. Click the settings icon beside the URL to show **Credentials**, then enter your Atlassian account **Email** and **API Token**.

5. Click **Save**.
6. Click **Refresh sources** to index the space's pages.
:::tip[Finding your space URL]
Navigate to any page in your Confluence space and copy the URL up to `/spaces/SPACENAME`.
:::
Monitor the loading status in the project dashboard and open **Logs** to check which pages were indexed.
## Troubleshooting
### Authentication failed
- Verify your email matches your Atlassian account.
- Check the API token is correct and hasn't expired.
- Ensure you have access to the specified space.
### Pages not indexing
- Check that pages are published (not drafts).
- Verify space permissions allow API access.
- Large spaces may take longer to process.
### Content quality issues
- Confluence macros may not render properly in AI responses.
- Consider excluding template or boilerplate pages with URL filters.
---
## Files
Upload documents directly to your project. Biel.ai indexes their content for chat responses.
:::tip
Uploaded files remain private. Your assistant does not expose a link to the stored file as a source.
:::
## When to use file uploads
Use file uploads for:
- Internal documents such as handbooks, policies, and procedures
- Offline content that is not published on the web
- PDF manuals, Office documents, and spreadsheets
- Confidential content that needs to stay private
## Supported formats
| Format | Extensions |
|--------|------------|
| PDF | `.pdf` |
| Word | `.docx` |
| PowerPoint | `.pptx` |
| Excel | `.xlsx` |
| Delimited data | `.csv` |
| Markdown and text | `.md`, `.txt` |
| Structured data | `.yaml`, `.yml`, `.json`, `.xml` |
| Documentation and web files | `.rst`, `.html`, `.css`, `.js` |
## Requirements
- Each file can be up to 10 MB.
- Use the listed extension. Legacy Office formats such as `.doc`, `.xls`, and `.ppt` are not supported.
- Files must not be empty or password-protected.
## Upload files
1. In the [Biel.ai dashboard](https://app.biel.ai), select an existing project. Files are available after you create the project.
2. Go to **Settings** > **Sources** > **Files**.

3. Drag files into the upload area, or click **Browse files**. Files upload automatically; wait until they appear in the uploaded-file list.
4. Click **Refresh sources** to index the files. Check the loading status and **Logs** in the project dashboard.
## How files are indexed
Biel.ai processes PDF, Word, and PowerPoint files page by page. It processes each Excel sheet separately. This keeps retrieved content aligned with the page or sheet where it came from.
Scanned PDFs are processed with OCR. Clear, high-resolution scans generally produce better results than low-quality scans or pages with difficult layouts.
## Manage files
For text and HTML files, use the **Preview** or **Edit** icon next to the file. After editing, click **Save** in the editor. For other formats, delete the old version and upload the replacement. Click **Refresh sources** after changing files to index the current set.
Use the **Download** icon next to an uploaded file in **Settings** > **Sources** > **Files** to retrieve the original file. To remove a file, click its **Delete** icon.
## Troubleshooting
### Upload failures
- Check that the file is no larger than 10 MB.
- Verify the file format is [supported](#supported-formats).
- Check that the file is not empty, corrupt, or password-protected.
### Content not indexing
- Refresh sources after upload, then allow the crawl to finish.
- For scanned PDFs, use a clear scan with legible text.
- If a large document is only partly indexed or a crawl reports that files were skipped, try refreshing sources again. [Contact us](https://biel.ai/contact) if the problem continues.
---
## GitHub repositories
Add GitHub repositories to include documentation, README files, and code comments in your assistant's knowledge base.
:::tip
File content remains private. Your assistant won't expose file links as sources to users.
:::
## When to use GitHub repositories
Use GitHub repositories for:
- Documentation stored with code (README files, docs folders)
- Private internal documentation
- API documentation and code examples
- Developer guides and technical content
## Add a repository
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Go to **Settings** > **Sources** > **GitHub**.

3. Enter the repository URL (e.g., `https://github.com/owner/repo`).
4. Click **Save**.
5. Click **Refresh sources** to index the repository. Check the loading status and **Logs** in the project dashboard.
### Private repositories
Private repos require a GitHub personal access token:
1. Go to [GitHub Settings > Personal access tokens](https://github.com/settings/tokens).
2. Click **Generate new token (classic)**.
3. Select the `repo` scope and click **Generate token**.
4. Copy the token.
5. In Biel.ai, click the settings icon beside the repository URL to expand **Advanced options**, then paste the token in **GitHub token**.
6. Click **Save**, then **Refresh sources**.
## Filter files
Control which files get indexed using include and exclude patterns.
Open the repository's **Advanced options** and enter comma-separated values in **Include patterns** or **Exclude patterns**. Click **Save**, then **Refresh sources** to apply them.
| Pattern | Action | Effect |
|---------|--------|--------|
| `*.md` | Include | Only Markdown files |
| `docs/` | Include | Only files in docs folder |
| `*.rst` | Include | Only reStructuredText files |
| `node_modules/` | Exclude | Skip dependencies |
| `.git/` | Exclude | Skip Git metadata |
| `*.test.*` | Exclude | Skip test files |
| `build/` | Exclude | Skip build artifacts |
## Advanced options
* **Multiple repositories**: Add different repositories as separate sources
* **Branch selection**: Default branch is indexed (usually `main` or `master`)
* **Submodules**: Not automatically indexed—add as separate sources
## Troubleshooting
### Repository not found
- Check URL format: `https://github.com/owner/repo`.
- For private repos, verify the token has `repo` scope and hasn't expired.
### Files not indexing
- Check that include patterns match your file paths.
- Review exclude patterns for over-exclusion.
- Verify files are in supported formats (Markdown, plain text, reStructuredText).
### Token issues
- Confirm the token has `repo` scope.
- Regenerate the token if it has expired.
- Check that repository permissions haven't changed.
---
## OpenAPI
# OpenAPI documents
Add OpenAPI specs to index API documentation. Structured YAML/JSON is parsed more accurately than crawling API docs websites — all endpoints, parameters, and schemas are captured.
:::tip
File content remains private. Your assistant won't expose file links as sources to users.
:::
## Requirements
- Valid OpenAPI/Swagger syntax (versions 2.0, 3.0.x, 3.1.x).
- JSON (`.json`) or YAML (`.yaml`, `.yml`) format.
- Publicly accessible URL.
## Add an OpenAPI document
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Go to **Settings** > **Sources** > **OpenAPI**.
3. Enter the document URL.

4. To add another specification, click **Add OpenAPI URL** and enter its URL.
5. Click **Save**.
6. Click **Refresh sources** to index the specifications. Check the loading status and **Logs** in the project dashboard.
Example URLs:
```text
https://api.example.com/openapi.json
https://docs.example.com/swagger.yaml
https://api.example.com/v1/openapi.yml
```
## Troubleshooting
### Document not loading
- Check the URL is publicly accessible.
- Verify valid OpenAPI syntax.
### Validation errors
- Check logs for validation details.
- Fix syntax errors and click **Refresh sources**.
---
## Sources overview
Configure content sources that your assistant uses to answer questions. Sources determine what information is available to users.
:::important
Only Administrator and Maintainer roles can manage sources. See [Manage roles](https://docs.biel.ai/../administration/roles.md).
:::
## Source types
Sitemaps
Add entire websites using XML sitemaps
URLs
Add individual web pages
Files
Upload documents in PDF, Word, Excel, and other formats
GitHub
Add code repositories and their documentation
Confluence
Import from Confluence
OpenAPI
Add OpenAPI/Swagger specifications for API documentation
Private content
Manage private and authenticated content
## Add a source
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Go to **Settings** > **Sources**.

3. Choose a source type and configure it.
4. Click **Save**.
5. Click **Refresh sources** to index the updated content.
The project dashboard shows **Sources loading** while content is being indexed and **Sources loaded** when it finishes. Open **Logs** to check which pages were processed, then test your assistant.
To upload files, create the project first, then open **Settings** > **Sources** > **Files**. Uploads are saved as soon as they finish; click **Refresh sources** to index them.
---
## Private content
Biel.ai can access content behind login pages and VPN protection. This requires custom configuration and a Business or Enterprise plan.
Contact [info@biel.ai](mailto:info@biel.ai) to discuss your requirements.
---
## Sitemaps
Add entire websites using XML sitemap files. Sitemaps efficiently index large amounts of content from a single domain.
## When to use sitemaps
Use sitemaps to:
- Add complete documentation sites or blogs
- Index hundreds or thousands of pages efficiently
- Automatically discover new pages as they're added
- Handle structured website content
## Requirements
Sitemaps must:
- End with `.xml`
- Be publicly accessible
- Follow the [XML Sitemap Protocol](https://www.sitemaps.org/)
Supported types:
- Standard sitemaps (single XML files)
- Sitemap indexes (reference multiple sitemaps)
- Nested sitemaps (linked sitemaps)
## Add sitemaps
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Go to **Settings** > **Sources** > **Sitemaps**.

3. Enter the sitemap URL (must end in `.xml`).
4. Click **Save**.
5. Click **Refresh sources** to discover and index the sitemap's pages. Check the loading status and **Logs** in the project dashboard.
Example sitemap URLs:
```
https://docs.example.com/sitemap.xml
https://blog.example.com/sitemap.xml
https://help.example.com/sitemap_index.xml
```
## Find sitemaps
Common locations:
```
https://yoursite.com/sitemap.xml
https://yoursite.com/sitemap_index.xml
https://yoursite.com/sitemaps/sitemap.xml
```
Platform-specific patterns:
| Platform | Sitemap URL |
|----------|-------------|
| Docusaurus | `https://yoursite.com/sitemap.xml` |
| GitBook | `https://yourorg.gitbook.io/sitemap.xml` |
| WordPress | `https://yoursite.com/wp-sitemap.xml` |
For other platforms, check `robots.txt` at `https://yoursite.com/robots.txt` for sitemap declarations.
## Filter URLs
Use URL filters to decide which pages from your sitemaps Biel indexes. Each
filter has a [regular expression pattern](https://docs.python.org/3/library/re.html#regular-expression-syntax)
and an action: **Include** or **Exclude**. Biel compares the pattern with the
complete URL, such as `https://docs.example.com/guides/install/`.
1. Go to **Projects** > your project > **Settings** > **Sources** > **Sitemaps**.
2. Add one or more filter rules under **Filter URLs**.

3. Click **Save**, then **Refresh sources** to apply the filters to the next crawl.
### Choose an action
- If no include rules exist, all URLs are included by default.
- If include rules exist, a URL is kept when it matches any include pattern.
- An exclude rule always takes precedence: a matching URL is skipped even when
it also matches an include rule.
Filters apply to URLs from every sitemap configured in the project.
### Write a URL pattern
Start with the part of the URL you want to match. For example, this include
pattern keeps documentation paths on any configured domain:
```regex
/docs(?:/|$)
```
Use regular expression syntax rather than wildcard syntax: write
`/docs(?:/|$)`, not `**/docs/**`. Patterns are case-sensitive.
To restrict a rule to one domain, match from the beginning of the complete URL:
```regex
^https://docs\.example\.com/guides(?:/|$)
```
In this pattern:
- `^` means the match must start at the beginning of the URL.
- `docs\.example\.com` matches the domain; `\.` represents a literal dot.
- `/guides(?:/|$)` matches `/guides`, everything below it, and no similarly
named path such as `/guides-old`.
You can omit `^https://` when a path pattern should apply to every configured
domain.
### Examples
| Pattern | Action | Effect |
|---|---|---|
| `^https://docs\.example\.com/docs(?:/|$)` | Include | Only index `/docs` and pages below it on this domain |
| `/api(?:/|$)` | Exclude | Skip API reference paths on any configured sitemap domain |
| `/deprecated(?:/|$)` | Exclude | Skip deprecated sections |
| `^https://docs\.example\.com/(?:en|fr)(?:/|$)` | Include | Only index English and French paths |
| `\.pdf(?:$|[?#])` | Exclude | Skip PDF URLs |
| `/[0-9]+\.[0-9]+\.[0-9]+(?:/|$)` | Exclude | Skip versioned paths such as `/1.2.3/` |
To include selected sections from different domains, create one include rule per
section. For example:
| Pattern | Action |
|---|---|
| `^https://docs\.example\.com(?:/|$)` | Include |
| `^https://example\.com/extensions/product(?:[-/]|$)` | Include |
| `^https://example\.com/api/Product(?:[./]|$)` | Include |
All other sitemap URLs are omitted because they do not match an include rule.
You do not need to create exclude rules for every unrelated path.
Avoid broad catch-all rules unless they are intentional:
- An include rule containing `.*` includes every URL.
- An exclude rule containing `.*` excludes every URL.
## Sitemap index files
Large sites often use index files that reference multiple sitemaps:
```xml
https://example.com/docs-sitemap.xmlhttps://example.com/blog-sitemap.xml
```
Biel.ai automatically follows sitemap indexes and processes all referenced sitemaps.
## Troubleshooting
### Sitemap not found
- Check URL format (must end with `.xml`).
- Try common sitemap locations listed in [Find sitemaps](#find-sitemaps).
- Check `robots.txt` for sitemap declarations.
### Partial indexing
- Verify pages in the sitemap are publicly accessible.
- Review URL filters for over-exclusion.
- JavaScript-heavy pages may not index properly.
---
## URLs
Add individual web pages to your project. Use URLs when you need specific pages rather than entire websites.
:::tip
For multiple pages from the same website, use [sitemaps](https://docs.biel.ai/customization/data-sources/sitemaps.md) instead.
:::
## When to use URLs
Use URLs to:
- Add specific pages from different websites
- Test new content before adding full sites
- Include only high-priority pages from larger sites
- Add pages that aren't in sitemaps
## Requirements
- Publicly accessible (not behind login).
- Full URL with protocol (e.g., `https://example.com/page`).
- Page contains text content (not just images or videos).
## Add URLs
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Go to **Settings** > **Sources** > **URLs**.

3. Enter the full URL (including `https://`).
4. Click **Save**.
5. Click **Refresh sources** to index the pages. Check the loading status and **Logs** in the project dashboard.
Example URLs:
```
https://example.com/blog/getting-started
https://docs.example.com/api-reference
https://support.example.com/troubleshooting
```
## Troubleshooting
### URL not indexing
- Verify the URL is publicly accessible.
- Check the URL includes `https://`.
- Check if the site blocks crawlers in `robots.txt`.
### Content not appearing
- Wait 5-10 minutes for processing.
- Test with specific questions about the page content.
- Check if the page relies on JavaScript to render content.
---
## Embedded mode
Embedded mode renders the assistant inline in your page layout instead of as a floating button. Use it to build dedicated help pages or embed the assistant within a specific section of your site.
## Preview
## Add embedded mode
Add the following to your HTML:
```html
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://app.biel.ai).
---
## Initial message
The initial message is the first text the assistant displays when a user opens it. Use it to greet visitors, provide instructions, or set the tone.
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
## Customize the initial message
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Open **Assistant** in the left sidebar and enter your text in **Conversation** > **Welcome message**.

4. Click **Save** on the Conversation card.
Open the assistant on your site to verify the updated message appears.
---
## Widget customization
Configure the assistant and search widgets by setting HTML attributes. Override text properties to localize the widget.
## biel-button
The `` component adds a floating AI chat button to your site. Use `` to render the same assistant inline; it accepts the assistant modal properties below. See [Embedded mode](https://docs.biel.ai/customization/embedded-mode.md).

### Usage
```html
Ask AI
```
### Assistant button properties {#chatbot-button-properties}
| Property | Description |
|------------------------|-----------------------------------------------------------------------------------------------|
| **Layout** | | |
| `project` | **Required****Type**: `string`The project ID. |
| `button-position` | **Type**: `string`**Default value**: `default`**Available values:** `default`, `bottom-right`, `bottom-left`, `center-right`, `center-left`, `custom` Controls the position of the chat button on your webpage. Use `custom` to position the button using CSS.|
| `button-style` | **Type**: `string`**Default value**: `default`**Available values:** `default`, `dark`, `light`Defines the visual style of the chat button. `dark` and `light` choose a launcher palette; `default` inherits the page styling. The modal theme is controlled separately by `data-theme`.|
| `custom-font` | **Type**: `boolean`**Default value**: `false`When set to `true`, disables loading of the Inter font. Use this if your site already uses a different font to improve load time and maintain font consistency.|
| `hide-icon` | **Type**: `boolean`**Default value**: `false`When set to `true`, the button icon hides. |
| `ai-icon` | **Type**: `string`**Default value**: `biel`**Available values:** `biel`, `bot`, `sparks`, `question-mark`Specifies which AI icon to display in the button.|
| `hide-avatars` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides avatars in the chat interface.|
| `api-key` | **Type**: `string`**Default value**: ``API key for authenticating requests to private projects. Required for private projects with `chat_create` and `project_read` permissions. Not required for public projects.|
| `api-url` | **Type**: `string`**Default value**: Biel.ai APIOverride the base API URL for self-hosted or custom endpoints.|
The "Powered by Biel.ai" branding is controlled by your team's **Remove 'Powered by Biel.ai' branding** setting. An eligible plan enables that setting; you still need to activate it and click **Save details**. See [Whitelabel](https://docs.biel.ai/administration/whitelabel.md).
### Assistant modal properties {#chatbot-modal-properties}
| Property | Description |
|------------------------|-----------------------------------------------------------------------------------------------|
| **Layout** | | |
| `disable-input` | **Type**: `boolean`**Default value**: `false`When set to `true`, the user input field is disabled. |
| `disable-autofocus` | **Type**: `boolean`**Default value**: `false`When set to `true`, opening the assistant does not focus the message input automatically. |
| `email` | **Type**: `string`**Default value**: `` An email address or ID for conversation tracking. This ID will be associated with the chat session in your project dashboard for analytics and user tracking purposes. |
| `metadata` | **Type**: `string`**Default value**: ``Custom metadata to attach to chat sessions. Use this to pass additional contextual information (e.g., user plan, page URL, or other identifiers) that will be associated with the conversation for analytics purposes. |
| `expand-modal` | **Type**: `boolean`**Default value**: `false`When set to `true`, the chat modal opens in its expanded state by default. |
| `hide-close-button` | **Type**: `boolean`**Default value**: `false`When set to `true`, the close icon hides. |
| `hide-expand-button` | **Type**: `boolean`**Default value**: `false`When set to `true`, the expand button icon hides. |
| `hide-refresh-button` | **Type**: `boolean`**Default value**: `false`When set to `true`, the refresh button hides. |
| `hide-feedback` | **Type**: `boolean`**Default value**: `false`When set to `true`, removes the feedback options (like thumbs up/down) that users can use to rate AI responses. |
| `hide-sources` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides the sources section from AI responses in the chat interface. |
| `hide-inline-citations` | **Type**: `boolean`**Default value**: `false`When set to `true`, removes numeric inline citations from AI answers and their numbers from source cards. The sources section remains available unless `hide-sources` is also set. |
| `hide-settings-button` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides the reasoning mode selector above the message input. Only applies if reasoning mode is enabled for your project. |
| `hide-connect-button` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides the Connect menu above the message input. This menu provides MCP (Model Context Protocol) connection options when MCP is enabled for the project. |
| `hide-tooltips` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides the tooltips that appear when hovering over header icons. |
| `loading-indicator` | **Type**: `string`**Default value**: `spinner`**Available values:** `spinner`, `dots`Shows a spinner with the current operation while the assistant is working. Use `dots` for the previous bouncing dots animation without visible progress text. Screen reader announcements and error recovery remain available. See [Chat progress](https://docs.biel.ai/customization/chat-progress.md). |
| `loading-text` | **Type**: `string`**Default value**: `Loading…`Loading label before the first progress update arrives. With `dots`, this label is announced to screen readers without appearing visually. See [Chat progress](https://docs.biel.ai/customization/chat-progress.md). |
| `modal-position` | **Type**: `string`**Default value**: `center`**Available values:** `center`, `top-center`, `top-left`, `top-right`, `center-left`, `center-right`, `bottom-left`, `bottom-right`, `sidebar-left`, `sidebar-right`Determines where the chat modal appears on the screen when opened. Use `sidebar-left` or `sidebar-right` to dock the chat as a side panel.|
| `show-terms-modal` | **Type**: `boolean`**Default value**: `false`When set to `true`, displays a terms and conditions modal before starting the chat. |
| `think-mode-enabled` | **Type**: `boolean`**Default value**: `false`Legacy option that starts a new conversation in Think mode when reasoning mode is enabled for the project. Use `default-think-mode` to choose Auto, Instant, or Think. A visitor's saved choice takes precedence. See [Reasoning modes](https://docs.biel.ai/customization/reasoning-modes.md). |
| `default-think-mode` | **Type**: `string`**Available values:** `auto`, `fast`, `think`Starting mode for a new conversation when reasoning mode is enabled for the project. A visitor's saved choice takes precedence. This property takes precedence over the legacy `think-mode-enabled` option. See [Reasoning modes](https://docs.biel.ai/customization/reasoning-modes.md). |
| `keep-conversation` | **Type**: `boolean`**Default value**: `true`When set to `false`, clears the conversation history on page navigation. By default, a conversation can be restored across page reloads for one hour after its last saved update, using browser storage. Each widget instance keeps its own conversation; use a stable HTML `id` when placing several widgets on a page. |
| `render-math` | **Type**: `boolean`**Default value**: `true`When set to `true`, typesets supported LaTeX in AI answers with MathJax. Set to `false` to leave LaTeX source unchanged. |
| `render-diagrams` | **Type**: `boolean`**Default value**: `true`Renders Mermaid diagrams in AI answers. Set to `false` to show their source code instead. |
| `mermaid-theme` | **Type**: `string`**Default value**: `default`Theme used for rendered Mermaid diagrams. |
| `mathjax-url` | **Type**: `string`**Default value**: `https://cdn.jsdelivr.net/npm/mathjax@3.2.2/es5/tex-svg.js`The MathJax script URL. Set this to a self-hosted copy when your site's Content Security Policy blocks the default CDN. |
| **MCP Integration** | | |
| `mcp-server-url` | **Type**: `string`**Default value**: ``Override the MCP server URL. Use for custom or self-hosted MCP servers, or when authentication is required. Takes priority over the API-provided URL. See [MCP Server](https://docs.biel.ai/integrations/mcp-server.md). |
| **Text** | | |
| `assistant-label` | **Type**: `string`**Default value**: `Assistant`Label text displayed above AI responses in the chat. |
| `close-button-text` | **Type**: `string`**Default value**: `Close`Tooltip text for the close button in the assistant header. |
| `collapse-button-text` | **Type**: `string`**Default value**: `Collapse`Tooltip text for the collapse button in the assistant header. |
| `error-message-4-0-3` | **Type**: `string`**Default value**: `Oops! The request URL or API key is invalid or not authorized for this project.`403 unauthorized message. |
| `error-message-4-0-4` | **Type**: `string`**Default value**: `Oops! We could not find the provided project ID.`404 not found message. |
| `error-message-default`| **Type**: `string`**Default value**: `Oops! Please try again later.`500 error message. |
| `expand-button-text` | **Type**: `string`**Default value**: `Expand`Tooltip text for the expand button in the assistant header. |
| `footer-text` | **Type**: `string`**Default value**: `AI answers may be inaccurate. Verify with official sources.`Footer text. |
| `header-title` | **Type**: `string`**Default value**: `Company Name AI`Title text for the assistant header. |
| `input-placeholder-text` | **Type**: `string`**Default value**: `Type your message`Placeholder text displayed in the assistant's input field. |
| `connect-button-text` | **Type**: `string`**Default value**: `Connect`Tooltip text for the Connect button in the assistant header. |
| `mcp-url-text` | **Type**: `string`**Default value**: `MCP URL`Label for the MCP URL option in the connect dialog. |
| `mcp-url-description` | **Type**: `string`**Default value**: `Copy to clipboard`Description text for the MCP URL option in the connect dialog. |
| `mcp-claude-text` | **Type**: `string`**Default value**: `Claude Code`Label for the Claude Code option in the connect dialog. |
| `mcp-claude-description` | **Type**: `string`**Default value**: `CLI command`Description text for the Claude Code option in the connect dialog. |
| `mcp-codex-text` | **Type**: `string`**Default value**: `Codex`Label for the Codex option in the Connect menu. |
| `mcp-codex-description` | **Type**: `string`**Default value**: `Copy setup command`Tooltip text for copying the Codex setup command. |
| `mcp-codex-copied-description` | **Type**: `string`**Default value**: `Command copied to clipboard`Confirmation after copying the Codex setup command. |
| `mcp-copilot-text` | **Type**: `string`**Default value**: `Copilot (VS code)`Label for the Copilot option in the connect dialog. |
| `mcp-copilot-description` | **Type**: `string`**Default value**: `Opens in a new tab`Description text for the Copilot option in the connect dialog. |
| `mcp-cursor-text` | **Type**: `string`**Default value**: `Cursor`Label for the Cursor option in the connect dialog. |
| `mcp-cursor-description` | **Type**: `string`**Default value**: `Opens in a new tab`Description text for the Cursor option in the connect dialog. |
| `mcp-copied-text` | **Type**: `string`**Default value**: `Copied!`Confirmation text shown after copying an MCP value to the clipboard. |
| `mcp-url-copied-description` | **Type**: `string`**Default value**: `URL copied to clipboard`Description text shown after copying the MCP URL. |
| `mcp-claude-copied-description` | **Type**: `string`**Default value**: `Command copied to clipboard`Description text shown after copying the Claude Code command. |
| `refresh-button-text` | **Type**: `string`**Default value**: `Refresh`Tooltip text for the refresh button in the assistant header. |
| `continue-text` | **Type**: `string`**Default value**: `Continue generating`Label for continuing an answer that reached its length limit. |
| `incomplete-text` | **Type**: `string`**Default value**: `This answer could not be completed. Ask for a shorter answer or a specific section.`Message shown when an answer cannot be completed. |
| `message-too-long-text` | **Type**: `string`**Default value**: `Message is too long. Use at most 10,000 characters.`Validation message for an oversized question. |
| `send-button-text` | **Type**: `string`**Default value**: `Send`Text displayed on the send button next to the input field. |
| `sources-text` | **Type**: `string`**Default value**: `Sources`Text displayed for introducing sources in messages. |
| `suggested-questions` | **Type**: `string`**Default value**: emptyA JSON array or comma-separated list of questions shown when users open the chat. For example, `suggested-questions='["How do I start?", "What can I build?"]'`. |
| `suggested-questions-title` | **Type**: `string`**Default value**: `Suggested questions`The heading text that appears above the list of suggested questions in the chat interface. |
| `settings-button-text` | **Type**: `string`**Default value**: `Settings`Tooltip text for the settings button (reasoning mode selector) in the assistant header. Only visible if reasoning mode is enabled for your project. |
| `terms-checkbox-text` | **Type**: `string`**Default value**: `I have read and agree to the Terms & Conditions.`Text displayed next to the terms acceptance checkbox. |
| `terms-description` | **Type**: `string`**Default value**: `Please review our Terms & Conditions before proceeding.`Description text shown in the terms and conditions modal. |
| `terms-title` | **Type**: `string`**Default value**: `Chatbot Terms & Conditions`Title text for the terms and conditions modal. |
| `think-mode-auto-text` | **Type**: `string`**Default value**: `Auto`Label for the Auto reasoning mode in the settings dropdown. |
| `think-mode-auto-description` | **Type**: `string`**Default value**: `Balances speed and quality`Description for the Auto reasoning mode. |
| `think-mode-fast-text` | **Type**: `string`**Default value**: `Instant`Label for the Instant reasoning mode in the settings dropdown. |
| `think-mode-fast-description` | **Type**: `string`**Default value**: `Prioritizes speed`Description for the Instant reasoning mode. |
| `think-mode-think-text` | **Type**: `string`**Default value**: `Think`Label for the Think reasoning mode in the settings dropdown. |
| `think-mode-think-description` | **Type**: `string`**Default value**: `Takes longer for better accuracy`Description for the Think reasoning mode. |
| `welcome-message` | **Type**: `string`**Default value**: ""A custom greeting message that appears when users first open the chat. |
The `escape-close`, `click-outside-close`, and `show-modal` properties are available on `` directly. The `` launcher does not expose those properties.
When using `` directly, you can also set `smooth-streaming="false"` to display response chunks as they arrive instead of smoothing their appearance. Its default is `true`.
## biel-search-button
The `` component adds an AI-powered search bar to your site. Use `` to render the search interface directly; it accepts the search modal and assistant modal properties below.

### Usage
```html
Search
```
### Search button properties
| Property | Description |
|------------------------|-----------------------------------------------------------------------------------------------|
| **Layout** | | |
| `project` | **Required****Type**: `string`The project ID. |
| `button-style` | **Type**: `string`**Default value**: `default`**Available values:** `default`, `rounded`Style of the button.|
| `custom-font` | **Type**: `boolean`**Default value**: `false`When set to `true`, the [Inter font](https://fonts.google.com/specimen/Inter) will not be loaded. Useful if your site already uses a different font, enabling a quicker load time.|
| `hide-ctrl-k` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides the Ctrl+K hint and disables the launcher's Ctrl+K keyboard shortcut. |
| `hide-icon` | **Type**: `boolean`**Default value**: `false`When set to `true`, the button icon hides. |
| `ai-icon` | **Type**: `string`**Default value**: `biel`**Available values:** `biel`, `bot`, `sparks`, `question-mark`Specifies the AI icon in the assistant opened through Ask AI. The search launcher uses a search icon.|
| `hide-avatars` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides avatars in the chat interface.|
| `api-key` | **Type**: `string`**Default value**: ``API key for authenticating requests to private projects. Required for private projects with `chat_create`, `project_search`, and `project_read` permissions. Not required for public projects.|
### Search modal properties
| Property | Description |
|------------------------|-----------------------------------------------------------------------------------------------|
| **Layout** | | |
| `disable-autofocus` | **Type**: `boolean`**Default value**: `false`When set to `true`, opening search does not focus the search input automatically. |
| `hide-ask-ai-button` | **Type**: `boolean`**Default value**: `false`When set to `true`, the "Ask AI" button is hidden from the search results. |
| `hide-descriptions` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides descriptions in search results for a cleaner interface.|
| `hide-filters` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides the site filter dropdown. The dropdown appears beside the navigation hints when search filters are configured in your project settings. See [Search filters](https://docs.biel.ai/customization/search-filters.md). |
| `hide-navigation-buttons` | **Type**: `boolean`**Default value**: `false`When set to `true`, hides navigation buttons (up and down arrows, enter, escape) in the search modal for a simplified interface. |
| `modal-position` | **Type**: `string`**Default value**: `top-center`**Available values:** `center`, `top-center`, `top-left`, `top-right`, `center-left`, `center-right`, `bottom-left`, `bottom-right`, `sidebar-left`, `sidebar-right`Position of the search modal. Use `sidebar-left` or `sidebar-right` to dock as a side panel.|
| `stacked` | **Type**: `boolean`**Default value**: `false`When set to `true`, displays search results in a stacked layout.|
| `clean-titles` | **Type**: `boolean`**Default value**: `false`When set to `true`, removes site names from page titles that follow the format "Page Title | Site Name" for cleaner presentation.|
| **Text** | | |
| `ai-result-fragment` | **Type**: `string`**Default value**: `"Ask AI to answer your question"`Text displayed in the AI result section of the search modal. |
| `all-sites-text` | **Type**: `string`**Default value**: `All sites`Label for the unfiltered option in the site filter dropdown. |
| `search-placeholder` | **Type**: `string`**Default value**: `"Search or ask AI..."`Placeholder for the search input. |
### Search assistant modal properties {#search-chatbot-modal-properties}
Most properties that can be defined in `` for configuring the assistant modal can be set in the `biel-search-button`.
For details, see [Assistant modal properties](#chatbot-modal-properties). Diagram options (`render-diagrams` and `mermaid-theme`) are supported by `` and ``; the search widgets do not expose them.
Use `` directly for `escape-close`, `click-outside-close`, and `show-search-modal`. These properties are not exposed by the `` launcher.
## Common customizations
### Change the assistant title {#change-the-chatbot-title}
By default, the assistant header displays "Company Name AI". Set the `header-title` property to show your own title:
```html
Ask AI
```
### Change the button text
Replace the inner text of the element to change what the button says:
```html
Help
```
### Open the chat modal from a custom element
Use `` directly and set its `show-modal` property from a custom button:
```html
```
Use the equivalent `show-search-modal` property on `` to open search programmatically. The two launcher components open their modals when clicked; assigning these modal properties to a launcher does not open its modal.
---
## Models
Biel.ai supports four models from OpenAI and Anthropic. GPT-6 Luna is the default and is available on every plan. Claude Haiku 5.5 is available on paid plans. GPT-6.1 Sol and Claude Sonnet 5.5 require a Business plan or above.
The Business trial includes all four models. Extra usage does not unlock models outside your plan.
## Available models
| Model | API model ID | Tier |
| --- | --- | --- |
| **GPT-6 Luna (default)** | `gpt-6-luna` | Fast |
| GPT-6.1 Sol | `gpt-6.1-sol` | Advanced |
| Claude Haiku 5.5 | `claude-haiku-5-5` | Fast |
| Claude Sonnet 5.5 | `claude-sonnet-5-5` | Advanced |
Start with GPT-6 Luna for routine documentation questions. Compare an advanced model using representative questions from your own documentation before switching.
## Change the model
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Open **Assistant** in the left sidebar and, under **AI model and instructions** > **Select model**, choose a model from the dropdown.
4. Click **Save** on the AI model and instructions card. Models marked **locked** require an eligible subscription.
## Data privacy
Assistant interactions are opted out of third-party model training by default. Your data is not used to train or improve external AI models.
---
## Reasoning modes
Control how the assistant reasons through questions with three modes: Auto, Instant, and Think.

## Available modes
| Mode | Description | Interactions per question |
|------|-------------|--------------------------|
| **Auto** (default) | Searches documentation using keywords and meaning. If it finds no usable documentation, tries keyword search once with the same question. If no supporting evidence is available, asks for more detail or documentation. | 1 |
| **Instant** | Searches documentation once using keywords and meaning, then writes the answer. | 1 |
| **Think** | Reviews results and can make additional focused searches and read fuller documentation pages before answering. Searches and review rounds are limited. | Up to 10 |
Auto does not automatically switch to Think. Choose Think for questions that may need information from several documentation sections. Additional searches do not guarantee a correct answer.
The interaction counts above cover the base documentation workflow. Enabling [web search](https://docs.biel.ai/customization/web-search.md) can add interactions.
These interactions count toward your team's included allowance. With [extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage) enabled, interactions beyond that allowance cost $0.05 each.
All three modes show the current operation while answering. Progress disappears when the answer finishes. See [Chat progress](https://docs.biel.ai/customization/chat-progress.md) to choose between the default spinner and loading dots.
## Enable reasoning modes
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Open **Assistant** in the left sidebar and find the **AI model and instructions** section.
4. Check **Enable think mode**.

5. Click **Save** on the AI model and instructions card.
Once enabled, users can select their preferred mode from the selector above the chat input. This includes the assistant opened through **Ask AI** in the search widget. The selection persists across page reloads.
## Widget attributes
Control reasoning mode behavior with these attributes on ``, ``, ``, or ``:
| Attribute | Default | Description |
|-----------|---------|-------------|
| `default-think-mode` | `auto` | Starting mode for a new visitor: `auto`, `fast` (shown as Instant), or `think`. A visitor's saved choice takes precedence. |
| `think-mode-enabled` | `false` | Legacy option to start in Think mode. `default-think-mode` takes precedence when both are set. |
| `hide-settings-button` | `false` | Hide the mode selector above the input. On ``, this also hides it after a visitor selects **Ask AI** from search results. An embedded `` currently shows the selector whenever reasoning modes are enabled for the project. |
**Start new visitors in Think mode:**
```html
Ask AI
```
:::tip[Hide the mode selector]
You can combine `default-think-mode` with `hide-settings-button` to hide the selector. A visitor's previously saved choice still takes precedence over the default.
```html
Ask AI
```
:::
---
## Search filters
Search filters let users narrow search results by category. Each filter maps a label to a URL pattern — when selected, only matching results appear.
## Configure filters
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Go to **Settings** > **Search**.
3. Under **Search Filters**, add one or more filters. Each filter requires:
- **Label:** The label shown in the widget (for example, `API`, `Guides`, `Blog`).
- **URL pattern:** A case-insensitive regular expression matched against result URLs. Use `\.` to match a literal dot and `.*` to match any characters. See [Pattern examples](#pattern-examples) for common use cases.

4. Click **Save** on the Search Filters card.
### Pattern examples
| Goal | Pattern | Matches |
| -------------------------- | --------------------- | ------------------------------------------------------------------------------------ |
| Pages under a path | `/docs/api/.*` | `https://example.com/docs/api/overview`, `https://example.com/docs/api/auth/tokens` |
| A specific subdomain | `docs\.example\.com` | `https://docs.example.com/guide`, `https://docs.example.com/api/v2` |
| Any subdomain | `.*\.example\.com` | `https://docs.example.com/guide`, `https://blog.example.com/post` |
| URLs containing a keyword | `release-notes` | `https://example.com/release-notes/v2`, `https://example.com/docs/release-notes` |
## Enable filters in the widget
When you configure filters, the search widget shows a site dropdown beside the navigation hints. The dropdown does not appear if the project has no search filters. It starts at **All sites** and lets visitors choose one of your configured filters.

Use `all-sites-text="All documentation"` to replace the **All sites** label when the dropdown is visible:
```html
Search
```
Set `hide-filters` to `true` to hide the dropdown:
```html
Search
```
## Customize filter appearance
To style the dropdown, use the `--biel-dropdown-*` CSS custom properties. For details, see [Styles](https://docs.biel.ai/customization/styles.md).
## Limitations
- Filters are available in `` and ``, not in the chat widget.
- Each filter title must be unique within a project.
- Filters do not affect the relevance ranking of results.
---
## Search
The search widget finds documentation pages and sections across your indexed website content. Users can select **Ask AI** to turn a question into an assistant conversation.

## How search works
The widget uses keyword search across the page title, description, section headings, keywords, and content. Title matches receive additional weight, and results can link directly to the matching section.
Each successful search counts as one interaction. **Ask AI** uses assistant interactions in addition to the search. Both count toward your team's included allowance and cost $0.05 each beyond that allowance when [extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage) is enabled.
Text relevance is normalized between 0 and 1 before applying boosts. The final score can exceed 1 when a positive boost is added.
You can adjust rankings with a [boost score](#boost-search-results): positive values (e.g., `0.5`) increase a page's ranking, negative values (e.g., `-0.5`) decrease it. The final score is the base score plus the boost.
:::tip
Pages with a combined boost of `-1.0` or lower are excluded from search results. Smaller negative boosts lower their ranking.
:::
## Installation
- [CDN installation guide](https://docs.biel.ai/installation/cdn.md#add-the-search-widget)
- [Platform-specific guides](https://docs.biel.ai/installation.md)
## Customization
### Widget appearance
See [Layout](https://docs.biel.ai/customization/layout.md#biel-search-button) for styling and positioning options.
### Search filters
You can configure filters that let users narrow search results by category (for example, API, Guides, Blog). For details, see [Search filters](https://docs.biel.ai/customization/search-filters.md).
### Metadata and keywords
Add meta tags to improve how your content is indexed and ranked:
```html
```
For Docusaurus, Sphinx, and other documentation systems, see [Metadata by platform](#metadata-by-platform).
### Boost search results
Use boost scores to prioritize certain pages. For example, boost guides by `0.5` so they rank higher, while leaving reference pages at `0` for natural ranking.
If your team has access to **Boost Rules**, open **Settings** > **Search**, add a URL pattern and boost score, and click **Save** on that card. Click **Refresh sources** to apply the rule to indexed pages. A matching rule's boost is added to the page's metadata boost.
Add the following meta tag to the **head** of the page:
```html
```
Click **Refresh sources** after updating page metadata so Biel.ai indexes the change.
For Docusaurus, Sphinx, and other documentation systems, see [Metadata by platform](#metadata-by-platform).
### Metadata by platform
Add the **head** tag directly in your markdown content:
```markdown
---
title: Search Configuration
---
# Search Configuration
Your content here...
```
Use the `meta` directive in your reStructuredText files:
```rst
.. meta::
:description: Learn how to configure and customize your Biel.ai assistant
:keywords: assistant, configuration, customization, Biel.ai, setup
:biel:boost_score: 0.5
Search Configuration
====================
```
## Limitations
The search widget returns website pages. Uploaded files, repository files, and OpenAPI specifications can inform assistant answers but do not appear in the widget's page results. The API and MCP all-content search can retrieve those sources.
---
## Styles
Two approaches for customizing widget styles:
1. **CSS custom properties** — Override colors, fonts, spacing, and sizing.
2. **CSS parts** (advanced) — Target specific elements inside the Shadow DOM.
## CSS custom properties
Define CSS custom properties in your stylesheet using the `:root` selector:
```css
:root {
--biel-primary-color: #00D68F;
--biel-primary-hover-color: #00b77a;
}
```
### Properties
```css
:root {
/* Colors */
--biel-primary-color: #0070F4;
--biel-primary-light-color: #3a99ff;
--biel-primary-hover-color: #005FCC;
--biel-secondary-color: #f9fafb;
--biel-secondary-hover-color: #ebebeb;
--biel-light-color: #ccc;
--biel-border-color: #949494;
--biel-dark-color: #191919;
--biel-dark-hover-color: #333;
--biel-text-color: #5f6368;
--biel-white-color: #fff;
--biel-white-hover-color: var(--biel-secondary-hover-color);
--biel-highlight-color: #ffb422;
--biel-scrollbar-color: #888888;
--biel-scrollbar-hover-color: #666666;
--biel-code-header-color: #3a3a3a;
--biel-code-body-color: #3b3b3b;
--biel-table-header-color: #372b2b;
/* Radii */
--biel-radius-sm: 6px;
--biel-radius-md: 10px;
--biel-radius-lg: 16px;
/* Elevation */
--biel-shadow-1: 0 4px 12px rgba(0, 0, 0, 0.1);
--biel-shadow-2: 0px 4px 6px -1px rgba(0, 0, 0, 0.1), 0px 2px 4px -1px rgba(0, 0, 0, 0.06);
/* Tooltip */
--biel-tooltip-bg: var(--biel-dark-color);
--biel-tooltip-text: var(--biel-white-color);
/* Fonts */
--biel-font-family: "Inter", "Tahoma", "sans-serif";
--biel-text-sm-font-size: 12px;
--biel-text-font-size: 14px;
--biel-text-lg-font-size: 16px;
--biel-control-font-size: var(--biel-text-font-size);
--biel-text-xl-font-size: 18px;
--biel-text-xxl-font-size: 20px;
--biel-code-snippet-font-family: "Courier New", "Courier", "monospace";
/* Biel button */
--biel-button-border-radius: 20px;
--biel-button-box-shadow: rgba(60, 64, 67, 0.3) 0px 1px 2px 0px, rgba(60, 64, 67, 0.15) 0px 2px 6px 2px;
--biel-button-dark-bg-color: var(--biel-primary-color);
--biel-button-dark-bg-color-hover: var(--biel-primary-hover-color);
--biel-button-dark-text-color: var(--biel-white-color);
--biel-button-icon-size: 20px;
--biel-button-light-bg-color: var(--biel-white-color);
--biel-button-light-bg-color-hover: var(--biel-white-hover-color);
--biel-button-light-text-color: var(--biel-primary-color);
--biel-button-text-font-size: var(--biel-text-lg-font-size);
--biel-button-text-font-weight: 400;
--biel-button-padding: 8px 15px;
--biel-button-position-top: 15px;
--biel-button-position-bottom: 15px;
--biel-button-position-left: 15px;
--biel-button-position-right: 15px;
--biel-button-z-index: auto;
/* Biel bot */
--biel-bot-close-bg-color: var(--biel-white-color);
--biel-bot-close-color: var(--biel-dark-color);
--biel-bot-content-bg-color: var(--biel-white-color);
--biel-bot-screenshot-bg-color: transparent;
--biel-bot-content-border-color: rgba(0, 0, 0, 0.08);
--biel-bot-content-border-radius: 12px;
--biel-bot-content-box-shadow: var(--biel-shadow-2);
--biel-bot-content-font-family: var(--biel-font-family);
--biel-bot-content-position-bottom: 10px;
--biel-bot-content-position-left: 10px;
--biel-bot-content-position-right: 10px;
--biel-bot-content-position-top: 10px;
--biel-bot-content-max-width: 600px;
--biel-bot-content-text-color: var(--biel-text-color);
--biel-bot-wrapper-z-index: auto;
--biel-bot-content-z-index: 300;
/* Biel bot chat */
--biel-chat-scrollbar-color: var(--biel-scrollbar-color);
--biel-chat-scrollbar-hover-color: var(--biel-scrollbar-hover-color);
--biel-chat-embedded-height: 450px;
--biel-loading-dot-color: var(--biel-footer-action-color);
--biel-activity-text-color: var(--biel-text-color);
--biel-activity-accent-color: var(--biel-primary-color);
--biel-activity-border-color: var(--biel-border-color);
--biel-activity-spinner-color: var(--biel-primary-color);
/* Biel bot header */
--biel-header-font-family: var(--biel-font-family);
--biel-header-font-size: var(--biel-text-xl-font-size);
--biel-header-font-weight: 600;
--biel-header-powered-by-font-weight: 400;
--biel-header-powered-by-text-color: var(--biel-text-color);
--biel-header-powered-by-link-color: var(--biel-dark-color);
--biel-header-text-color: var(--biel-dark-color);
--biel-header-border-color: var(--biel-light-color);
/* Biel input options dropdown */
--biel-dropdown-bg-color: var(--biel-white-color);
--biel-dropdown-border-color: var(--biel-light-color);
--biel-dropdown-hover-bg-color: var(--biel-secondary-color);
--biel-dropdown-selected-bg-color: var(--biel-white-hover-color);
--biel-dropdown-selected-hover-bg-color: var(--biel-secondary-hover-color);
--biel-dropdown-text-color: var(--biel-dark-hover-color);
--biel-dropdown-text-secondary-color: var(--biel-text-color);
/* Biel bot message */
--biel-message-biel-text-color: var(--biel-dark-color);
--biel-message-user-text-color: var(--biel-white-color);
--biel-message-biel-bg-color: var(--biel-secondary-color);
--biel-message-user-bg-color: var(--biel-primary-color);
--biel-message-avatar-width: 20px;
--biel-message-avatar-height: 20px;
--biel-message-padding: 10px;
--biel-message-avatar-margin-right: 10px;
--biel-message-border-radius: 10px;
--biel-message-code-font-size: 14px;
--biel-message-code-bg-color: var(--biel-code-body-color);
--biel-message-code-inline-text-color: var(--biel-dark-color);
--biel-message-code-inline-bg-color: var(--biel-white-hover-color);
--biel-message-code-inline-border-radius: 4px;
--biel-message-font-size: var(--biel-text-font-size);
--biel-message-label-font-size: var(--biel-text-sm-font-size);
--biel-message-h1-font-size: var(--biel-text-xxl-font-size);
--biel-message-h2-font-size: var(--biel-text-xl-font-size);
--biel-message-h3-font-size: var(--biel-text-lg-font-size);
--biel-message-h4-font-size: var(--biel-text-lg-font-size);
--biel-message-h5-font-size: var(--biel-text-lg-font-size);
--biel-message-h6-font-size: var(--biel-text-lg-font-size);
--biel-message-link-color: var(--biel-primary-light-color);
--biel-message-source-font-size: 14px;
--biel-message-source-bg-color: var(--biel-white-hover-color);
--biel-message-source-bg-hover-color: var(--biel-light-color);
--biel-message-source-text-color: var(--biel-dark-color);
/* Inline citations */
--biel-citation-bg-color: var(--biel-message-source-bg-color);
--biel-citation-bg-hover-color: var(--biel-message-source-bg-hover-color);
--biel-citation-text-color: var(--biel-message-source-text-color);
--biel-citation-text-hover-color: var(--biel-message-source-text-color);
--biel-citation-font-size: 0.75em;
/* Action buttons */
--biel-action-bg-color: var(--biel-message-source-bg-color);
--biel-action-bg-hover-color: var(--biel-message-source-bg-hover-color);
--biel-action-text-color: var(--biel-message-source-text-color);
--biel-action-text-hover-color: var(--biel-message-source-text-color);
--biel-action-font-size: var(--biel-message-source-font-size);
/* Answer continuation and diagram dialog */
--biel-continue-button-bg-color: var(--biel-white-hover-color);
--biel-continue-button-bg-color-hover: var(--biel-light-color);
--biel-continue-button-color: var(--biel-dark-color);
--biel-diagram-dialog-bg-color: var(--biel-bot-content-bg-color);
/* Biel bot input */
--biel-input-color: var(--biel-dark-color);
--biel-input-button-color: var(--biel-white-color);
--biel-input-button-bg-color: var(--biel-primary-color);
--biel-input-button-border-color: var(--biel-dark-color);
--biel-input-button-hover-color: var(--biel-white-color);
--biel-input-button-hover-bg-color: var(--biel-primary-hover-color);
--biel-input-button-hover-border-color: var(--biel-primary-hover-color);
--biel-input-border-color: #d8dee7;
--biel-input-border-radius: 6px;
--biel-input-border-focus-color: var(--biel-primary-color);
--biel-input-font-family: var(--biel-font-family);
--biel-input-textarea-max-height: 114px;
--biel-input-textarea-min-height: 19px;
/* Biel bot input options */
--biel-input-options-font-size: 13px;
--biel-input-options-button-hover-bg-color: var(--biel-dropdown-hover-bg-color);
--biel-input-options-button-hover-border-color: var(--biel-input-border-color);
--biel-input-options-button-focus-border-color: var(--biel-input-border-focus-color);
/* Biel bot code snippet */
--biel-code-snippet-header-text-color: var(--biel-light-color);
--biel-code-snippet-content-text-color: var(--biel-white-color);
--biel-code-snippet-header-bg-color: var(--biel-code-header-color);
--biel-code-snippet-content-bg-color: var(--biel-dark-color);
--biel-code-snippet-font-size: var(--biel-text-font-size);
/* Biel bot table */
--biel-table-th-bg-color: var(--biel-table-header-color);
--biel-table-bg-color: var(--biel-dark-color);
--biel-table-content-text-color: var(--biel-white-color);
/* Biel bot suggested questions */
--biel-suggested-questions-border-radius: 8px;
--biel-suggested-questions-bg-color: var(--biel-white-color);
--biel-suggested-questions-bg-hover-color: var(--biel-primary-color);
--biel-suggested-questions-border-color: var(--biel-primary-color);
--biel-suggested-questions-padding: 8px 12px;
--biel-suggested-questions-text-color: var(--biel-dark-color);
--biel-suggested-questions-text-hover-color: var(--biel-white-color);
--biel-suggested-questions-title-font-size: var(--biel-text-sm-font-size);
--biel-suggested-questions-font-size: var(--biel-text-font-size);
/* Biel bot feedback */
--biel-feedback-bg-color: var(--biel-white-hover-color);
--biel-feedback-bg-hover-color: var(--biel-light-color);
--biel-feedback-background-selected-color: var(--biel-primary-color);
--biel-feedback-text-color: var(--biel-dark-color);
--biel-feedback-text-selected-color: var(--biel-white-color);
/* Biel bot footer */
--biel-footer-font-size: var(--biel-text-sm-font-size);
--biel-bot-footer-link: inherit;
/* Biel answer footer (sources toggle + copy + thumbs row) */
--biel-footer-action-color: var(--biel-text-color);
--biel-footer-action-copied-color: var(--biel-primary-color);
--biel-footer-action-hover-bg: var(--biel-message-source-bg-color);
--biel-footer-thumb-selected-bg: var(--biel-feedback-background-selected-color);
--biel-footer-thumb-selected-color: var(--biel-feedback-text-selected-color);
/* Biel sources toggle */
--biel-source-toggle-bg: var(--biel-white-color);
--biel-source-toggle-border: var(--biel-input-border-color);
--biel-source-toggle-border-hover-color: var(--biel-input-border-color);
/* Biel source cards (expanded sources panel) */
--biel-source-card-bg: var(--biel-white-color);
--biel-source-card-icon-color: var(--biel-text-color);
--biel-source-card-border: var(--biel-search-result-border-color);
--biel-source-card-border-hover-color: var(--biel-primary-color);
--biel-source-card-title-color: var(--biel-message-source-text-color);
--biel-source-card-host-color: var(--biel-text-color);
/* Biel search button */
--biel-search-button-text-display: none;
--biel-search-button-ctrl-k-display: none;
--biel-search-button-border-radius: 20px;
--biel-search-button-border-color: var(--biel-light-color);
--biel-search-button-bg-color: var(--biel-white-color);
--biel-search-button-text-color: var(--biel-dark-color);
--biel-search-button-icon-size: 20px;
--biel-search-button-width: 100%;
--biel-search-button-max-width: fit-content;
--biel-search-button-padding: 8px;
--biel-search-button-icon-margin-right: 0px;
--biel-search-button-text-font-size: var(--biel-text-lg-font-size);
--biel-search-button-text-font-weight: 400;
--biel-search-button-z-index: 300;
/* Biel search */
--biel-search-content-bg-color: var(--biel-white-color);
--biel-search-content-border-color: rgba(0, 0, 0, 0.08);
--biel-search-content-border-radius: 12px;
--biel-search-content-box-shadow: var(--biel-shadow-2);
--biel-search-content-font-family: var(--biel-font-family);
--biel-search-content-max-width: 700px;
--biel-search-content-max-height: 100dvh;
--biel-search-content-position-bottom: 10px;
--biel-search-content-position-left: 10px;
--biel-search-content-position-right: 10px;
--biel-search-content-position-top: 10px;
--biel-search-content-position-top-center: 50px;
--biel-search-content-text-color: var(--biel-dark-color);
--biel-search-content-z-index: 300;
--biel-search-body-max-height: calc(80dvh - 30px);
/* Biel search result */
--biel-search-result-bg-color: transparent;
--biel-search-result-bg-hover-color: var(--biel-input-options-button-hover-bg-color);
--biel-search-result-bg-selected-color: var(--biel-input-options-button-hover-bg-color);
--biel-search-result-border-radius: 6px;
--biel-search-result-border-color: var(--biel-light-color);
--biel-search-result-border-hover-color: var(--biel-primary-color);
--biel-search-result-description-color: var(--biel-scrollbar-hover-color);
--biel-search-result-mark-color: var(--biel-primary-color);
--biel-search-result-padding: 10px 8px;
--biel-search-result-title-color: var(--biel-dark-color);
--biel-search-result-title-font-size: var(--biel-text-xl-font-size);
--biel-search-result-description-font-size: calc(var(--biel-text-lg-font-size) - 2px);
--biel-search-result-description-line-height: 1.4;
--biel-search-line-height: 1;
/* Biel search ask ai button */
--biel-search-ask-ai-bg-color: var(--biel-primary-color);
--biel-search-ask-ai-border-color: var(--biel-search-result-border-color);
--biel-search-ask-ai-border-hover-color: var(--biel-primary-color);
--biel-search-ask-ai-border-radius: 8px;
--biel-search-ask-ai-color: var(--biel-white-color);
/* Biel search filters */
--biel-search-filter-color: var(--biel-dark-color);
--biel-search-filter-selected-color: var(--biel-white-color);
--biel-search-filter-bg-color: var(--biel-white-color);
--biel-search-filter-selected-bg-color: var(--biel-primary-color);
--biel-search-filter-border-color: var(--biel-white-hover-color);
--biel-search-filter-hover-color: var(--biel-white-hover-color);
--biel-search-filter-selected-border-color: var(--biel-primary-color);
--biel-search-filter-trigger-border-hover-color: var(--biel-input-border-color);
/* Biel search footer */
--biel-search-footer-command-key-border-color: var(--biel-header-border-color);
/* Biel search toctree */
--biel-search-toctree-page-bg-color: var(--biel-search-result-bg-hover-color);
--biel-search-toctree-page-border-color: var(--biel-light-color);
--biel-search-toctree-page-border-hover-color: var(--biel-primary-color);
--biel-search-toctree-page-text-color: var(--biel-dark-color);
--biel-search-toctree-count-color: var(--biel-scrollbar-hover-color);
--biel-search-toctree-border-color: var(--biel-light-color);
--biel-search-toctree-page-title-font-size: var(--biel-text-xl-font-size);
--biel-search-toctree-page-title-font-weight: 500;
--biel-search-toctree-count-font-size: var(--biel-text-sm-font-size);
--biel-search-toctree-title-height: 100%;
/* Biel terms modal */
--biel-terms-modal-color: var(--biel-dark-color);
--biel-terms-modal-bg-color: var(--biel-white-color);
--biel-terms-modal-box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
--biel-terms-modal-link-color: var(--biel-primary-light-color);
--biel-terms-modal-accept-btn-bg-color-disabled: var(--biel-primary-light-color);
--biel-terms-modal-accept-btn-color-disabled: var(--biel-white-color);
--biel-terms-modal-accept-btn-bg-color: var(--biel-primary-color);
--biel-terms-modal-accept-btn-color: var(--biel-white-color);
--biel-terms-modal-accept-btn-bg-color-hover: var(--biel-primary-hover-color);
--biel-terms-modal-decline-btn-bg-color: var(--biel-white-hover-color);
--biel-terms-modal-decline-btn-hover-bg-color: var(--biel-light-color);
--biel-terms-modal-decline-btn-color: var(--biel-dark-color);
--biel-terms-modal-close-btn-color: var(--biel-footer-action-color);
--biel-terms-modal-close-btn-color-hover: var(--biel-terms-modal-color);
}
[data-theme='dark'] {
--biel-border-color: #6b6b6b;
--biel-tooltip-bg: #2a2a2a;
--biel-tooltip-text: var(--biel-white-color);
--biel-text-color: #b0b8c4;
--biel-scrollbar-color: #555555;
--biel-scrollbar-hover-color: #333333;
--biel-bot-button-bg-color-active: transparent;
--biel-bot-button-icon-color: var(--biel-white-color);
--biel-bot-button-text-color: var(--biel-white-color);
--biel-header-text-color: var(--biel-white-color);
--biel-bot-close-bg-color: transparent;
--biel-bot-close-color: var(--biel-white-color);
--biel-bot-content-bg-color: var(--biel-dark-color);
--biel-bot-content-border-color: rgba(255, 255, 255, 0.1);
--biel-bot-content-text-color: var(--biel-text-color);
--biel-header-border-color: #363636;
--biel-header-powered-by-link-color: var(--biel-white-color);
--biel-dropdown-bg-color: var(--biel-message-biel-bg-color);
--biel-dropdown-border-color: var(--biel-header-border-color);
--biel-dropdown-hover-bg-color: var(--biel-feedback-bg-color);
--biel-dropdown-selected-bg-color: var(--biel-feedback-bg-hover-color);
--biel-dropdown-selected-hover-bg-color: var(--biel-message-source-bg-hover-color);
--biel-dropdown-text-color: var(--biel-white-color);
--biel-dropdown-text-secondary-color: var(--biel-text-color);
--biel-input-color: var(--biel-white-color);
--biel-input-border-color: var(--biel-border-color);
--biel-input-border-focus-color: var(--biel-primary-light-color);
--biel-input-button-color: var(--biel-white-color);
--biel-input-button-bg-color: var(--biel-primary-color);
--biel-input-button-border-color: var(--biel-primary-color);
--biel-input-button-hover-color: var(--biel-white-color);
--biel-input-button-hover-bg-color: var(--biel-primary-hover-color);
--biel-input-button-hover-border-color: var(--biel-primary-hover-color);
--biel-input-options-button-hover-bg-color: var(--biel-dropdown-hover-bg-color);
--biel-input-options-button-focus-border-color: var(--biel-input-border-focus-color);
--biel-message-biel-text-color: var(--biel-white-color);
--biel-message-biel-bg-color: #2a2a2a;
--biel-message-user-text-color: var(--biel-white-color);
--biel-message-user-bg-color: #2a2a2a;
--biel-message-source-color: var(--biel-white-hover-color);
--biel-message-source-bg-color: #3a3a3a;
--biel-message-source-bg-hover-color: #4a4a4a;
--biel-message-source-text-color: var(--biel-white-color);
--biel-message-source-link-color: var(--biel-primary-color);
--biel-source-card-bg: var(--biel-message-biel-bg-color);
--biel-source-card-border: var(--biel-source-toggle-border);
--biel-source-toggle-bg: var(--biel-message-biel-bg-color);
--biel-source-toggle-border: var(--biel-input-border-color);
--biel-suggested-questions-text-color: var(--biel-white-color);
--biel-suggested-questions-bg-color: var(--biel-dark-color);
--biel-feedback-bg-color: #3a3a3a;
--biel-feedback-bg-hover-color: #4a4a4a;
--biel-feedback-text-color: var(--biel-white-color);
--biel-search-button-bg-color: var(--biel-dark-color);
--biel-search-button-text-color: var(--biel-white-color);
--biel-search-button-border-color: var(--biel-primary-color);
--biel-search-content-text-color: var(--biel-text-color);
--biel-search-content-bg-color: var(--biel-dark-color);
--biel-search-content-border-color: rgba(255, 255, 255, 0.1);
--biel-search-result-bg-color: transparent;
--biel-search-result-bg-hover-color: var(--biel-input-options-button-hover-bg-color);
--biel-search-result-bg-selected-color: var(--biel-input-options-button-hover-bg-color);
--biel-search-result-border-color: #363636;
--biel-search-ask-ai-border-color: var(--biel-search-result-border-color);
--biel-search-result-title-color: var(--biel-white-color);
--biel-search-result-description-color: var(--biel-text-color);
--biel-search-result-mark-color: var(--biel-primary-light-color);
--biel-code-snippet-header-text-color: var(--biel-text-color);
--biel-code-snippet-text-color: var(--biel-white-color);
--biel-search-filter-color: var(--biel-white-color);
--biel-search-filter-selected-color: var(--biel-white-color);
--biel-search-filter-bg-color: var(--biel-dark-color);
--biel-search-filter-selected-bg-color: var(--biel-primary-color);
--biel-search-filter-border-color: #3a3a3a;
--biel-search-filter-hover-color: #3a3a3a;
--biel-search-filter-selected-border-color: var(--biel-primary-color);
--biel-terms-modal-bg-color: var(--biel-dark-color);
--biel-terms-modal-color: var(--biel-white-color);
--biel-terms-modal-close-btn-color: var(--biel-footer-action-color);
--biel-terms-modal-close-btn-color-hover: var(--biel-terms-modal-color);
--biel-search-toctree-page-bg-color: var(--biel-search-result-bg-hover-color);
--biel-search-toctree-page-border-color: var(--biel-search-result-border-color);
--biel-search-toctree-page-text-color: var(--biel-white-color);
--biel-search-toctree-count-color: var(--biel-text-color);
--biel-search-toctree-border-color: var(--biel-search-result-border-color);
}
@media (min-width: 768px) {
:root {
--biel-search-button-text-display: block;
--biel-search-button-ctrl-k-display: block;
--biel-search-button-padding: 8px 15px;
--biel-search-button-icon-margin-right: 5px;
--biel-search-content-max-height: 80dvh;
--biel-search-body-max-height: 50dvh;
}
}
```
## CSS parts
For fine-grained control, the widget exposes CSS parts that let you style elements inside the Shadow DOM using the `::part()` pseudo-element.
**Syntax:**
```css
/* Styling a component's own parts */
component-name::part(part-name) {
/* your styles */
}
/* Styling nested component parts (with prefix) */
parent-component::part(child-component-part-name) {
/* your styles */
}
```
**Naming conventions:**
- **Direct parts** use simple names: `biel-bot::part(modal)`, `biel-button::part(button)`
- **Nested parts** use prefixed names: `biel-bot::part(biel-message-bubble)`, `biel-search::part(biel-search-result-title)`
### Finding available parts
1. Right-click the widget and select **Inspect**.
2. Expand the `#shadow-root` inside the component tag.
3. Look for elements with `part="..."` attributes.
### Examples
#### Custom biel button
```css
/* Square button with custom color */
biel-button::part(button) {
border-radius: 8px;
background-color: #ff5722;
color: white;
box-shadow: 0 4px 12px rgba(255, 87, 34, 0.3);
transition: all 0.2s ease;
}
/* Hover effect */
biel-button::part(button):hover {
background-color: #f4511e;
transform: translateY(-2px);
}
```
---
## Suggested questions
Suggested questions are clickable prompts that appear when a user opens the assistant. Use them to surface common queries so users don't have to type from scratch.
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
## Add suggested questions
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Open **Assistant** in the left sidebar and, under **Conversation** > **Suggested questions**, enter your questions. Click **Add question** to add more.
4. Click **Save** on the Conversation card.
Open the assistant on your site to verify the suggested questions appear as clickable options.
---
## Web search (beta)
Augment assistant answers with real-time results from the internet when your documentation does not fully cover a question.
:::warning
Enabling web search means your assistant can return answers your team did not write, review, or approve.
Responses may be inaccurate, outdated, or inconsistent with your product's terminology and tone, and you have limited control over which sources are used.
:::
## How it works
When web search is enabled, the assistant first looks for an answer in your documentation.
If the documentation is not enough, it searches the web and combines both sources in the response.
A web search is triggered when the assistant decides it needs outside information. Running the web search adds five interactions to the question's base usage, even if it returns no usable content. An Auto or Instant question with web search therefore uses six interactions. Think mode can use more.
Web-search interactions count toward your team's included allowance. With [extra usage](https://docs.biel.ai/administration/subscription.md#extra-usage) enabled, interactions beyond that allowance cost $0.05 each.
## Before you enable web search
Web search is a fallback, not a substitute for good documentation.
Before turning it on, consider whether the gap is better closed by improving your docs:
- **Accuracy:** Web sources may contradict your documentation, reference outdated versions of your product, or surface answers from competitors and unofficial forums.
- **Brand voice:** Answers pulled from the web will not match your product's terminology, tone, or style.
- **Support burden:** Incorrect answers sourced from the web can generate support tickets that are harder to trace, since the source is not under your control.
In most cases, expanding your documentation is the safer long-term choice.
Web search is most appropriate for narrow, well-defined gaps such as third-party integrations or ecosystem topics that are not worth maintaining in your own docs.
You can constrain web search behavior by extending your project's prompt, for example by restricting which topics the assistant should answer from the web, instructing it to prefer official sources, or requiring it to flag when an answer comes from outside your documentation.
See [Custom prompt](https://docs.biel.ai/customization/custom-prompt.md) for details.
## Enable web search
:::important
Only **Administrator** or **Maintainer** roles can manage projects. See [Manage roles](https://docs.biel.ai/administration/roles.md).
:::
1. In the [Biel.ai dashboard](https://app.biel.ai), select your project.
2. Click **Settings**.
3. Open **Assistant** in the left sidebar and, under **AI model and instructions**, check **Enable web search**.

4. Click **Save** on the AI model and instructions card.
---
## Workflows (Enterprise)
# Workflows (Agentic RAG for Documentation)
:::info Archived guide
This page preserves a historical workflow overview. Its builder, routing, and deployment instructions do not describe the current Biel.ai dashboard. To configure your assistant today, use [Projects](https://docs.biel.ai/administration/projects.md) and [Actions](https://docs.biel.ai/customization/actions.md). For enterprise orchestration requirements, [contact us](https://biel.ai/contact).
:::
Workflows connect multiple Biel.ai projects into a single assistant interface. Each project covers a specific domain, and a router directs queries to the most appropriate one. Projects maintain their own sources, model configuration, and custom prompts.
:::important
This feature is available exclusively on **Enterprise** plans. [Contact us](https://biel.ai/contact) to learn more about enterprise solutions.
:::
## How workflows work
**Single project:**
```mermaid
graph LR
A[User Query] --> B[Single Knowledge Base]
B --> C[LLM]
C --> D[Response]
```
**Workflow with routing and actions:**
```mermaid
graph TB
A[User Query] --> B[Router Agent]
B -->|Routes to| C[Python Docs Agent]
B -->|Routes to| D[Java Docs Agent]
B -->|Routes to| E[API Reference Agent]
C --> F[Response]
D --> F
E --> F
F --> G[Action Triggers]
G -->|Optional| H[Create Ticket]
G -->|Optional| I[Send to Slack]
G -->|Optional| J[Schedule Meeting]
```
The router analyzes each query and directs it to the appropriate agent. Agents can also trigger external actions (tickets, notifications, etc.) based on conversation context.
## When to use workflows
| Scenario | Example | Why workflows help |
|----------|---------|-------------------|
| Multiple languages/SDKs | Python, JavaScript, Java docs | Users only see relevant examples |
| Multiple products | Product A (analytics), Product B (collaboration) | Focused responses without cross-contamination |
| Different doc types | API reference, user guides, admin docs | Routes technical queries to API docs, UI questions to guides |
| Large doc sets (1000+ pages) | Enterprise documentation | Splitting by domain improves accuracy |
| Custom actions | Bug reports → Zendesk, demo requests → Calendly | Trigger integrations based on conversation context |
Use a single project instead if your docs are under 1000 pages, cover one cohesive topic, and don't need external integrations.
## Setting up a workflow
:::tip Enterprise setup included
As part of your enterprise agreement, our team handles the initial workflow configuration to ensure everything works correctly from the start.
We'll work with you to define routing rules, configure integrations, and test the setup before going live.
:::
### Prerequisites
- At least two existing projects with indexed content.
- (Optional) Webhook endpoints for custom actions.
### Create your workflow
1. In the [Biel.ai dashboard](https://app.biel.ai), click **Workflows** > **Create workflow**.
2. Enter a **Name** and optional **Description**.
3. Click **Create**.
### Add projects
1. In your workflow settings, navigate to the **Projects** section.
2. Click **Add project**.
3. Select a project from your existing projects.
4. Define when this project should be used:
- **Keywords**: Terms that indicate this project should handle the query
- **Topics**: High-level categories this project covers
- **Priority**: Ranking when multiple projects could match
5. Repeat for each project you want to include.
6. Click **Save**.
### Configure routing rules
1. Navigate to **Routing rules** in your workflow settings.
2. Click **Add rule**.
3. Define your rule:
```
Name: API Questions
Condition: Query contains ["API", "endpoint", "authentication", "integration"]
Action: Route to "Developer Documentation" project
Priority: High
```
4. Add multiple rules to cover different scenarios.
5. Set a fallback strategy:
- **Query all projects**: Combines responses from all relevant projects
- **Default project**: Routes to a general knowledge project
- **Request clarification**: Asks the user to rephrase
6. Click **Save**.
### Set up custom actions (optional)
1. Navigate to **Actions** in your workflow settings.
2. Click **Add action**.
3. Configure your action:
- **Action type**: Slack, Microsoft Teams, Email, Zendesk, Webhook, or other available integrations.
- **Trigger condition**: When this action should fire.
- **Configuration**: Credentials and integration details.
4. Click **Save**.
## Test your workflow
1. In the workflow dashboard, click **Test**.
2. Enter sample queries that should trigger different projects, including edge cases and action triggers.
3. Review routing decisions and responses.
4. Adjust rules and priorities as needed.
## Deploy your workflow
1. In your workflow settings, navigate to **Deployment**.
2. Copy the embed code and add it to your website.
## Supported integrations
| Category | Platforms |
|----------|-----------|
| Communication | Slack, Microsoft Teams, Email, Discord |
| Ticketing | Zendesk, Jira, ServiceNow, Freshdesk |
| CRM | Salesforce, HubSpot |
| Scheduling | Calendly, Cal.com |
| Analytics | Segment, Mixpanel, Google Analytics |
| Custom | Any HTTP endpoint via webhooks |
---
## Customization
Configure the Biel.ai widget appearance, behavior, and AI settings.
Widget
Configure widget properties and positioning
Styles
Customize colors, fonts, and CSS
Dark mode
Enable dark mode support
Initial message
Set the assistant greeting message
Suggested questions
Add clickable question prompts
Actions
Define clickable action buttons based on conversation triggers
Models
Choose the AI model
Prompt
Configure AI behavior and response style
Reasoning modes
Control reasoning depth (Auto, Instant, Think)
Chat progress
Choose the progress spinner or loading dots
Web search
Augment answers with real-time results from the internet
Data privacy
PII redaction, IP collection, Terms & Conditions
Search
Configure search ranking and metadata
Search filters
Add category filters to search results
Embedded mode
Render the assistant inline in your page
---
## Ask AI assistant widget for Antora
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Antora documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **An Antora documentation site** ready to install Biel.ai.
## Add the assistant widget {#add-the-chatbot-widget}

1. Modify the UI bundle:
* If you're using a custom UI bundle for your Antora project, navigate to the UI bundle's directory.
* Otherwise, clone Antora's default UI bundle with the following command:
```bash
git clone https://gitlab.com/antora/antora-ui-default.git
```
1. Locate the `head.hbs` file, which is usually under `src/partials`, and insert the following code:
```html
```
1. Locate the `footer.hbs` or the specific file where you'd like the assistant to appear. Just before the closing tags in that file, add the following snippet:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
1. Build and verify your project:
* Re-bundle your custom UI and run the Antora build command.
* If using the default UI, you'd have to integrate it as a local UI and then run Antora with the `--ui-bundle-url` flag to point to your modified local UI bundle.
* Once built, ensure the assistant is functioning correctly on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Astro
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Astro site using the `astro-biel` integration.
:::tip Building with Starlight?
Use the dedicated [Starlight plugin](https://docs.biel.ai/installation/starlight.md) instead.
:::
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
- An Astro site.
- Node.js installed.
## Add the assistant widget {#add-the-chatbot-widget}
The `astro-biel` integration adds a floating chat button to every page. It works with any template or UI framework and survives client-side navigation with Astro's ClientRouter.

1. Install the integration:
```console
npm install astro-biel
```
2. Add it to your `astro.config.mjs`:
```js
export default defineConfig({
integrations: [
biel({
project: '',
headerTitle: 'Biel.ai assistant',
}),
],
})
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Run `npm run dev` and verify the chat button appears in the bottom-right corner.
## Customization
Pass [layout options](https://docs.biel.ai/customization/layout.md) to the integration as camelCase properties:
```js
biel({
project: '',
bielButtonText: 'Ask AI',
buttonPosition: 'bottom-right',
modalPosition: 'bottom-right',
buttonStyle: 'dark',
headerTitle: 'Documentation AI',
})
```
Set `enable: false` to turn the widget off without removing the configuration.
## Add the search widget
The search widget renders an AI search input you can place anywhere in your layout. The `astro-biel` integration loads the required assets.

Install and configure the integration:
```console
npm install astro-biel
```
In `astro.config.mjs`, append Biel to your existing integrations:
```js
export default defineConfig({
integrations: [biel({ project: '' })],
})
```
Add the element to your layout's header (or any component):
```html
Search
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
## Alternative: layout tags
If you prefer not to use the integration, add the tags to your layout manually.
1. Locate the `src/layouts/Layout.astro` file (or any layout file that wraps your pages) and insert the following code within the **head** section:
```html
```
2. Just before the closing **body** tag of your layout file, add the following snippet:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Open the website in a web browser to verify the assistant appears and works correctly.
## Next steps
- [View the `astro-biel` source and releases](https://github.com/TechDocsStudio/astro-biel).
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Basic installation
Add a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to any HTML site. This method uses CDN-hosted components — no build tools or package managers required.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
## Add the assistant widget {#add-the-chatbot-widget}
The `` component adds a floating chat button to your site.

1. Add the following inside the **head** section of your HTML:
```html
```
2. Add the following just before the closing **body** tag:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Open the page in a browser to verify the assistant appears in the bottom-right corner.
## Add the search widget
The `` component adds an AI-powered search bar instead of (or alongside) the assistant.

1. Add the following inside the **head** section of your HTML:
```html
```
2. Add the following where you want the search button to appear:
```html
Search
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Open the page in a browser to verify the search widget works.
## Select a widget version
The links above omit a version, which is equivalent to `biel-search@latest`. The browser loads the latest published npm release from jsDelivr. It can change without rebuilding your site, although CDN caching means a new release may not appear immediately.
To use a specific release, include the same version in both asset URLs:
```html
```
Replace `0.1.93` with your chosen release. Remove the version, or use `@latest`, to follow new releases again. See jsDelivr's [versioning](https://github.com/jsdelivr/jsdelivr#npm) and [caching](https://github.com/jsdelivr/jsdelivr#caching) documentation.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Confluence
Use a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to answer questions from indexed Confluence content on a website you control.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/) and a [project](https://docs.biel.ai/quickstart.md).
- A Confluence Cloud space and credentials for pages you want to index.
- A website that allows custom JavaScript to host the widget.
## Add the assistant widget {#add-the-chatbot-widget}

Confluence Cloud has no native **Custom HTML** setting for injecting these scripts. Atlassian's [Custom HTML feature request](https://jira.atlassian.com/browse/CONFCLOUD-72750) documents this limitation.
1. Connect your space using [Confluence as a data source](https://docs.biel.ai/customization/data-sources/confluence.md). Save the source and click **Refresh sources** to index it.
2. On your external website, add these dependencies inside the **head**:
```html
```
3. Add the assistant before the closing **body** tag:
```html
Ask AI
```
Replace `` with your project's ID from the Biel.ai installation code.
4. Publish the external page and test a question about your indexed Confluence content. Link to that page from your space.
## Limitations
- Indexing Confluence content does not install a widget inside Confluence Cloud.
- Confluence page permissions are not inherited by the external widget. Configure [access control](https://docs.biel.ai/customization/data-sources/private-content.md) for its readers.
- Confluence Data Center customization is a separate setup and is not covered by this Cloud guide.
## Troubleshooting
**Custom HTML not available**
This is expected in Confluence Cloud. Host the widget on a site that permits custom JavaScript.
**Assistant not answering questions**
Check the project dashboard's loading status and **Logs**. Verify that the source credentials can read the pages you want indexed.
**Assistant not appearing on the external site**
Check that its CSS and JavaScript load, and that the project ID matches the installation code.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Docusaurus
Add a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Docusaurus v3 site using the `docusaurus-biel` plugin.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
- A Docusaurus v3 site.
- Node.js installed.
## Add the assistant widget {#add-the-chatbot-widget}
The `docusaurus-biel` plugin adds a floating chat button to your site.

1. Install the plugin:
```console
npm install docusaurus-biel
```
2. Add the plugin to `docusaurus.config.js`:
```js
plugins: [
[
'docusaurus-biel',{
project: '',
headerTitle: 'Biel.ai assistant',
version: 'latest'
}
]
],
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Run `npm start` and verify the assistant appears on your site.
## Select a widget version
The plugin loads the widget's JavaScript and CSS from the CDN using `latest` by default. You do not need to install `biel-search` separately. This follows the latest published widget release, independently of your npm lockfile.
To use a specific release, set `version` in `docusaurus.config.js` and rebuild your site:
```js
plugins: [
['docusaurus-biel', {
project: '',
version: '0.1.93',
}],
],
```
Replace `0.1.93` with your chosen release. Use `version: 'latest'` to follow new releases again. See [CDN version selection](https://docs.biel.ai/installation/cdn.md#select-a-widget-version) for how caching affects `latest`.
## Customization
Pass [layout options](https://docs.biel.ai/customization/layout.md) to the plugin as camelCase properties:
```js
plugins: [
[
'docusaurus-biel',{
enable: true,
project: '',
bielButtonText: 'ASK AI',
buttonPosition: 'center-right',
modalPosition: 'sidebar-right',
headerTitle: 'Biel.ai assistant',
buttonStyle: 'dark',
}
]
],
```
To override the widget's styles (colors, fonts, etc.), add CSS custom properties to your `src/css/custom.css` file:
```css
:root {
--biel-primary-color: #FF0000;
}
```
See [Styles](https://docs.biel.ai/customization/styles.md) for the full list of CSS properties.
:::tip[Docusaurus not loading your custom CSS?]
Make sure `custom.css` is referenced in `docusaurus.config.js` under the `classic` preset:
```js
presets: [
[
'classic',
{
theme: {
customCss: require.resolve('./src/css/custom.css'),
},
},
],
],
```
:::
## Add the search widget
The search widget replaces the default Docusaurus search bar with Biel.ai's AI-powered search.

1. Install the plugin:
```console
npm install docusaurus-biel
```
2. Register the plugin in `docusaurus.config.js` to load the widget assets:
```js
plugins: [
[
'docusaurus-biel', {
project: '',
headerTitle: 'Documentation AI',
version: 'latest',
enable: false,
},
],
],
```
Replace `` with your project ID. `enable: false` hides the floating assistant button while keeping the assets available for search. Set it to `true` to use both widgets.
3. Eject the `SearchBar` component using [swizzling](https://docusaurus.io/docs/swizzling):
```console
npm run swizzle @docusaurus/theme-classic SearchBar
```
When prompted, choose **TypeScript** and **Eject**.
4. Open `src/theme/SearchBar.tsx` and replace its content with:
```tsx
export default function SearchBar() {
const projectId = '';
const headerTitle = 'Documentation assistant';
// @ts-ignore: Not a React component
return Search;
}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
5. Run `npm start` and verify the search widget appears in the navbar.
:::tip[Using search without the assistant?]
Set `enable: false` in the `docusaurus-biel` plugin config to hide the floating chat button:
```js
plugins: [
[
'docusaurus-biel', {
enable: false,
project: '',
headerTitle: 'Biel.ai assistant',
version: 'latest'
}
]
],
```
:::
## Multilingual support
If your Docusaurus site uses [i18n](https://docusaurus.io/docs/i18n/tutorial), you can localize the assistant's UI strings per locale. This approach uses `biel-react` instead of the `docusaurus-biel` plugin.

1. Install `biel-react`:
```bash
npm install biel-react
```
:::tip[Already using docusaurus-biel?]
This setup replaces it. Run `npm uninstall docusaurus-biel` to remove the plugin.
:::
2. Wrap the Footer component using [swizzling](https://docusaurus.io/docs/swizzling) to inject the assistant before the closing **body** tag:
```bash
npm run swizzle @docusaurus/theme-classic Footer
```
When prompted, choose **Wrap**.
3. Open `src/theme/Footer/index.js` and replace its content with:
```js
function BielWidget() {
const { i18n } = useDocusaurusContext();
const language = i18n.currentLocale;
const projectId = ''; // Replace with your actual project ID
const placeholders = {
en: {
bielButtonText: "Ask AI",
sendButtonText: 'Send',
inputPlaceholderText: 'Type your message',
error403: 'Oops! The request URL does not match the one defined for this project.',
error404: 'Oops! We could not find the provided project ID.',
errorDefault: 'Oops! Please try again later.',
headerTitle: 'Need help?',
footerText: 'AI generated answers. Always verify the sources before using them.',
sourcesText: 'Sources',
suggestedQuestions: JSON.stringify(["What is Biel.ai?", "How to install in Docusaurus?"]),
suggestedQuestionsTitle: 'Suggested questions',
termsTitle: 'Assistant Terms & Conditions',
termsDescription: "Please review our Terms & Conditions before proceeding.",
termsCheckboxText: 'I have read and agree to the Terms & Conditions.',
welcomeMessage: 'Hello! How can I help you today?'
},
es: {
bielButtonText: "Pregúntame",
sendButtonText: 'Enviar',
inputPlaceholderText: 'Escribe tu mensaje',
error403: '¡Ups! La URL de solicitud no coincide con la definida para este proyecto.',
error404: '¡Ups! No pudimos encontrar el ID de proyecto proporcionado.',
errorDefault: '¡Ups! Por favor, intenta de nuevo más tarde.',
headerTitle: '¿Necesitas ayuda?',
footerText: 'Respuestas generadas por IA. Verifica siempre las fuentes antes de usarlas.',
sourcesText: 'Fuentes',
suggestedQuestions: JSON.stringify(["¿Qué es Biel.ai?", "¿Cómo instalar en Docusaurus?"]),
suggestedQuestionsTitle: 'Preguntas sugeridas',
termsTitle: 'Términos y condiciones del asistente',
termsDescription: "Por favor revisa nuestros Términos y Condiciones antes de continuar.",
termsCheckboxText: 'He leído y acepto los Términos y Condiciones.',
welcomeMessage: '¡Hola! ¿En qué puedo ayudarte hoy?'
}
};
const {
bielButtonText,
error403,
error404,
errorDefault,
footerText,
headerTitle,
inputPlaceholderText,
sendButtonText,
sourcesText,
suggestedQuestions,
suggestedQuestionsTitle,
termsCheckboxText,
termsDescription,
termsTitle,
welcomeMessage,
} = placeholders[language] || placeholders.en;
useEffect(() => {
if (typeof window !== 'undefined') {
defineCustomElements(window);
}
}, []);
return (
{bielButtonText}
);
}
export default function FooterWrapper(props) {
return (
<>
>
);
}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project). Update the `placeholders` object with your supported languages.
4. Run `npm start` and verify the assistant displays localized strings when you switch locales.
## Next steps
- [View the `docusaurus-biel` source and releases](https://github.com/TechDocsStudio/docusaurus-biel).
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Fumadocs
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Fumadocs site using Biel.ai's React components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Fumadocs site** ready to install Biel.ai.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

1. Install Biel.ai for React:
```console
npm install biel-react
```
2. Create a client component at `components/BielWidget.tsx`. The React wrapper uses browser lifecycle APIs, so keep it behind a client boundary:
```tsx
'use client';
export default function BielWidget() {
useEffect(() => {
defineCustomElements(window);
}, []);
return (
Ask AI
);
}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. In your existing `app/layout.tsx`, import the client component and widget stylesheet:
```tsx
```
Render `` inside your existing ``, alongside `RootProvider`. Keep the root layout's HTML, fonts, metadata, and existing content. See Next.js [Server and Client Components](https://nextjs.org/docs/app/getting-started/server-and-client-components) for client boundaries.
4. Start your Fumadocs project by running `npm run dev` and verify that the assistant appears and functions correctly on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Gatsby
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Gatsby site.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Gatsby application** ready to install Biel.ai.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

1. Install the Biel.ai package:
```console
npm install biel-react
```
:::info
If you're using yarn as your package manager, run `yarn add biel-react` instead of the npm command above.
:::
1. In the main component where you wish to place the assistant (often `src/pages/index.js`), embed the Biel.ai button:
```ts
const IndexPage = () => {
useEffect(() => {
if (typeof window !== 'undefined') {
defineCustomElements(window);
}
}, []);
return (
{/* Other components and content */}
Ask AI
);
}
export default IndexPage;
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
1. Start your Gatsby app by running `gatsby develop` in your terminal. Once it compiles successfully, verify that the assistant appears and functions correctly on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for GitBook
Use a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to answer questions from your published GitBook content on a website you control.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/) and a [project](https://docs.biel.ai/quickstart.md).
- Published GitBook content that Biel.ai can crawl.
- A website that allows custom JavaScript to host the widget.
## Add the assistant widget {#add-the-chatbot-widget}

GitBook reserves its script-injection scopes for internal integrations. Its [integration configuration guide](https://gitbook.com/docs/developers/integrations/configurations) states that third-party integrations cannot inject JavaScript into a site or space. The native **Custom scripts** setup is not available for this widget.
1. Open your Biel.ai project, select **Settings** > **Sources** > **URLs**, and enter your published GitBook URL. For multiple pages, use a [sitemap](https://docs.biel.ai/customization/data-sources/sitemaps.md).
2. Click **Save**, then **Refresh sources**. Check loading progress and **Logs** in the project dashboard.
3. Install the widget on a site you control using the [CDN installation guide](https://docs.biel.ai/installation/cdn.md). Use the same project's ID from its installation code.
4. Publish that page, test a question about your GitBook content, and link to it from your GitBook space.
## Troubleshooting
**Custom scripts option not available**
Use the external hosting method above. A paid GitBook plan does not grant a third-party integration the internal script-injection scope.
**Pages were not indexed**
Check **Logs** and confirm that the published URLs are reachable by Biel.ai. For protected content, see [private content](https://docs.biel.ai/customization/data-sources/private-content.md).
**Assistant not appearing on the external site**
Verify that the widget's CSS and JavaScript load and that the project ID matches the installation code.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Hugo
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Hugo site using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Hugo application** ready to install Biel.ai.
## Add the assistant widget {#add-the-chatbot-widget}

To integrate the Biel.AI chat widget into your Hugo site:
1. Navigate to your theme directory (e.g., `themes/your-theme/`).
1. Find the head partial, which is often located under `layouts/partials/`. Add the following code to this file:
```html
```
1. Find the footer partial (or wherever you'd like the assistant to be placed) and add the following code just before the closing tags:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
1. Run `hugo server` and verify the assistant appears and functions correctly on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Jekyll
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Jekyll site using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Jekyll application** ready to install Biel.ai.
## Add the assistant widget {#add-the-chatbot-widget}

To integrate the Biel.AI chat widget into your Jekyll site:
1. Open the `_includes/head.html` file (or the equivalent file that contains the **head** section in your Jekyll theme). Append the following code:
```html
```
1. Open `_includes/footer.html` or the specific file where you'd like the assistant to appear. Add the following snippet just before its closing tags:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
1. Run `jekyll build` and verify the assistant appears on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for MadCap Flare
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your MadCap Flare documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **MadCap Flare** installed on your computer.
- **A Flare project** ready to modify.
## Add the assistant widget {#add-the-chatbot-widget}

### Step 1: Modify the master page
1. Open your Flare project in MadCap Flare.
2. In the **Project Organizer**, navigate to `Content/Resources/MasterPages`.
3. Open the master page you're using (typically `Home.flmsp` or `Other Topics.flmsp`). If your project uses multiple master pages, repeat these steps for each one.
4. Switch to the **Text Editor** view (bottom-left button).
5. Add the Biel.ai initialization scripts in the **head** section:
```html
```
6. Just before the closing **body** tag, add the assistant widget:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
7. Save the master page.
### Step 2: Build and test
1. Build your target:
* Select **Project** > **Build Primary** from the menu (or press F6).
* Alternatively, build a specific target from the **Project Organizer**.
2. Once the build completes, open the generated output in your default browser:
* Select **View** > **Open Output Folder**.
* Navigate to the HTML5 output folder.
* Open `index.htm` or `Default.htm` in a web browser.
3. Verify that the assistant appears and works correctly on your pages.
## Example master page snippet
Your master page **head** section should look something like this:
```html
```
And before the closing **body** tag:
```html
Ask AI
```
## Working with multiple targets
If your Flare project has multiple targets (HTML5, Top Navigation, etc.):
1. Ensure each target uses a master page with the Biel.ai code added.
2. You can use the same project ID across all targets.
3. Build and test each target separately to verify the assistant appears correctly.
## Troubleshooting
**Assistant not appearing after build**
- Verify the code was added to the correct master page
- Check that your topics are using the modified master page
- Clear your browser cache and reload the page
- View the page source to confirm the scripts are included
**Build warnings or errors**
- Flare may show warnings about external scripts (this is normal)
- The assistant will still work correctly in the output
- You can safely ignore warnings about CDN-hosted scripts
**Assistant conflicts with Flare's built-in search**
- Biel.ai uses different positioning and won't interfere with Flare's search
- If needed, adjust the `button-position` attribute (e.g., `bottom-left`, `center-right`)
- You can also customize the appearance through CSS
**Styling issues with Top Navigation output**
- Top Navigation skins may have different styling
- See the [customization section](https://docs.biel.ai/customization/styles.md) for CSS overrides
- Consider adjusting button positioning for better visual integration
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Mintlify
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Mintlify documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Mintlify documentation site** ready to install Biel.ai.
## Add the assistant widget {#add-the-chatbot-widget}

1. Create `biel.js` beside your `docs.json` file. Mintlify [loads custom JavaScript files](https://www.mintlify.com/docs/customize/custom-scripts) from the content directory on every page; no `head` or `scripts` entries are needed in the configuration.
```javascript
(() => {
const link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css';
document.head.appendChild(link);
const script = document.createElement('script');
script.type = 'module';
script.src = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js';
document.head.appendChild(script);
function addButton() {
if (document.getElementById('biel-docs-button')) return;
const button = document.createElement('biel-button');
button.id = 'biel-docs-button';
button.setAttribute('project', '');
button.setAttribute('header-title', 'Biel.ai assistant');
button.setAttribute('button-position', 'bottom-right');
button.setAttribute('modal-position', 'bottom-right');
button.setAttribute('button-style', 'dark');
button.textContent = 'Ask AI';
document.body.appendChild(button);
}
addButton();
window.addEventListener('mintlify:navigate', addButton);
})();
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
1. Save the file and run your Mintlify development server:
```console
mint dev
```
1. Open your documentation site and navigate between pages to verify the assistant remains available.
## Alternative: Using MDX components
For a button on selected pages, keep the stylesheet and module-loading code in `biel.js`, but omit `addButton()` and its navigation listener. Then place the element in an MDX component:
1. Create a new file `components/BielChat.mdx` in your Mintlify project:
```html
Ask AI
```
1. Import and use this component in any MDX page where you want the assistant to appear.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for MkDocs
Add a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your MkDocs site using the `mkdocs-biel` plugin. Works with any MkDocs theme, including Material for MkDocs.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
- A MkDocs site.
## Add the assistant widget {#add-the-chatbot-widget}
The `mkdocs-biel` plugin adds a floating chat button to your site.

1. Install the plugin:
```console
pip install mkdocs-biel
```
2. Add the plugin to `mkdocs.yml`:
```yaml
plugins:
- search
- biel:
project:
header_title: Biel.ai assistant
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Run `mkdocs serve` and verify the chat button appears in the bottom-right corner.
## Customization
Pass [layout options](https://docs.biel.ai/customization/layout.md) to the plugin as snake_case keys:
```yaml
plugins:
- biel:
project:
button_text: Ask AI
button_position: bottom-right
modal_position: bottom-right
button_style: dark
header_title: Documentation AI
```
Set `enable: false` to turn the widget off without removing the configuration.
The plugin loads the widget's JavaScript and CSS from the CDN using `latest` by default. You do not need to install an npm widget package. To use a specific release, set `version` in `mkdocs.yml`:
```yaml
plugins:
- biel:
project:
version: '0.1.93'
```
Replace `0.1.93` with your chosen release and rebuild your site. Use `version: latest` to follow new releases again. See [CDN version selection](https://docs.biel.ai/installation/cdn.md#select-a-widget-version) for how caching affects `latest`.
## Add the search widget
The search widget replaces the theme's search with Biel.ai's AI-powered search. The `mkdocs-biel` plugin already loads the required assets, so overriding one template is all it takes.

Install and configure the plugin to load the assets:
```console
pip install mkdocs-biel
```
In `mkdocs.yml`, append Biel to your existing plugins:
```yaml
plugins:
- search
- biel:
project:
header_title: Documentation AI
```
On **Material for MkDocs**, override the search partial:
1. Create `overrides/partials/search.html` with the following content:
```html
Search
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
2. Point `mkdocs.yml` at the overrides directory:
```yaml
theme:
name: material
custom_dir: overrides
```
3. Run `mkdocs serve` and verify the search widget appears in the header where Material's search was.
On other themes, place the same `` element in any template override that renders in your header or sidebar.
:::tip Keeping the built-in search?
Skip the override and the two searches coexist: the theme's keyword search stays in the header and Biel.ai answers questions from the chat button.
:::
## Alternative: template overrides
If you prefer not to use the plugin, you can add the widget with template overrides instead.
1. Create a custom template directory:
```console
mkdir -p docs/overrides
```
2. Create `docs/overrides/main.html` with the following content:
```html
{% extends "base.html" %}
{% block extrahead %}
{% endblock %}
{% block content %}
{{ super() }}
Ask AI
{% endblock %}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Point `mkdocs.yml` to the overrides directory:
```yaml
theme:
name: material # or your preferred theme
custom_dir: 'docs/overrides'
```
4. Run `mkdocs serve` and verify the chat button appears in the bottom-right corner.
## Material for MkDocs keyboard shortcuts
Material for MkDocs registers keyboard shortcuts (`f`, `s`, `/` for search; `p`, `n` for navigation) that can conflict with Biel.ai's input handling.
**Using the `mkdocs-biel` plugin?** The plugin fixes this automatically: keystrokes inside the widget are scoped to it, and Material's shortcuts keep working everywhere else on the page. Set `theme_shortcuts_fix: false` in the plugin options to opt out.
**Using template overrides?** Disable the shortcuts manually:
1. Create `docs/javascripts/disable-search-autofocus.js`:
```javascript
document.addEventListener('keydown', (e) => {
const blockedKeys = ['f', 's', '/', 'p', 'n', ',', '.'];
if (blockedKeys.includes(e.key.toLowerCase())) {
e.stopPropagation();
}
});
```
2. Add the script to `mkdocs.yml`:
```yaml
extra_javascript:
- javascripts/disable-search-autofocus.js
```
## Next steps
- [View the `mkdocs-biel` source and releases](https://github.com/TechDocsStudio/mkdocs-biel).
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Next.js
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Next.js site.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Next.js application** ready to install Biel.ai.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

1. Install the Biel.ai package:
```console
npm install biel-react
```
:::info
If you're using yarn as your package manager, run `yarn add biel-react` instead of the npm command above.
:::
1. Create a wrapper for the assistant by creating a file at `components/biel-search.tsx`:
```ts
'use client';
const DynamicBielButtonComponent = (props: ComponentProps) => {
useEffect(() => {
defineCustomElements(window);
}, []);
return ;
};
export default DynamicBielButtonComponent;
```
1. Create `components/DocumentationChat.tsx` for the browser-only widget entry point:
```js
'use client'
const DynamicBielButton = dynamic(() => import('@/components/biel-search'), {
ssr: false,
});
export default function DocumentationChat() {
return (
{/* Other components and content */}
Ask AI
);
}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
1. Import `DocumentationChat` in your existing `app/layout.tsx` or `pages/_app.tsx` and render `` alongside the existing page content. Keep your root layout's ``, ``, and metadata. The client boundary belongs in `DocumentationChat`, not the root layout.
1. Run `npm run dev` and verify that the assistant appears and works on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Nextra
Add a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Nextra documentation using the `biel-react` package.
:::info
This guide covers **Nextra v2** (Pages Router). If your project uses Nextra v3 (App Router with `app/layout.tsx`), see the [Next.js installation guide](https://docs.biel.ai/installation/nextjs.md) instead.
:::
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
- A Nextra v2 site.
- Node.js installed.
## Add the assistant widget {#add-the-chatbot-widget}
The `BielButton` React component adds a floating chat button to your site.

1. Install the package:
```console
npm install biel-react
```
2. Create or update `pages/_app.tsx`:
```tsx
export default function App({ Component, pageProps }: AppProps) {
useEffect(() => {
if (typeof window !== 'undefined') {
defineCustomElements(window);
}
}, []);
return (
<>
Ask AI
>
);
}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Run `npm run dev` and verify the assistant appears on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant for Nimbus documentation
Add source-linked chat to a [Cloudflare Nimbus](https://nimbus-docs.com/) documentation site with the `astro-biel` integration. Nimbus generates a standard Astro project, so Biel can load beside the existing Nimbus integration without changing the documentation layout.
:::note
Nimbus already includes Pagefind search and agent-readable Markdown, `llms.txt`, sitemap, and structured-data output. Biel complements those features with interactive answers, usage analytics, content-gap reporting, and an optional hosted MCP endpoint.
:::
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [Biel project](https://docs.biel.ai/quickstart.md#2-create-a-project) with your published Nimbus documentation URL added as a source.
- A Nimbus site created with `@cloudflare/create-nimbus-docs`.
- Node.js 22.12 or later, as required by Nimbus.
## Add the assistant {#add-the-chatbot}
The recommended starting point is to keep Nimbus's built-in search and add Biel as a separate **Ask AI** button.

1. Install `astro-biel` in the Nimbus project:
```console
npm install astro-biel
```
Use the equivalent `pnpm add`, `yarn add`, or `bun add` command if the project uses another package manager.
2. Open `astro.config.ts` and import the integration:
```ts
```
3. In the existing `integrations` array, append the following item after the current `nimbus(...)` item:
```ts
biel({
project: "",
headerTitle: "Documentation AI",
buttonPosition: "bottom-right",
}),
```
The relevant part of the configuration should now follow this structure:
```ts
export default defineConfig({
// Keep the output, Vite, prefetch, and other Nimbus settings.
integrations: [
nimbus(nimbusConfig, {
// Keep the Nimbus options already in your project.
}),
biel({
project: "",
headerTitle: "Documentation AI",
buttonPosition: "bottom-right",
}),
],
});
```
Replace `` with the project ID from the [Biel dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project). Do not remove Nimbus's existing rules, Markdown plugins, Tailwind Vite configuration, or deployment settings.
4. Start Nimbus and check the site:
```console
npm run dev
```
The Ask AI button should appear in the bottom-right corner and remain available as Astro's ClientRouter moves between pages.
## Customize the assistant {#customize-the-chatbot}
Pass Biel's [layout options](https://docs.biel.ai/customization/layout.md) as camelCase properties:
```ts
biel({
project: "",
bielButtonText: "Ask AI",
buttonPosition: "bottom-right",
modalPosition: "sidebar-right",
buttonStyle: "dark",
headerTitle: "Documentation AI",
});
```
Set `enable: false` to hide the widget without removing the configuration.
## Choose how page search should work
Nimbus includes Pagefind search. You have two useful configurations:
- **Keep Nimbus search and add Ask AI:** recommended for most sites. Readers keep the familiar Pagefind interface and use the separate Biel button when they need an answer.
- **Use Biel page search:** useful when you want page results and an **Ask AI** handoff in the same search interface.

To use Biel page search, install and configure the integration even if you are starting with search only:
```console
npm install astro-biel
```
Import `biel` from `astro-biel` in `astro.config.ts` and append `biel({ project: "" })` to your existing `integrations` array after `nimbus(...)`. Keep Nimbus's existing configuration.
Then replace the search trigger:
1. Disable Nimbus Pagefind in `astro.config.ts` so its keyboard shortcut does not remain active:
```ts
const nimbusConfig = defineNimbusConfig({
// Keep the other Nimbus options already in your project.
search: false,
});
```
2. Open `src/components/Header.astro` and remove the `SearchTrigger` import.
3. Replace the existing Nimbus search trigger:
```astro
{config.search !== false && }
```
with:
```astro
Search docs
```
The `astro-biel` integration already loads the assets required by the search component. The search widget and assistant use the same Biel project and indexed documentation.
## Add hosted MCP
Nimbus's Markdown alternates and `llms.txt` make documentation readable by agents. A Biel [MCP server](https://docs.biel.ai/integrations/mcp-server.md) adds an interactive endpoint that Claude, Cursor, Cline, and other compatible tools can query.
Open the Biel project's **Settings** > **MCP**, enable the server, and click **Save**. Copy the displayed **MCP endpoint** or use the widget's **Connect** menu. Paste that complete URL into your client's configuration; endpoint formats and metadata can vary by deployment. For example:
```json
{
"mcpServers": {
"biel-ai": {
"type": "http",
"url": "https://mcp.biel.ai/v2/YOUR_PROJECT_SLUG/mcp"
}
}
}
```
## Troubleshooting
### The widget does not appear
- Confirm `biel(...)` is inside the exported Astro `integrations` array.
- Confirm the project ID matches the Biel dashboard.
- Restart the Nimbus development server after changing `astro.config.ts`.
- Check that `enable` is not set to `false`.
### Search appears twice
Keep both search triggers only if you intentionally want both interfaces. Otherwise set `search: false` in the Nimbus configuration and remove Nimbus's `SearchTrigger` when adding ``.
### Nimbus changed a generated component
The assistant uses Astro's integration API and does not depend on the Nimbus header. If a Nimbus update changes `Header.astro`, review only the optional page-search placement. Nimbus is currently pre-1.0, so pin versions and review its changelog before upgrading.
## Next steps
- [Customize Biel](https://docs.biel.ai/customization.md) to match the Nimbus theme and terminology.
- [Review the Astro integration guide](https://docs.biel.ai/installation/astro.md) for all `astro-biel` options.
- [Read the Nimbus installation guide](https://nimbus-docs.com/installation/).
- [View the `astro-biel` source](https://github.com/TechDocsStudio/astro-biel).
---
## Ask AI assistant widget for NPM projects
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your JavaScript project using Biel.ai's NPM package.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

1. Install Biel.ai:
```console
npm install biel-search
```
2. Make sure you embed the styles and scripts in your primary JS or entry file:
```js
```
3. Just before the closing **body** tag of your website's HTML, add the following snippet:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
4. Open the website in a web browser to verify the assistant appears and works correctly.
## Select a widget version
`npm install biel-search` selects the latest published release for a new installation. Your dependency range and lockfile control later installations; `npm ci` uses the locked version.
To select a specific release:
```console
npm install --save-exact biel-search@0.1.93
```
Replace `0.1.93` with your chosen release, then rebuild your application. This setting controls the installed package; see [CDN version selection](https://docs.biel.ai/installation/cdn.md#select-a-widget-version) if your page loads scripts from jsDelivr instead.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Paligo
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Paligo documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Paligo account** with HTML5 output capability.
- **Access to your Paligo publication settings** to add custom JavaScript.
## Add the assistant widget {#add-the-chatbot-widget}

1. Log in to your Paligo account and open your publication.
2. Create a local `biel.js` file, or add the following code to the custom JavaScript file already used by your layout:
```javascript
(function() {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css';
document.head.appendChild(link);
var script = document.createElement('script');
script.type = 'module';
script.src = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js';
document.head.appendChild(script);
script.onload = function() {
var button = document.createElement('biel-button');
button.setAttribute('project', '');
button.setAttribute('header-title', 'Biel.ai assistant');
button.setAttribute('button-position', 'bottom-right');
button.setAttribute('modal-position', 'bottom-right');
button.setAttribute('button-style', 'dark');
button.textContent = 'Ask AI';
document.body.appendChild(button);
};
})();
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. In Paligo, select **Layout**, open your HTML5 layout, and choose **CSS, JS, logos and other assets**. Under **Custom Javascript**, click **Upload** and select the `.js` file, then click **Save**. See Paligo's [JavaScript guide](https://docs.paligo.net/en/style-with-javascript.html).
A layout accepts one custom JavaScript file. If it already has one, extend that file rather than replacing its existing functionality.
4. Publish using the modified layout and verify the assistant on the generated pages.
## Alternative: modify published HTML
If you host and postprocess the exported HTML yourself, add the widget to the generated files:
1. Open the generated HTML files in your exported output.
2. Add the initialization scripts to each page's **head** section:
```html
```
3. Add the widget code before the closing **body** tag:
```html
Ask AI
```
4. Publish the modified output. Repeat this postprocessing after each Paligo export, since new output replaces the generated files.
## Troubleshooting
**Custom JavaScript not working**
- Verify your Paligo plan includes custom JavaScript features
- Check that the JavaScript file is uploaded to the layout used for publication
- Review browser console for any JavaScript errors
**Assistant not appearing**
- Ensure both the CSS and JavaScript modules are loading (check Network tab)
- Verify your project ID is correct
- Clear your browser cache and reload the page
**Styling conflicts with Paligo themes**
- Paligo's built-in themes may have conflicting styles
- Try adjusting the `button-position` attribute (e.g., `center-right`, `bottom-left`)
- See the [customization section](https://docs.biel.ai/customization/layout.md) for style overrides
**Assistant appearing on some pages but not others**
- Ensure every publication uses the layout with the uploaded JavaScript
- Verify all pages are being regenerated when you publish
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for React
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your React application using Biel.ai's React components.
The `biel-react` package includes three components: `BielButton` for a floating assistant, `BielSearchButton` for AI-powered search, and `BielBot` for embedding the assistant directly in your page layout.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A React application** ready to install Biel.ai.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

1. Install Biel.ai:
```console
npm install biel-react
```
:::info
If you're using yarn as your package manager, run `yarn add biel-react` instead of the npm command above.
:::
2. In the main component where you wish to place the assistant (often `src/App.js`), embed the Biel.ai button:
```tsx
function App() {
useEffect(() => {
if (typeof window !== 'undefined') {
defineCustomElements(window);
}
}, []);
return (
{/* Other components and content */}
Ask AI
);
}
export default App;
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Start your React app by running `npm start` or `yarn start` in your terminal. Once it compiles successfully, verify that the assistant appears and functions correctly on your site.
## Add the search widget

1. Install Biel.ai:
```console
npm install biel-react
```
:::info
If you're using yarn as your package manager, run `yarn add biel-react` instead of the npm command above.
:::
2. In the component where you want to place the search widget, embed the Biel.ai search button:
```tsx
function App() {
useEffect(() => {
if (typeof window !== 'undefined') {
defineCustomElements(window);
}
}, []);
return (
{/* Other components and content */}
Search
);
}
export default App;
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Start your React app by running `npm start` or `yarn start` in your terminal. Once it compiles successfully, verify that the search widget appears and functions correctly on your site.
## Add embedded chat
Use `BielBot` to render the assistant inline in your page layout instead of as a floating button. This is useful for building dedicated help pages or embedding the assistant within a specific section of your site. See [Embedded mode](https://docs.biel.ai/customization/embedded-mode.md) for more details.
1. Install Biel.ai:
```console
npm install biel-react
```
:::info
If you're using yarn as your package manager, run `yarn add biel-react` instead of the npm command above.
:::
2. In the component where you want the assistant to appear inline, embed `BielBot` with `embedded-mode` set to `true`:
```tsx
function HelpPage() {
useEffect(() => {
if (typeof window !== 'undefined') {
defineCustomElements(window);
}
}, []);
return (
);
}
export default HelpPage;
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Start your React app by running `npm start` or `yarn start` in your terminal. Once it compiles successfully, verify that the assistant appears inline on the page.
## Select a widget version
The React wrapper loads the widget installed by npm. It declares `biel-search@latest`, so a fresh npm installation selects the npm `latest` widget release. Your application's lockfile keeps the resolved version, `npm ci` installs that locked version.
To select a specific widget release, add an override to your application's root `package.json`:
```json
{
"overrides": {
"biel-react": {
"biel-search": "0.1.93"
}
}
}
```
Then run `npm install`. Replace `0.1.93` with the release you want. Remove the override and update the widget dependency to follow `latest` again. If your application also lists `biel-search` as a direct dependency, keep it on the same version so its loader and styles match.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for ReadMe
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your ReadMe documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A ReadMe project** with a paid plan that allows custom JavaScript.
- **Admin access** to your ReadMe project.
## Add the assistant widget {#add-the-chatbot-widget}

1. Log in to your ReadMe dashboard and navigate to your project.
1. Access appearance settings:
- Open **Appearance** in the project dashboard.
- Select **CSS, JS, HTML**, then the JavaScript editor. See ReadMe's [customization guide](https://docs.readme.com/main/docs/custom-css-and-javascript) for the controls available on your plan.
:::tip
If you don't see the Custom JavaScript & CSS option, verify that your ReadMe plan includes this feature.
:::
1. Add the Biel.ai initialization code in the Custom JavaScript field:
```javascript
(function() {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.href = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css';
document.head.appendChild(link);
var script = document.createElement('script');
script.type = 'module';
script.src = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js';
document.head.appendChild(script);
script.onload = function() {
var button = document.createElement('biel-button');
button.setAttribute('project', '');
button.setAttribute('header-title', 'Biel.ai assistant');
button.setAttribute('button-position', 'bottom-right');
button.setAttribute('modal-position', 'bottom-right');
button.setAttribute('button-style', 'dark');
button.textContent = 'Ask AI';
document.body.appendChild(button);
};
})();
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
1. Click **Save** to apply the changes.
1. Visit your ReadMe documentation in a web browser to verify the assistant appears and works correctly.
## Troubleshooting
### Custom JavaScript not available
- Check ReadMe's [current customization permissions](https://docs.readme.com/main/docs/custom-css-and-javascript) for your project's plan
- Contact your ReadMe admin to upgrade if needed
### Assistant not appearing {#chatbot-not-appearing}
- Check your browser console for any error messages
- Ensure the script has loaded properly (look in the Network tab)
- Verify your project ID is correct
### Conflicts with ReadMe's chat widget
- If you're using ReadMe's built-in Intercom or other chat widgets, you may want to adjust positioning
- Use the `button-position` attribute to move the Biel.ai widget (e.g., `bottom-left`, `center-right`)
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Read the Docs
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Read the Docs documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Read the Docs project** using Sphinx or MkDocs.
- **Access to your documentation repository** to modify theme files.
## Installation for Sphinx

### Using the Sphinx extension (Recommended)
If your Read the Docs project uses Sphinx, the easiest way to add Biel.ai is using the official Sphinx extension:
1. Install the Biel.ai extension via pip (add to your `requirements.txt`):
```txt
sphinx-biel
```
2. Add the extension to your `conf.py`:
```python
extensions = ['sphinx_biel']
biel_project = ''
biel_header_title = 'Biel.ai assistant'
biel_button_style = 'dark'
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Commit and push your changes. Read the Docs will automatically rebuild your documentation with the Biel.ai widget.
For more details, see the [Sphinx installation guide](https://docs.biel.ai/installation/sphinx.md).
### Using custom templates
Alternatively, you can add Biel.ai using custom Sphinx templates:
1. Create a `_templates` directory in your docs folder if it doesn't exist.
2. Create a file `_templates/layout.html` with the following content:
```html
{% extends "!layout.html" %}
{% block extrahead %}
{{ super() }}
{% endblock %}
{% block footer %}
{{ super() }}
Ask AI
{% endblock %}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Update your `conf.py` to use the templates directory:
```python
templates_path = ['_templates']
```
4. Commit and push your changes.
## Installation for MkDocs
If your Read the Docs project uses MkDocs:
1. Create a directory called `overrides` in your docs folder.
2. Create a file `overrides/main.html` with the following content:
```html
{% extends "base.html" %}
{% block extrahead %}
{{ super() }}
{% endblock %}
{% block content %}
{{ super() }}
Ask AI
{% endblock %}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Update your `mkdocs.yml` to use the custom theme directory:
```yaml
theme:
name: material # or your chosen theme
custom_dir: overrides
```
4. Commit and push your changes. Read the Docs will rebuild with the assistant included.
## Troubleshooting
### Widget not appearing after rebuild
- Check the build logs on Read the Docs for any errors
- Verify your template files are in the correct location
- Ensure your project ID is correct
### Build failures
- For Sphinx extension issues, verify `sphinx-biel` is in your requirements file
- Check that your Python version is compatible
- Review the Read the Docs build log for specific error messages
### Styling conflicts
- Different Read the Docs themes may have different styling
- Adjust the `button-position` and `modal-position` attributes if needed
- See the [customization section](https://docs.biel.ai/customization.md) for style overrides
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Sphinx
Add a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Sphinx documentation using the `sphinx-biel` package. Works with any Sphinx theme, including Read the Docs.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
- A Sphinx project.
## Add the assistant widget {#add-the-chatbot-widget}
The `sphinx-biel` extension adds a floating chat button to your site.

1. Install the package:
```console
pip install sphinx-biel
```
2. Add the extension to your `conf.py`:
```python
extensions = ['sphinx_biel']
```
3. Configure your project ID in `conf.py`:
```python
biel_project = ''
biel_header_title = 'Biel.ai assistant'
biel_version = 'latest'
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
4. Build and verify:
```console
make html
```
Open the built documentation in a browser and verify the assistant appears.
## Add the search widget
The search widget replaces the theme's search box with Biel.ai's AI-powered search. Enable `sphinx-biel` to load the widget assets, then override the search template.

1. Install and configure the extension:
```console
pip install sphinx-biel
```
In `conf.py`, append `sphinx_biel` to your existing extensions and set your project ID:
```python
extensions = ['sphinx_biel']
biel_project = ''
biel_header_title = 'Documentation AI'
```
2. Create `_templates/searchbox.html` in your project with the following content:
```html
Search
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Make sure `conf.py` points at your templates directory:
```python
templates_path = ["_templates"]
```
4. Rebuild and verify the search widget appears where the theme's search box was (the sidebar on the Read the Docs theme).
## Select a widget version
The extension loads the widget's JavaScript and CSS from the CDN using `latest` by default. You do not need to install an npm widget package. Your Python dependencies do not pin these browser assets.
To use a specific widget release, add this to `conf.py` and rebuild with `make html`:
```python
biel_version = '0.1.93'
```
Replace `0.1.93` with your chosen release. Set `biel_version = 'latest'` to follow new releases again. See [CDN version selection](https://docs.biel.ai/installation/cdn.md#select-a-widget-version) for how caching affects `latest`.
## Customization
Pass [layout options](https://docs.biel.ai/customization/layout.md) in `conf.py` with these naming conventions:
- Prefix each option with `biel_` (e.g., `project` → `biel_project`).
- Replace hyphens with underscores (e.g., `button-position` → `biel_button_position`).
```python
biel_button_style = "light"
biel_button_position = "center-right"
```
## Next steps
- [View the `sphinx-biel` source and releases](https://github.com/TechDocsStudio/sphinx-biel).
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Starlight
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Starlight documentation using the `starlight-biel` plugin.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
- A Starlight site (Starlight 0.32 or later).
- Node.js installed.
## Add the assistant widget {#add-the-chatbot-widget}
The `starlight-biel` plugin adds a floating chat button to your site.

1. Install the plugin:
```console
npm install starlight-biel
```
2. Add the plugin to your Starlight configuration in `astro.config.mjs`:
```js
export default defineConfig({
integrations: [
starlight({
title: 'My Docs',
plugins: [
starlightBiel({
project: '',
headerTitle: 'Biel.ai assistant',
}),
],
}),
],
})
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Run `npm run dev` and verify the chat button appears in the bottom-right corner.
## Customization
Pass [layout options](https://docs.biel.ai/customization/layout.md) to the plugin as camelCase properties:
```js
starlightBiel({
project: '',
bielButtonText: 'Ask AI',
buttonPosition: 'bottom-right',
modalPosition: 'bottom-right',
buttonStyle: 'dark',
headerTitle: 'Documentation AI',
})
```
Set `enable: false` to turn the widget off without removing the configuration.
## Add the search widget
The search widget replaces Starlight's built-in Pagefind search with Biel.ai's AI-powered search. The `starlight-biel` plugin already loads the required assets, so one component override is all it takes.

Install the plugin before adding the override:
```console
npm install starlight-biel
```
1. Create `src/components/Search.astro` with the following content:
```astro
---
---
Search
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
2. Register the override in your Starlight configuration in `astro.config.mjs`:
```js
starlight({
components: {
Search: './src/components/Search.astro',
},
plugins: [
starlightBiel({ project: '' }),
],
})
```
3. Run `npm run dev` and verify the search widget appears in the navbar where Pagefind's search was.
:::tip Keeping Pagefind?
Skip the override and the two searches coexist: Pagefind stays in the navbar for keyword lookup and Biel.ai answers questions from the chat button.
:::
## Alternative: component overrides
If you prefer not to use the plugin, or need to place the button inside a custom component, you can add the widget manually with Starlight's `head` configuration and a footer override.
1. Load the dependencies in your Astro configuration file (`astro.config.mjs`):
```js
export default defineConfig({
integrations: [
starlight({
head: [
{
tag: 'link',
attrs: {
rel: 'stylesheet',
href: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css',
},
},
{
tag: 'script',
attrs: {
type: 'module',
src: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js',
},
},
],
(...)
}),
],
})
```
2. Create `src/components/CustomFooter.astro` containing a `` element alongside the default footer content:
```astro
---
---
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
The global style sets `z-index: -1` on `.right-sidebar-container` to ensure the button is placed on top of the right sidebar.
3. Register the footer override in `astro.config.mjs`:
```js
export default defineConfig({
integrations: [
starlight({
(...)
components: {
Footer: './src/components/CustomFooter.astro',
},
(...)
}),
],
})
```
4. Run `npm run dev` and verify the chat button appears in the bottom-right corner.
## Next steps
- [View the `starlight-biel` source and releases](https://github.com/TechDocsStudio/starlight-biel).
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for VitePress
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your VitePress documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A VitePress site** ready to install Biel.ai.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

1. Create a custom theme directory if you don't already have one:
```console
mkdir -p .vitepress/theme
```
2. Create a file `.vitepress/theme/index.js` (or `.ts` if using TypeScript) with the following content:
```js
export default {
extends: DefaultTheme,
Layout() {
return h(DefaultTheme.Layout, null, {
'layout-bottom': () => h(BielWidget)
})
}
}
const BielWidget = {
setup() {
onMounted(() => {
// Load CSS
const link = document.createElement('link')
link.rel = 'stylesheet'
link.href = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css'
document.head.appendChild(link)
// Load JS module
const script = document.createElement('script')
script.type = 'module'
script.src = 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js'
document.head.appendChild(script)
// Add assistant button
script.onload = () => {
const button = document.createElement('biel-button')
button.setAttribute('project', '')
button.setAttribute('header-title', 'Biel.ai assistant')
button.setAttribute('button-position', 'bottom-right')
button.setAttribute('modal-position', 'bottom-right')
button.setAttribute('button-style', 'dark')
button.textContent = 'Ask AI'
document.body.appendChild(button)
}
})
return () => null
}
}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Create an empty CSS file `.vitepress/theme/custom.css` (you can add custom styles here later if needed):
```css
/* Add your custom styles here */
```
4. Start your VitePress development server:
```console
npm run docs:dev
```
5. Open your documentation site in a web browser to verify the assistant appears and works correctly.
## Alternative: Using head configuration
If you prefer not to create a custom theme, you can add the widget using VitePress's head configuration.
1. Open your `.vitepress/config.js` (or `.ts`) file.
2. Add the following to your config:
```js
export default defineConfig({
// ... your other config
head: [
[
'link',
{ rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css' }
],
[
'script',
{ type: 'module', src: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js' }
],
[
'script',
{},
`
window.addEventListener('DOMContentLoaded', () => {
const button = document.createElement('biel-button');
button.setAttribute('project', '');
button.setAttribute('header-title', 'Biel.ai assistant');
button.setAttribute('button-position', 'bottom-right');
button.setAttribute('modal-position', 'bottom-right');
button.setAttribute('button-style', 'dark');
button.textContent = 'Ask AI';
document.body.appendChild(button);
});
`
]
]
})
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Restart your development server to see the changes.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Vue.js
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Vue.js application using Biel.ai's Vue components. The integration works with both Vue 2 and Vue 3, and is compatible with Vue CLI, Vite, and other common Vue setups.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Vue.js application** ready to install Biel.ai.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

1. Install Biel.ai:
```console
npm install biel-search
```
2. Open your main Vue component or the desired Vue component where you want the assistant to appear. Then, incorporate the Biel.ai styles and scripts:
```js
```
3. In the template section of your Vue component, add the following snippet:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
4. Run `npm run serve` and verify the assistant appears on your site.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for VuePress
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your VuePress documentation using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A VuePress site** ready to install Biel.ai.
- **Node.js** installed.
## Add the assistant widget {#add-the-chatbot-widget}

### For VuePress 2.x
1. Open your VuePress config file (`.vuepress/config.js` or `.vuepress/config.ts`).
2. Add the Biel.ai scripts to the `head` configuration:
```js
export default defineUserConfig({
// ... your other config
head: [
[
'link',
{ rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css' }
],
[
'script',
{ type: 'module', src: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js' }
],
[
'script',
{},
`
if (typeof window !== 'undefined') {
window.addEventListener('DOMContentLoaded', () => {
const button = document.createElement('biel-button');
button.setAttribute('project', '');
button.setAttribute('header-title', 'Biel.ai assistant');
button.setAttribute('button-position', 'bottom-right');
button.setAttribute('modal-position', 'bottom-right');
button.setAttribute('button-style', 'dark');
button.textContent = 'Ask AI';
document.body.appendChild(button);
});
}
`
]
]
})
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Start your VuePress development server:
```console
npm run docs:dev
```
4. Open your documentation site in a web browser to verify the assistant appears and works correctly.
### For VuePress 1.x
1. Open your VuePress config file (`.vuepress/config.js`).
2. Add the following to your config:
```js
module.exports = {
// ... your other config
head: [
[
'link',
{ rel: 'stylesheet', href: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.css' }
],
[
'script',
{ type: 'module', src: 'https://cdn.jsdelivr.net/npm/biel-search/dist/biel-search/biel-search.esm.js' }
],
[
'script',
{},
`
window.addEventListener('DOMContentLoaded', function() {
var button = document.createElement('biel-button');
button.setAttribute('project', '');
button.setAttribute('header-title', 'Biel.ai assistant');
button.setAttribute('button-position', 'bottom-right');
button.setAttribute('modal-position', 'bottom-right');
button.setAttribute('button-style', 'dark');
button.textContent = 'Ask AI';
document.body.appendChild(button);
});
`
]
]
}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Start your VuePress development server:
```console
npm run docs:dev
```
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Webflow
Add an [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your Webflow site using Biel.ai's web components.
## Prerequisites
- A **Biel.ai account**. If you don't have one, [sign up for free](https://app.biel.ai/accounts/signup/).
- **A project created in your Biel.ai dashboard**. Follow the [Quickstart guide](https://docs.biel.ai/quickstart.md) to create one.
- **A Webflow site** with a paid site plan (required for custom code features).
## Add the assistant widget {#add-the-chatbot-widget}

1. Log in to your Webflow dashboard and open the site you want to edit.
2. Navigate to your site settings:
* Click the **Settings** icon (gear icon) in the left sidebar.
* Select **Custom Code** from the menu.
3. Add the Biel.ai styles and scripts in the Head Code section:
* In the **Head Code** field, paste the following:
```html
```
4. Add the assistant widget in the Footer Code section:
* Scroll down to the **Footer Code** field.
* Paste the following snippet:
```html
Ask AI
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
5. Click **Save Changes** at the top right.
6. Publish your site:
* Click the **Publish** button in the top right corner of the Webflow Designer.
* Select the domain(s) you want to publish to.
* Click **Publish to selected domains**.
7. Visit your published Webflow site in a web browser to verify the assistant appears and works correctly.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI and site search for WordPress
Biel.ai provides two official WordPress plugins. Install either one or use both with the same Biel.ai project:
- [**Biel.ai Assistant**](https://wordpress.org/plugins/biel-ask-ai/) adds a floating Ask AI assistant with source-linked answers.
- [**Biel.ai Search**](https://wordpress.org/plugins/biel-ai-search/) replaces the search form your theme already renders with page search and an Ask AI handoff.
Both plugins use guided setup and work with classic themes, block themes, and page builders. No PHP or template editing is required.
## Prerequisites
- A public WordPress site that Biel.ai can crawl.
- A sitemap containing the posts, pages, or other public content you want Biel.ai to index.
- A Biel.ai account. You can create one from either plugin during setup.
## Add the Ask AI assistant
1. In WordPress, go to **Plugins → Add New Plugin**.
2. Search for **Biel.ai Assistant**, then install and activate it. You can also [open the plugin in the WordPress directory](https://wordpress.org/plugins/biel-ask-ai/).
3. Choose the type of site you run and confirm the sitemap detected by the setup wizard.
4. Select **Connect to Biel.ai**, then create an account or log in. WordPress reconnects automatically and creates the project with the choices you made.
5. Choose where the assistant appears and wait for the first crawl to finish.
The assistant can float on every matching page or render from the `[biel_ask_ai]` shortcode. Use `[biel_ask_ai embedded="true"]` to place the conversation inline.
## Add page search with Ask AI
1. In WordPress, go to **Plugins → Add New Plugin**.
2. Search for **Biel.ai Search**, then install and activate it. You can also [open the plugin in the WordPress directory](https://wordpress.org/plugins/biel-ai-search/).
3. Confirm the site type and sitemap, then connect the same Biel.ai account and project used by the assistant.
4. Enable **Use AI search wherever your theme shows a search form** to replace classic search forms and WordPress search blocks without editing the theme.
Use the `[biel_search]` shortcode to place another search trigger in a page, post, widget area, or template. Existing `?s=` result URLs continue to use the normal WordPress results page.
## Use both plugins together
Point both plugins at the same Biel.ai project. Readers can use page search when they know what they want and open the assistant when they need a source-linked answer. Both surfaces share the same indexed content, configuration, and analytics.
## Manual installation
If you cannot install WordPress plugins, use the [CDN installation](https://docs.biel.ai/installation/cdn.md) through a header/footer editor or your theme. The official plugins are the recommended path because they handle connection, placement, customization, and re-crawling from the WordPress dashboard.
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Ask AI assistant widget for Zensical
Add a Biel.ai [AI assistant](https://biel.ai) or [AI search widget](https://biel.ai/ai-search-for-docs) to your [Zensical](https://zensical.org) site using template overrides. Zensical is the static site generator from the Material for MkDocs team, and it supports the same `custom_dir` template overrides — so the Biel.ai widget drops in with a few lines of config.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai/accounts/signup/).
- A [project](https://docs.biel.ai/quickstart.md#2-create-a-project) with indexed content.
- A Zensical site.
## Add the assistant widget {#add-the-chatbot-widget}
The `` component adds a floating chat button to your site.

1. Create a custom template directory:
```console
mkdir -p overrides
```
2. Create `overrides/main.html` with the following content:
```html
{% extends "base.html" %}
{% block extrahead %}
{% endblock %}
{% block content %}
{{ super() }}
Ask AI
{% endblock %}
```
Replace `` with your project's ID from the [Biel.ai dashboard](https://docs.biel.ai/quickstart.md#2-create-a-project).
3. Point Zensical at the overrides directory.
In `zensical.toml`:
```toml
[project.theme]
custom_dir = "overrides"
```
If your project still uses the legacy `mkdocs.yml`, the equivalent is:
```yaml
theme:
custom_dir: overrides
```
4. Run `zensical serve` and verify the chat button appears in the bottom-right corner.
## Disable conflicting keyboard shortcuts
Like Material for MkDocs, Zensical registers keyboard shortcuts (`f`, `s`, `/` for search; `p`, `n` for navigation) that can conflict with Biel.ai's input handling. To disable them:
1. Create `docs/javascripts/disable-search-autofocus.js`:
```javascript
document.addEventListener('keydown', (e) => {
const blockedKeys = ['f', 's', '/', 'p', 'n', ',', '.'];
if (blockedKeys.includes(e.key.toLowerCase())) {
e.stopPropagation();
}
});
```
2. Register the script.
In `zensical.toml`:
```toml
[project]
extra_javascript = ["javascripts/disable-search-autofocus.js"]
```
Or in `mkdocs.yml`:
```yaml
extra_javascript:
- javascripts/disable-search-autofocus.js
```
## Next steps
- [Customize](https://docs.biel.ai/customization.md) the widget's appearance, behavior, and tone.
- [Connect integrations](https://docs.biel.ai/integrations.md) like GitHub Actions, MCP, or Zapier.
---
## Installation
Step-by-step installation guides for a range of programming languages and frameworks.
## Basic installation
CDN
Add an AI assistant to your HTML site
## Documentation sites
Docusaurus
Install on Docusaurus
Sphinx
Install on Sphinx
MkDocs
Install on MkDocs
Nextra
Install on Nextra
Fumadocs
Install on Fumadocs
Starlight
Install on Starlight
Nimbus
Install on Nimbus
VitePress
Install on VitePress
VuePress
Install on VuePress
Antora
Install on Antora
GitBook
Install on GitBook
Mintlify
Install on Mintlify
ReadMe
Install on ReadMe
Read the Docs
Install on Read the Docs
Paligo
Install on Paligo
MadCap Flare
Install on MadCap Flare
## JavaScript & React apps
NPM
Install via NPM
React
Install on React
Vue
Install on Vue
Next.js
Install on Next.js
Astro
Install on Astro
Gatsby
Install on Gatsby
Hugo
Install on Hugo
Jekyll
Install on Jekyll
## Website builders
WordPress
Install on WordPress
Webflow
Install on Webflow
Confluence
Install on Confluence
---
## Create a ChatGPT plugin for your documentation
# ChatGPT documentation plugin
Use your Biel.ai MCP endpoint to give ChatGPT access to your indexed documentation. You can connect it for your own use, then package a plugin for public distribution.
## Before you start
- Index your content in Biel.ai and enable hosted MCP on a plan that includes it.
- Open the widget's **Connect** menu and select **MCP URL**. Use the complete copied URL, including its path and any project configuration.
- Use a ChatGPT account and workspace that allow custom MCP connections.
For a public documentation project, the connection does not need a Biel.ai API key. For a private project, review [MCP configuration and access](https://docs.biel.ai/integrations/mcp-server.md#configuration-parameters) before sharing the connection. Biel's API-key configuration does not provide an OAuth sign-in flow.
## 1. Connect the MCP server in ChatGPT
1. Open [ChatGPT Plugins](https://chatgpt.com/plugins).
2. Select **+**, then **Add custom MCP server**.
3. Enter a name such as **Your Product Docs** and a description of the documentation it covers.
4. Enter the complete Biel.ai MCP URL under **Connection**.
5. Configure authentication for the endpoint. Use no authentication for a public Biel.ai project.
6. Review the connection notice and select **Create as a plugin**.
7. Confirm that ChatGPT discovers `biel_ai`, `biel_search`, and `biel_get_document`.
Install the plugin, start a new chat, and select it with `@`. Account and workspace policies can restrict these options. See OpenAI's [connection guide](https://developers.openai.com/plugins/deploy/connect-chatgpt) for the current interface.
## 2. Test answers and source retrieval
Ask a question whose answer is in your documentation:
> Use Your Product Docs to explain how authentication works and cite the sources.
For source retrieval, ask:
> Use Your Product Docs to search for SDK authentication. Retrieve the sources without generating a Biel answer, then explain them with citations.
The server exposes `biel_ai` for Biel-generated answers, `biel_search` for hybrid keyword and semantic retrieval, and `biel_get_document` for complete indexed document text. Normally the assistant searches, reads relevant documents, and writes its own answer. Use `biel_ai` when you specifically want Biel to answer. See [tools and limits](https://docs.biel.ai/integrations/mcp-server.md#generated-answers-or-document-retrieval).
Test a follow-up, an uploaded document, a question with no matching source, and private access if your project requires it. Check that citations identify the actual source and that failures are reported as errors.
After an MCP tool-schema update, open the connection in ChatGPT Plugins, select **Refresh**, and test again in a new conversation.
## 3. Package a distributable plugin
For directory distribution, create a folder containing a portable `plugin.json` manifest and an `mcp.json` connection file. Start with these examples and replace the project URL with the public connection you tested.
`plugin.json`:
```json
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "your-product-docs",
"version": "1.0.0",
"description": "Search Your Product documentation and answer questions with source references."
}
```
`mcp.json`:
```json
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"your-product-docs": {
"type": "streamable-http",
"url": "https://app.biel.ai/mcp/YOUR_PROJECT_SLUG?metadata=chatgpt"
}
}
}
```
The URL is an example. Copy the endpoint from your own project, since hosted endpoint formats can differ. Keep API keys out of public packages. Add publisher metadata and assets required by the submission portal, then ZIP the plugin contents. OpenAI's [packaging guide](https://developers.openai.com/plugins/build/plugins) covers optional skills and complete metadata.
## 4. Submit to the plugin directory
Open [Plugins in the OpenAI platform](https://platform.openai.com/plugins), upload the ZIP, and complete publisher verification. Connect and scan the MCP endpoint, resolve required findings, and supply the requested test cases, reviewer access, walkthrough and release notes. Submit for review and publish after approval. Follow OpenAI's [submission guide](https://developers.openai.com/plugins/deploy/submission) for the current requirements.
The portal requires domain verification for the MCP endpoint. Biel.ai controls the domain of its hosted endpoint: contact [Biel.ai support](mailto:support@biel.ai) to coordinate verification, or use a supported self-hosted endpoint on a domain you control. Connecting a hosted server privately does not complete public-directory verification.
## Existing custom GPTs
The [Custom GPT Actions guide](https://docs.biel.ai/integrations/custom-gpt.md) is archived for existing configurations. Use this MCP plugin guide for new documentation connections. Archiving the guide does not disable existing GPTs.
---
## Create a Claude connector for your documentation
# Claude documentation connector
Connect Claude to your Biel.ai project through remote MCP so it can use your indexed documentation in a conversation.
## Before you start
Index your documentation, enable hosted MCP on a Biel.ai plan that includes it, then select **MCP URL** in the widget's **Connect** menu. The endpoint must be reachable over HTTPS from Anthropic's servers.
Use the complete project URL. A public project needs no Biel.ai API key. For private content, review [MCP access configuration](https://docs.biel.ai/integrations/mcp-server.md#configuration-parameters) first. Shared credentials grant connector users the credential's project access.
## 1. Add a custom remote connector
For an individual account with connector access:
1. Open **Customize > Connectors** in Claude.
2. Select **+ Add > Add custom connector**.
3. Name the connector, for example **Your Product Docs**.
4. Paste your complete Biel.ai MCP URL and continue.
5. Review the detected authentication. Choose **No sign in** for a public project.
6. Finish adding the connector.
On Team or Enterprise, an authorized owner adds the endpoint under **Organization settings > Connectors > Add > Custom > Web**. Members then connect to it from **Customize > Connectors**. See Anthropic's [custom connector guide](https://support.claude.com/en/articles/11175166-get-started-with-custom-connectors-using-remote-mcp) for current account and role requirements.
## 2. Enable and test the connector
Start a conversation, use **+ > Connectors**, and enable your connector. Ask:
> Use Your Product Docs to explain how authentication works and cite the documentation.
Then test source retrieval:
> Search Your Product Docs for SDK authentication using `biel_search`, then read relevant documents with `biel_get_document`. Use the retrieved sources to answer and cite them.
The server exposes `biel_ai` for Biel-generated answers, `biel_search` for hybrid keyword and semantic retrieval, and `biel_get_document` for complete indexed document text. Normally the assistant searches, reads relevant documents, and writes its own answer. Use `biel_ai` when you specifically want Biel to answer. See [tools and limits](https://docs.biel.ai/integrations/mcp-server.md#generated-answers-or-document-retrieval).
Check a follow-up, a document with page or worksheet references, and a query with no result. Verify that source URLs work and that non-URL documents are identified by title and location.
## 3. Publish a connector in the Claude directory
For public distribution, open the **directory submission portal** linked from Anthropic's [plugin publishing guide](https://claude.com/resources/articles/build-plugins-for-claude). Choose the **Single MCP connector** route and provide your remote endpoint and listing details. Follow the portal's validation and review feedback, then publish after approval. Directory submission is available to developers on paid Claude plans.
Use a public documentation project for a public connector, or arrange supported authentication for the intended audience. Keep private API keys out of public listing details. A hosted endpoint connects to the specific Biel.ai project in its URL.
## Troubleshooting
- **Cannot connect:** copy the URL again, including its path. Check that MCP is enabled and that Anthropic can reach the endpoint.
- **403:** check private-project API-key permissions, allowed domains, and usage limits. Biel.ai does not provide OAuth through an API-key URL.
- **Timeout:** use source retrieval when Claude needs context to write its own answer. Generated answers can take longer; retries should follow a reported failure.
- **Updated tools are missing:** reconnect the custom connector and start a new conversation. Anthropic currently documents removing and re-adding a custom connector to change its configuration.
Use the [MCP troubleshooting guide](https://docs.biel.ai/integrations/mcp-server.md#troubleshooting) for project and session errors.
---
## Discord Integration for Biel.ai
# Discord integration
The Biel.ai Discord bot lets members of your server ask questions about your documentation in any channel using the `/ask` slash command.

## What you can do
- **Slash command**: members use `/ask` to get answers from your documentation.
- **Works in any channel**: the bot responds wherever it has permission, no setup per channel required.
- **Per-thread context**: an `/ask` from a channel root opens a Discord thread on the reply, and follow-up `/ask`s inside that thread share the same conversation.
- **Reset the conversation**: use `/clear` to start a fresh context in the current thread or DM.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai) with a project that has indexed content.
- A Discord server where you have **Manage Server** permission (required to authorize bots).
## Setup
1. Open your project in the [Biel.ai dashboard](https://app.biel.ai), then click **Settings**.
2. Select **Integrations** in the settings sidebar. On the Discord card, click **Connect**.
3. Discord opens an authorization page. Select the server where you want to install the bot and click **Authorize**.
4. After authorizing, you are redirected back to Biel.ai and the bot is connected.
The `/ask` command is available to all members of the server.
## Usage
### Asking questions
In any channel in your server, type:
```text
/ask question: How do I reset my password?
```
When you run `/ask` from a channel root, Biel posts the reply and opens a public Discord thread anchored to it. Run `/ask` again inside that thread to ask follow-up questions with the conversation history kept. A new `/ask` from the channel root always opens a new thread with fresh context. In DMs, the bot has no threads, so all `/ask`s in the same DM share one conversation.
### Starting a new conversation
Run `/clear` inside a thread or DM to reset its context. Only you see the confirmation, and your next `/ask` starts a fresh conversation.
:::tip[Not getting answers?]
Make sure your Biel.ai project has indexed content. Open the project dashboard and check that it shows **Sources loaded**.
:::
## Troubleshooting
**The `/ask` command doesn't appear**
Discord can take a few seconds to register new slash commands. Wait a moment and try again. If it still doesn't appear, try restarting your Discord client.
**The bot doesn't respond**
Check that the bot has **Send Messages** and **Use Application Commands** permissions in the channel. These can be configured in the channel's permission settings.
**The bot gives incorrect or outdated answers**
Re-index your documentation in the [Biel.ai dashboard](https://app.biel.ai) to make sure the bot is querying the latest content.
---
Need help? [Contact us](https://biel.ai/contact) or visit the [support page](/support).
---
## GitHub workflow integration
Use GitHub Actions to automatically sync your Biel.ai project when you push documentation changes.
## Before you begin
- A Biel.ai Business or Enterprise plan (required for API access).
- An API key from **Team** → **API keys**, with **Project access** set to your project and these permissions:
- `sources_create` (to upload site files)
- `sync_create` (to trigger content crawls)
- Your project slug from the Biel.ai dashboard.
## Choose your automation approach
You can automate two types of updates:
| Action | Purpose | When to use |
|--------|---------|-------------|
| **Content sync** | Trigger a crawl of existing sources | Sources already configured in dashboard; content has changed |
| **Site deployment** | Upload and index a built static site | Site is private (behind VPN, private GitHub Pages) |
:::tip Recommended approach
Configure URL sources in your Biel.ai dashboard, then use content sync to trigger crawls.
Use **site deployment** only for private sites that Biel.ai cannot access directly.
:::
## Set up content sync (recommended)
Use this workflow when your sources are already configured in your Biel.ai dashboard.
### 1. Create the workflow file
Create `.github/workflows/sync-biel.yml` in your repository:
```yaml
name: Sync Biel.ai
on:
push:
branches: [main]
paths:
- 'docs/**'
- '*.md'
workflow_dispatch:
env:
BIEL_PROJECT_SLUG: 'your-project-slug'
jobs:
sync:
runs-on: ubuntu-latest
steps:
- name: Sync Biel.ai Project
run: |
echo "Syncing Biel.ai project..."
if ! curl -f -X POST \
-H "Authorization: Api-Key ${{ secrets.BIEL_API_TOKEN }}" \
-H "Content-Type: application/json" \
https://app.biel.ai/api/v2/projects/$BIEL_PROJECT_SLUG/sync/; then
echo "❌ Failed to sync Biel.ai project"
exit 1
fi
echo "✅ Project sync accepted"
```
The sync request returns `202 Accepted`; indexing continues after the workflow finishes. Check **Sources loading** or **Sources loaded** in the project dashboard, or poll the [sync status endpoint](https://docs.biel.ai/api/get-sync-status.md).
### 2. Configure the workflow
1. Replace `your-project-slug` in the `env` section with your project slug from the Biel.ai dashboard.
2. In your GitHub repository, go to **Settings** > **Secrets and variables** > **Actions**.
3. Click **New repository secret** and add:
| Name | Value |
|------|-------|
| `BIEL_API_TOKEN` | Your Biel.ai API key |
See [Using secrets in GitHub Actions](https://docs.github.com/actions/security-for-github-actions/security-guides/using-secrets-in-github-actions) for details.
### 3. Customize the trigger paths
Update the `paths` section to match your documentation structure:
```yaml
paths:
- 'docs/**' # Trigger when docs folder changes
- 'content/**' # Or your content folder
- 'README.md' # Or specific files
- '**/*.md' # Or all markdown files
```
## Set up site deployment (for private sites)
Use this workflow only when your site is not publicly accessible.
:::important
Site uploads are limited to 250MB. [Contact us](https://biel.ai/contact) for higher limits.
:::
### 1. Create the deployment workflow
Create `.github/workflows/deploy-biel.yml` in your repository:
```yaml
name: Deploy to Biel.ai
on:
push:
branches: [main]
paths:
- 'docs/**'
- '*.md'
workflow_dispatch:
env:
BIEL_API_BASE_URL: 'https://app.biel.ai'
BIEL_PROJECT_SLUG: 'your-project-slug'
BIEL_SITE_NAME: 'wiki' # Lowercase identifier for your site
BIEL_BASE_URL: 'https://your-site.com'
BUILD_OUTPUT_DIR: 'site'
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
# Add your site build steps here
# Example:
# - name: Build site
# run: |
# npm install
# npm run build
- name: Deploy to Biel AI
if: github.ref == 'refs/heads/main'
run: |
cd $BUILD_OUTPUT_DIR && zip -r ../docs-site.zip . && cd ..
echo "Uploading site to Biel AI..."
if ! curl -f -X POST \
-H "Authorization: Api-Key ${{ secrets.BIEL_API_TOKEN }}" \
-F "site_zip=@docs-site.zip" \
-F "site_name=$BIEL_SITE_NAME" \
-F "base_url=$BIEL_BASE_URL" \
"$BIEL_API_BASE_URL/api/v2/projects/$BIEL_PROJECT_SLUG/sources/"; then
echo "❌ Failed to deploy to Biel AI"
exit 1
fi
echo "✅ Site uploaded successfully"
echo "Syncing site on Biel AI..."
if ! curl -f -X POST \
-H "Authorization: Api-Key ${{ secrets.BIEL_API_TOKEN }}" \
"$BIEL_API_BASE_URL/api/v2/projects/$BIEL_PROJECT_SLUG/sync/"; then
echo "❌ Failed to sync on Biel AI"
exit 1
fi
echo "✅ Site sync accepted"
```
### 2. Update environment variables
Replace the placeholder values in the `env` section:
- `BIEL_PROJECT_SLUG`: Your project slug from the Biel.ai dashboard
- `BIEL_SITE_NAME`: A lowercase identifier for your site source (e.g., `wiki`, `docs`, `help`)
- `BIEL_BASE_URL`: Your site's public URL
- `BUILD_OUTPUT_DIR`: Your build output directory (e.g., `dist`, `build`, `public`)
### 3. Add your build steps
Replace the commented build steps with your actual site generation commands.
## Test your workflow
After setting up your workflow:
1. Push a change to your documentation
2. Go to the **Actions** tab in your GitHub repository
3. Verify that the workflow runs successfully
You can also trigger the workflow manually by clicking **Run workflow** in the Actions tab.
---
## Make integration for RAG workflows
Connect Biel.ai to Make (formerly Integromat) to query your indexed documentation from any scenario. Use it to build support assistants, Slack bots, email automation, or any workflow that needs answers from your docs.
:::info
This integration requires a **Business** or **Enterprise** plan for API access.
:::
## Prerequisites
- A [Biel.ai account](https://app.biel.ai) with documentation indexed.
- A Business or Enterprise plan.
- A Make account.
- Your **project slug** from the Biel.ai dashboard.
- An **API key** from **Team** → **API keys**, with **Project access** set to your project and `chats_create` permission.
## Setup
### 1. Create a new scenario
Create a new scenario with the following modules:
1. **Trigger module** (e.g., Webhook, Custom webhook, Slack)
2. **HTTP module** to query Biel.ai
3. **Response module** to return results
### 2. Configure the HTTP module
Add an **HTTP > Make a request** module with these settings:
**URL:** `https://app.biel.ai/api/v2/projects/YOUR_PROJECT_SLUG/chats/`
**Method:** `POST`
**Headers:**
| Key | Value |
|-----|-------|
| `Content-Type` | `application/json` |
| `Authorization` | `Api-Key YOUR_API_KEY` |
Replace `YOUR_API_KEY` with your API key from your Biel.ai team settings.
**Body:**
```json
{
"message": "{{1.question}}"
}
```
Replace `{{1.question}}` with the appropriate variable from your trigger module. Replace `YOUR_PROJECT_SLUG` with your project slug from the Biel.ai dashboard.
For the full API reference, see [Biel.ai REST API](https://docs.biel.ai/api/biel-ai-api.md).
### 3. Process the response
The chat API returns a structured response:
```json
{
"user_message_id": "message-id",
"ai_message": {
"from": "ai",
"message": "AI-generated answer based on your documentation...",
"messageId": "ai-message-id",
"isPartial": false,
"timestamp": "2024-01-01T00:00:00Z",
"sources": [
{
"title": "Source page title",
"url": "https://docs.example.com/source"
}
]
},
"chat_uuid": "unique-conversation-id",
"restore_token": "opaque-conversation-token"
}
```
Use the returned data in subsequent modules:
- `{{2.ai_message.message}}` - The AI-generated answer
- `{{2.ai_message.sources}}` - Array of source documents with citations
- `{{2.chat_uuid}}` - Conversation ID for multi-turn chats
### 4. Continue the conversation (optional)
Retain both `chat_uuid` and `restore_token` from the response. For each subsequent request to the same project endpoint, include `chat_uuid` in the body and add this header:
| Key | Value |
|-----|-------|
| `X-Chat-Restore-Token` | `{{2.restore_token}}` |
```json
{
"message": "{{1.question}}",
"chat_uuid": "{{2.chat_uuid}}"
}
```
---
## Connect AI assistants to your documentation with MCP
# Docs MCP server
Connect ChatGPT, Claude, and coding assistants to your documentation through Biel.ai's hosted Model Context Protocol (MCP) server. Your assistant can search indexed content, read relevant documents, and answer with sources.
For browser agents visiting your documentation site, see [WebMCP](https://docs.biel.ai/integrations/webmcp.md).

## Requirements
- A Biel.ai project with indexed content.
- MCP access during your **14-day trial**, or on **Professional** or a higher plan. See [plans](https://biel.ai/pricing).
- An AI client that supports remote MCP connections.
- For private projects, **Business** or **Enterprise** and a project API key.
## Setup
1. Open your project in Biel.ai and go to **Settings > MCP**.
2. Select **Enable MCP server** and click **Save**.
3. Copy the **MCP endpoint** shown on the page and add it to your AI client.
For client-specific instructions, see the [ChatGPT plugin guide](https://docs.biel.ai/integrations/chatgpt-plugin.md) or [Claude connector guide](https://docs.biel.ai/integrations/claude-connector.md).
### Connect from the widget {#one-click-configuration}
You can also open the widget's **Connect** menu:
- **MCP URL** copies the endpoint to paste into another client's MCP settings.
- **Codex** copies a setup command. Run it in your terminal.
- **Claude Code** copies a setup command. Run it in your terminal.
- **Copilot (VS code)** opens VS Code's MCP setup flow.
- **Cursor** opens Cursor's MCP setup flow.
### Manual configuration
Add a remote MCP server in your client's settings and paste the complete endpoint supplied by Biel.ai. Choose **Streamable HTTP** if the client asks for a transport.
For example, a project endpoint may look like this:
```text
https://app.biel.ai/mcp/YOUR_PROJECT_SLUG
```
Use the URL supplied for your project and follow your client's remote MCP setup instructions.
## Available tools {#generated-answers-or-document-retrieval}
| Tool | What it does |
|------|--------------|
| `biel_search` | Searches indexed pages, files, repositories, and OpenAPI documents. Returns matching text and source references. |
| `biel_get_document` | Reads the indexed text of a document found by search. |
| `biel_ai` | Asks Biel.ai to generate an answer with sources. Supports follow-up questions within the connection's conversation. |
The assistant normally searches, reads relevant documents if it needs more context, and writes its own answer with citations. Document reads return the text indexed by Biel.ai.
Try asking:
> Search our docs for API authentication. Read the relevant documentation and explain how to rotate an API key, with source links.
When you want Biel.ai to generate the answer, ask:
> Ask Biel.ai how to configure single sign-on.
Searches, document reads, and AI answers share your team's [interaction allowance](https://docs.biel.ai/administration/subscription.md). Reading a long document may require several requests, each of which counts toward usage.
## Connection access {#configuration-parameters}
Public projects do not require an API key. For a private project, [create an API key](https://docs.biel.ai/api/biel-ai-api.md#create-an-api-key) restricted to that project and add it to the connection URL as `api_key`.
| URL parameter | When to use it |
|---------------|----------------|
| `api_key` | Required for private projects. The key needs `search` for search and document reads, and `chats_create` for AI answers. |
| `domain` | Required when your project restricts allowed domains. Use an allowed origin, such as `https://docs.example.com`. |
| `metadata` | Optional label identifying the client, such as `claude`. |
For example, a public project with domain restrictions can use:
```text
https://app.biel.ai/mcp/YOUR_PROJECT_SLUG?domain=https%3A%2F%2Fdocs.example.com
```
URL-encode parameter values. Keep URLs containing API keys private: anyone with the URL can use the key's project access. Do not include them in public listings or shared setup files.
## Widget customization
### Hide connect button
Add `hide-connect-button="true"` to your widget to hide its **Connect** menu.
To disable access, open your project in the Biel.ai dashboard and go to **Settings > MCP**. Turn off **Enable MCP server** to disable both hosted MCP and WebMCP. Turn off only **Enable WebMCP** to disable browser tools while keeping hosted MCP available.
### Custom MCP server URL
Add `mcp-server-url="https://mcp.example.com/your-endpoint"` to your widget to show a different endpoint in the **Connect** menu. This setting applies only to hosted MCP.
See [widget customization](https://docs.biel.ai/customization/layout.md) for more settings.
## Self-hosted option
To run your own MCP server, follow the [self-hosting guide](https://github.com/TechDocsStudio/biel-mcp).
## Troubleshooting
| Problem | What to do |
|---------|------------|
| The client cannot connect | Copy the endpoint again from **Settings > MCP**. Check that MCP is enabled, your plan includes it, and the client can reach the endpoint. |
| The assistant does not search your docs | Enable the connection in your client and explicitly ask it to use `biel_search`. Check that your project has indexed content. |
| Access is denied | Check the API key's project access and permissions, allowed domains, and your team's usage allowance. |
| A document is unavailable | Search again for a current result. If it is still unavailable, recrawl the source in Biel.ai. |
| Tools are missing or the session has expired | Refresh or reconnect the MCP server in your client, then start a new conversation. |
---
## Microsoft Teams Integration for Biel.ai
# Microsoft Teams integration
Deploy the Biel.ai bot in Microsoft Teams so your team can ask questions to your documentation from any channel, group chat, or direct message.

## What you can do
- **Surfaces**: team channels, group chats, and personal chats.
- **Per-conversation context**: each channel thread, DM, and group chat keeps its own conversation history.
- **Reset the conversation**: send `/clear` to start a fresh conversation context.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai) with documentation indexed.
- **Teams Administrator** access to your Microsoft 365 organization.
## Setup
### 1. Download the app package
Open your project, click **Settings**, then select **Integrations** in the settings sidebar.
**(Optional) Customize the bot name.** By default the bot appears as **Biel** in Teams. To use your own name, click **Customize bot name** on the Microsoft Teams card, enter the name, and save. Leave it blank to keep the default.
On the Microsoft Teams card, click **Download manifest**.
This downloads a `biel-teams-app.zip` file containing the bot manifest and icons, ready to upload to your Teams Admin Center.
:::note
The bot name is baked into the downloaded package, so set it **before** downloading the manifest. Once the app is installed in Teams, the **Customize bot name** option is no longer available — renaming an installed app would require uploading a new app version through your Teams Admin Center.
:::
### 2. Upload the app to your Teams Admin Center
A Teams administrator in your organization must upload the package:
1. Open [Teams Admin Center](https://admin.teams.microsoft.com).
2. Go to **Teams apps** → **Manage apps** → **Upload new app**.
3. Upload the `biel-teams-app.zip` file.
4. Under **Permission policies**, configure which users or groups can install the app.
:::tip
If your organization has strict app permission policies, you may need to explicitly allow the Biel app for the relevant users or groups before it becomes discoverable in the Teams app store.
:::
### 3. Generate a setup token
Back in **Settings** → **Integrations**, click **Generate token** under **Setup token** on the Microsoft Teams card.
Copy the setup token that appears.
### 4. Connect the bot
Open a chat with the Biel bot in Teams (search for **Biel** in the Teams app store and click **Add**) and send the setup token as your first message.
The bot will confirm the connection:
```text
Connected! This Teams workspace is now linked to the [Project Name] project.
You can start asking questions.
```
From this point on, all messages from your Teams organization are routed to the linked Biel project.
:::note
The setup token is single-use. It is consumed when the connection is established. If you ever need to reconnect or link a different project, generate a new token from the project settings page.
:::
## Usage
### Asking questions
Send any message to the bot.
```text
You: How do I reset my password?
Biel: To reset your password, go to Settings → Security → Reset Password and follow the steps shown.
```
You can ask follow-up questions:
```text
You: What permissions do I need for that?
Biel: You need the Account Owner or Admin role to access the Security settings.
```
In a channel, mentioning the bot from the channel root opens a new thread anchored to your message, and replies inside that thread share context. To start a fresh conversation, post a new message from the channel root.
### Starting a new conversation
Send `/clear` to reset the current thread or chat. The bot confirms, and your next message starts a fresh conversation.
:::tip[Not getting answers?]
Make sure your Biel.ai project has indexed content. Open the project dashboard and check that it shows **Sources loaded**.
:::
## Troubleshooting
**The bot doesn't appear in the app store**
Check that the app has been approved and that the user is covered by the configured permission policy in Teams Admin Center.
**The bot asks for a setup token instead of answering questions**
The Teams workspace has not been connected to a Biel project yet. In **Settings** → **Integrations**, generate a token on the Microsoft Teams card, and send it to the bot as described in step 4.
**The bot doesn't respond after sending the token**
Make sure you are sending the token exactly as shown (no extra spaces or characters). If the problem persists, generate a new token and try again.
**The bot doesn't respond to questions**
Ensure your Biel.ai project has documentation indexed. Contact [Biel support](https://biel.ai) if the issue persists.
**Responses are incorrect or outdated**
Re-index your documentation in the [Biel.ai dashboard](https://app.biel.ai) to make sure the bot is querying the latest content.
---
Need help? [Contact us](https://biel.ai/contact) or visit the [support page](/support).
---
## n8n integration for RAG workflows
Connect Biel.ai to n8n to query your indexed documentation from any workflow. Use it to build support assistants, Slack bots, email automation, or any workflow that needs answers from your docs.
:::info
This integration requires a **Business** or **Enterprise** plan for API access.
:::
## Prerequisites
- A [Biel.ai account](https://app.biel.ai) with documentation indexed.
- A Business or Enterprise plan.
- An n8n instance (cloud or self-hosted).
- Your **project slug** from the Biel.ai dashboard.
- An **API key** from **Team** → **API keys**, with **Project access** set to your project and `chats_create` permission.
## Setup
### 1. Create a new workflow
Create a new workflow with the following nodes:
1. **Trigger node** (e.g., Webhook, Manual, Slack)
2. **HTTP Request node** to query Biel.ai
3. **Output node** to return results
### 2. Configure the HTTP Request node
Add an **HTTP Request** node with these settings:
**Method:** `POST`
**URL:** `https://app.biel.ai/api/v2/projects/YOUR_PROJECT_SLUG/chats/`
**Headers:**
```json
{
"Content-Type": "application/json",
"Authorization": "Api-Key YOUR_API_KEY"
}
```
Replace `YOUR_API_KEY` with your API key from your Biel.ai team settings.
**Body (JSON):**
```json
{
"message": "={{ $json.question }}"
}
```
Replace `YOUR_PROJECT_SLUG` with your project slug from the Biel.ai dashboard.
For the full API reference, see [Biel.ai REST API](https://docs.biel.ai/api/biel-ai-api.md).
### 3. Process the response
The chat API returns a structured response:
```json
{
"user_message_id": "message-id",
"ai_message": {
"from": "ai",
"message": "AI-generated answer based on your documentation...",
"messageId": "ai-message-id",
"isPartial": false,
"timestamp": "2024-01-01T00:00:00Z",
"sources": [
{
"title": "Source page title",
"url": "https://docs.example.com/source"
}
]
},
"chat_uuid": "unique-conversation-id",
"restore_token": "opaque-conversation-token"
}
```
### 4. Continue the conversation (optional)
Retain both `chat_uuid` and `restore_token` from the response. For each subsequent request to the same project endpoint, set the `X-Chat-Restore-Token` header to the stored token (for example, `={{ $json.previousRestoreToken }}`) and include the stored `chat_uuid`:
```json
{
"message": "={{ $json.question }}",
"chat_uuid": "={{ $json.previousChatId }}"
}
```
---
## Slack Integration for Biel.ai
# Slack integration
Connect your Biel.ai project to Slack and let users interact with your documentation bot from any channel or direct message.

## What you can do
- **Answer questions in channels**: users mention `@Biel.ai` and get an answer in a thread.
- **Per-thread context**: each thread has its own conversation history.
- **Direct message support**: users chat with the bot privately.
- **Reset the conversation**: mention the bot with `clear` inside a thread to reset context.
## Prerequisites
- A [Biel.ai account](https://app.biel.ai) with at least one project and indexed documentation.
- A **Slack workspace** where you have permission to install apps.
- Admin access to your Biel.ai dashboard.
## Setup
### 1. Connect your Slack workspace
1. In the Biel.ai dashboard, open the project you want to connect.
2. Click **Settings**, then select **Integrations** in the settings sidebar.
3. On the Slack card, click **Connect**.
4. You will be redirected to Slack's authorization screen. Review the permissions and click **Allow**.
5. Once authorized, Slack redirects back to Biel.ai and the workspace is connected.
### 2. Invite the bot to a channel
After connecting, invite the bot to any channel where you want it to respond:
```text
/invite @Biel.ai
```
For direct messages, users can find the bot by searching its name in the Slack search bar.
## Advanced: use your own Slack app
By default the bot appears as **Biel.ai**. If you'd rather it show up under your
own name (for example `Support Assistant`), you can create your **own Slack app**
and point it at Biel — the bot then uses the name and icon you choose, with no
Biel branding.
This replaces the standard **Connect** button above; you only need one of the two
methods.
### 1. Create your Slack app
1. Go to [api.slack.com/apps](https://api.slack.com/apps) → **Create New App** → **From scratch**, and give it the name you want.
2. Under **OAuth & Permissions** → **Bot Token Scopes**, add: `chat:write`, `app_mentions:read`, `im:history`, `users:read`, `users:read.email`.
The last two (`users:read`, `users:read.email`) let Biel show **who** started each conversation — it looks up the sender's email so the chat appears under their address in your dashboard instead of "Unknown". They're optional: if you leave them out, conversations still work but stay unattributed.
3. Under **Event Subscriptions**, set the **Request URL** to:
```text
https://app.biel.ai/api/v1/slack/webhook/
```
Slack verifies it automatically. Then, under **Subscribe to bot events**, add `app_mention` and `message.im`.
4. Go back to **OAuth & Permissions** and, in the **OAuth Tokens** section, click **Install to _(your workspace name)_**, then **Allow** on the confirmation screen. This adds the bot to your workspace and generates its **Bot User OAuth Token**. You need permission to install apps in the workspace; if you don't, an admin has to approve it.
### 2. Copy the two credentials
- **Bot User OAuth Token** (`xoxb-...`) — from **OAuth & Permissions**.
- **Signing Secret** — from **Basic Information → App Credentials**.
### 3. Connect it in Biel.ai
1. In your project, go to **Settings → Integrations**.
2. On the Slack card, click **Use your own Slack app (advanced)**.
3. Paste the **Bot User OAuth Token** and **Signing Secret**, then click **Connect**.
Biel figures out the rest (your workspace and bot identity) automatically. Once
connected, [invite the bot to a channel](#2-invite-the-bot-to-a-channel) and use
it exactly as below — just with your chosen name instead of `@Biel.ai`.
:::note
A Slack workspace runs one Biel-connected app at a time. Your own app replaces the
default one for that workspace — don't connect both.
:::
## Usage
### Asking questions
In a channel, mention the bot followed by your question:
```text
@Biel.ai how do I authenticate with the API?
```
The bot replies in a thread anchored to your message.
To ask a follow-up with the same context, mention `@Biel.ai` again inside that thread, and Biel uses the thread's history. Mentions from the channel root always start a new thread with fresh context.
In a direct message, send your message directly, no mention needed:
```text
What are the system requirements?
```
### Resetting a conversation
Each thread keeps its own context for follow-up questions. To reset a thread, mention the bot with `clear` inside it:
```text
@Biel.ai clear
```
The bot confirms in the thread, and your next message there starts a fresh conversation. Other threads are unaffected.
:::tip[Not getting answers?]
Make sure your Biel.ai project has indexed content. Open the project dashboard and check that it shows **Sources loaded**.
:::
## Bot token scopes
Biel.ai requests these Slack bot token scopes. The default **Connect** flow lists them on Slack's authorization screen, and you add them by hand when you [use your own Slack app](#1-create-your-slack-app).
| Scope | Required | Why Biel needs it |
| ----- | -------- | ----------------- |
| `app_mentions:read` | Yes | Detects when users mention `@Biel.ai` in a channel so the bot can answer in a thread. |
| `chat:write` | Yes | Posts the bot's answers and confirmation messages back into channels and threads. |
| `im:history` | Yes | Reads direct messages sent to the bot so users can ask questions privately. |
| `users:read` | For attribution | Looks up the sender of each conversation so your dashboard shows who started it instead of "Unknown". |
| `users:read.email` | For attribution | Resolves the sender's email so conversations are attributed to that user in your dashboard. |
The two attribution scopes are optional. Leave them out and the bot still works, but conversations stay unattributed in your dashboard. See [Conversations show "Unknown"](#troubleshooting) if attribution isn't working.
## Troubleshooting
**The bot does not respond to mentions**
Make sure the bot has been invited to the channel with `/invite @Biel.ai`. The bot can only see messages in channels it has been added to.
**The conversation won't reset**
Reset is per thread: mention the bot with `clear` (`@Biel.ai clear`) *inside the thread* you want to reset. There is no channel-wide or slash-command reset.
**The bot gives incorrect or outdated answers**
Re-index your documentation in the [Biel.ai dashboard](https://app.biel.ai) to make sure the bot is querying the latest content.
**Conversations show "Unknown" instead of the user's email**
Email attribution needs the `users:read` and `users:read.email` scopes. If you connected Slack before these were added, reconnect the integration (or, for your own Slack app, add the two scopes and reinstall the app to your workspace) to grant them. Conversations started after reconnecting will be attributed; older ones stay as they were.
---
Need help? [Contact us](https://biel.ai/contact) or visit the [support page](/support).
---
## WebMCP for docs: connect browser agents to your documentation
# WebMCP for docs
WebMCP lets a browser agent search your documentation, read indexed documents, and request Biel.ai answers while visiting a page with the Biel.ai widget.
The agent and browser must support WebMCP. Other MCP clients can connect through your [hosted MCP server](https://docs.biel.ai/integrations/mcp-server.md) without visiting the page.
## Requirements
- A Biel.ai project with indexed content and MCP access: a **14-day trial**, **Professional**, or a higher plan. See [plans](https://biel.ai/pricing).
- The latest [Biel.ai widget](https://docs.biel.ai/installation.md). Update your widget if you use a pinned version or bundle it with your site.
- An HTTPS page and a browser agent that supports WebMCP.
WebMCP is experimental and browser support is limited. See Chrome's [WebMCP guide](https://developer.chrome.com/docs/ai/webmcp) for availability and testing instructions. Visitors using other browsers can use the widget as usual.
## Enable WebMCP
1. Open your project in Biel.ai and go to **Settings > MCP**.
2. Select **Enable MCP server** and **Enable WebMCP**, then click **Save**.
3. Load a page containing your widget in a supporting browser.
**Enable WebMCP** is on by default for new and existing projects. It takes effect when MCP is enabled and your plan includes MCP access. No additional embed code is needed, and the widget dialog can stay closed.
Turn off **Enable WebMCP** to disable browser tools while keeping hosted MCP available. Turning off **Enable MCP server** disables both. Downgrading to **Starter** also disables WebMCP.
## Available tools
| Tool | What it does |
|------|--------------|
| `biel_search` | Searches your indexed pages, files, repositories, and OpenAPI documents. Returns matching text and source references. |
| `biel_get_document` | Reads the indexed text of a document found by search. |
| `biel_ai` | Asks Biel.ai to generate an answer with sources. |
The agent normally searches, reads relevant documents if it needs more context, and writes its own answer with citations. Use `biel_ai` when you want a Biel.ai-generated answer. Each AI call starts a separate conversation from the visitor's widget chat.
Searches, document reads, and AI answers share your team's [interaction allowance](https://docs.biel.ai/administration/subscription.md). Reading a long document may require several requests, each of which counts toward usage.
## Try it
Open your documentation site in a supporting browser agent and ask:
> Use this site's Biel tools to find how API authentication works. Read the relevant documentation and explain the steps with source links.
The agent should discover the tools, search your indexed content, and use the results in its answer. Tools become available when the agent visits the page. Installing the widget does not add your site to every MCP client's tool list.
## Private projects
Private projects require **Business** or **Enterprise**. The widget's API key needs `projects_read` to load the project, `search` for search and document reads, and `chats_create` for AI answers.
A key included in a page is visible to visitors who can access it. Keep private-project widgets on a site restricted to the intended readers. See [API keys](https://docs.biel.ai/api/biel-ai-api.md#create-an-api-key) and [security](https://docs.biel.ai/security/overview.md).
## Troubleshooting
| Problem | What to do |
|---------|------------|
| The agent cannot find the tools | Check browser and agent support, update the widget, and confirm both MCP settings and your plan access. Widgets using `disable-input="true"` or `fetch-data="false"` do not expose tools. |
| The widget is inside an iframe | The parent page must allow the `tools` permission for that iframe. Follow the browser's WebMCP setup instructions. |
| A call is denied | Check API key permissions, allowed domains, and your team's usage allowance. |
| A document is unavailable | Search again. If it is still unavailable, recrawl the source in Biel.ai. |
| An AI call asks for terms acceptance | Open the widget and accept its chatbot terms. |
Hiding the widget's **Connect** button does not disable WebMCP. Use **Settings > MCP > Enable WebMCP** to turn it off.
---
## Zapier integration for RAG workflows
Connect Biel.ai to Zapier to query your indexed documentation from any Zap. Use it to build support assistants, Slack bots, email automation, or any workflow that needs answers from your docs.
:::info
This integration requires a **Business** or **Enterprise** plan for API access.
:::
## Prerequisites
- A [Biel.ai account](https://app.biel.ai) with documentation indexed.
- A Business or Enterprise plan.
- A Zapier account.
- Your **project slug** from the Biel.ai dashboard.
- An **API key** from **Team** → **API keys**, with **Project access** set to your project and `chats_create` permission.
## Setup
### 1. Create a new Zap
Create a new Zap with the following steps:
1. **Trigger** (e.g., New Email, Slack Message, Form Submission)
2. **Webhooks by Zapier** action to query Biel.ai
3. **Action** to return or send results (e.g., Send Email, Post to Slack)
### 2. Configure the Webhooks action
Add a **Webhooks by Zapier > POST** action with these settings:
**URL:** `https://app.biel.ai/api/v2/projects/YOUR_PROJECT_SLUG/chats/`
**Payload Type:** `json`
**Data:**
| Key | Value |
|-----|-------|
| `message` | `Question from step 1` |
Replace `Question from step 1` with the field from your trigger that contains the user's question. Replace `YOUR_PROJECT_SLUG` with your project slug from the Biel.ai dashboard.
**Headers:**
| Key | Value |
|-----|-------|
| `Content-Type` | `application/json` |
| `Authorization` | `Api-Key YOUR_API_KEY` |
Replace `YOUR_API_KEY` with your API key from your Biel.ai team settings.
For the full API reference, see [Biel.ai REST API](https://docs.biel.ai/api/biel-ai-api.md).
### 3. Process the response
The chat API returns a structured response:
```json
{
"user_message_id": "message-id",
"ai_message": {
"from": "ai",
"message": "AI-generated answer based on your documentation...",
"messageId": "ai-message-id",
"isPartial": false,
"timestamp": "2024-01-01T00:00:00Z",
"sources": [
{
"title": "Source page title",
"url": "https://docs.example.com/source"
}
]
},
"chat_uuid": "unique-conversation-id",
"restore_token": "opaque-conversation-token"
}
```
Use the returned data in subsequent steps:
- `Ai Message Message` - The AI-generated answer
- `Ai Message Sources` - Array of source documents with citations
- `Chat Uuid` - Conversation ID for multi-turn chats
### 4. Continue the conversation (optional)
Store both `chat_uuid` and `restore_token` from the response using **Storage by Zapier**. For each subsequent request to the same project endpoint, set the `X-Chat-Restore-Token` header to the stored **Restore Token** value and include the stored conversation ID:
**Data:**
| Key | Value |
|-----|-------|
| `message` | `Question from step 1` |
| `chat_uuid` | `Chat Uuid from step 2` |
---
## Integrations
Connect Biel.ai to AI development tools, IDEs, and other platforms to give them access to your documentation.
MCP Server
Connect AI coding assistants to your documentation
WebMCP
Browser tools to search and read indexed docs, or request AI answers
GitHub workflow
Automate documentation syncing with GitHub Actions
ChatGPT plugin
Connect ChatGPT to your documentation through MCP
Claude connector
Connect Claude to your documentation through MCP
Zapier
Connect Biel.ai with thousands of apps
Make
Automate workflows with Make
n8n
Integrate with n8n workflows
Slack
Answer questions from your docs in Slack
Discord
Answer questions from your docs in Discord
Microsoft Teams
Deploy the Biel bot in Microsoft Teams
---
## Set up the AI assistant for your docs
# Quickstart
[Biel.ai](https://biel.ai) adds AI-powered chat and search to your documentation site. Users ask questions in plain language and get answers drawn from your content — instead of browsing pages or filing support tickets.
In this tutorial, you create a Biel.ai account, index your documentation, and test the assistant from the dashboard. Later, you can embed the assistant or search widget on your site.
## 1. Create your Biel.ai account
The standard 14-day trial includes Business features, 10,000 indexed pages shared across your team, 25,000 monthly interactions, and unlimited projects. See [Manage subscription](./administration/subscription.md) for usage and billing details.
1. Open [app.biel.ai](https://app.biel.ai).
2. Click **Sign up**.
3. Enter your **Work email** and **Password**. You can also add your **Name** and **Company name**.
4. Accept the **Terms of service** and **Privacy policy**, then click **Create account**.
5. Open the verification link in your email to activate your account.

## 2. Create a project
A project groups your content sources and powers the assistant. Each project has its own index, settings, and analytics.
1. In the dashboard, click **Projects** > **Create project**.
2. Enter a **Name** for your project.
3. Add one or more **Sources** to index:
| Source type | Description |
|---|---|
| **URLs** | Individual webpages, such as `https://docs.biel.ai/`. |
| **Sitemaps** | Multiple pages from a sitemap URL. |
| **GitHub** | Documentation files from a repository. |
| **OpenAPI** | API documentation from an OpenAPI specification URL. |
| **Confluence** | Pages from a Confluence space. |
To use **Files**, create the project first, then upload your documents in **Settings** > **Sources** > **Files**.

4. Click **Create project**. If you added only one URL, click **Proceed anyway** in the coverage warning, or cancel to add more sources.
5. On **Install the widget**, choose **AI Assistant** or **AI Search**. Preview the widget and optionally expand **Customize appearance**.

6. Under **Add to your website**, use **Copy code** to copy the snippet for your website. You can install it later.

7. Click **Continue to test**.
Biel.ai crawls and indexes your sources while you set up the widget. The next screen shows **Your project is ready to test** when processing finishes.
## 3. Test the assistant {#3-test-the-chatbot}
Now that your content is indexed, verify that the assistant returns accurate answers:
1. On **Test your project**, click **Test assistant**.
2. In the chat window, type a question about your indexed content and click **Send**.

Close the chat window, then click **Go to project** to view your saved conversations and settings. You can start another test from **New chat** on the project dashboard. The dashboard shows **Sources loading** during a crawl and **Sources loaded** when it finishes.
:::tip[Not getting good answers?]
- Check **Logs** to verify that your sources were indexed correctly.
- Adjust the assistant behavior in **Settings**.
- Click **Refresh sources** to re-crawl your content.
:::
## Next steps
Your project is ready. Choose how you want to surface it to users:
- **Assistant widget** — Embed an AI chat button on your site. See the [Installation](/installation) guides for your platform.
- **Search widget** — Add an AI-powered search bar instead of (or alongside) the assistant. See [Install biel-search](/installation/cdn#add-the-search-widget).
- **MCP server** — Let developers query your docs from AI coding assistants like Claude or Cursor. See [MCP Server](/integrations/mcp-server).
- **Integrations** — Connect Biel.ai to GitHub Actions, ChatGPT plugins, Zapier, and more. See [Integrations](/integrations).
---
## Release notes
Track changes to the Biel.ai platform and its open-source packages.
## Product updates
Product announcements and feature highlights are published in the [Biel.ai changelog](https://biel.ai/changelog).
## Package updates
### Core packages
biel-search
Core assistant and search widget package
Coming soon
### Integrations
biel-react
AI assistant component for React applications
CHANGELOG
docusaurus-biel
Official Biel.ai plugin for Docusaurus sites
CHANGELOG
mkdocs-biel
Official Biel.ai plugin for MkDocs sites
CHANGELOG
sphinx-biel
Official Biel.ai extension for Sphinx documentation
CHANGELOG
starlight-biel
Official Biel.ai plugin for Starlight sites
CHANGELOG
astro-biel
Official Biel.ai integration for Astro sites
CHANGELOG
Biel.ai Assistant for WordPress
Official Ask AI assistant plugin for WordPress
WORDPRESS.ORG
Biel.ai Search for WordPress
Official AI site-search plugin for WordPress
WORDPRESS.ORG
biel-mcp
Model Context Protocol server for connecting AI tools to your documentation
CHANGELOG
---
## Production checklist
Review these security measures before deploying your Biel.ai assistant to production.
## Widget integrations
- [ ] **Restrict allowed domains** — List authorized domains in **Settings** > **Security & Privacy** > **Access Control** > **Allowed domains**.
- [ ] **Enable 2FA** — Open **My account** > **Profile** and click **Enable** under **Two-factor authentication** for each dashboard user.
- [ ] **Configure data privacy** — Enable PII removal or Terms & Conditions as needed. See [Data privacy](https://docs.biel.ai/customization/data-privacy.md).
- [ ] **Limit client-side API key permissions** — Public widgets need no key. For a private widget, use a project-scoped key with only the permissions its features need: `projects_read`, `search`, and `chats_create` in API v2. `chats_create` permits generating answers and consumes interactions; it is not read-only.
- [ ] **Secure high-privilege keys server-side** — Store keys with write permissions (`sources_create`, `sources_delete`) in environment variables or a secrets manager. Never expose in client-side code.
## API integrations
- [ ] **Authenticate protected operations** — Include `Authorization: Api-Key ` when calling private projects or operations that require a key. Check the endpoint's required permission in the [API reference](https://docs.biel.ai/api/biel-ai-api.md).
- [ ] **Rotate API keys regularly** — Establish a rotation schedule for all active keys.
- [ ] **Store keys securely** — Use environment variables, encrypted config, or a secrets manager (AWS Secrets Manager, Azure Key Vault, HashiCorp Vault). Never hardcode or commit keys to version control.
- [ ] **Verify token access** — Confirm tokens are not in public repositories and are shared only with authorized team members.
- [ ] **Remove unused keys** — Open **Team** > **API keys**, select the key, and click **Remove API key** for keys that are no longer in use.
---
## Security overview
Biel.ai is designed to meet enterprise security requirements for data protection, compliance, and transparency.
## Configurable security features
| Feature | Description |
|---------|-------------|
| **Role-based access (RBAC)** | Restricts dashboard access to authorized users with segmented permissions. |
| **Domain restrictions** | Limits which domains can embed the assistant widget. |
| **Rate limiting** | Per-session and per-IP limits to prevent spam and abuse. |
| **PII removal** | Automatically detects and redacts names, emails, and phone numbers from conversations. |
| **API key authentication** | Enable **Require authentication for all API access** under **Settings** > **Security & Privacy** > **Access Control** to make a project private. Send keys as `Authorization: Api-Key `. |
| **Granular API permissions** | Scope each API key to the operations it needs, such as `projects_read`, `search`, `chats_create`, and `sources_create` in API v2. Legacy names remain valid aliases. |
| **Project-scoped API keys** | Limit a key to a single project when you create it, so it can't reach your other projects or read the team. |
## Security architecture
| Layer | Protection |
|-------|-----------|
| **Network** | Firewalls, DDoS mitigation, continuous monitoring, and real-time alerts. |
| **Data encryption** | Encrypted in transit and at rest. Automated backups for recovery. |
| **Audit logs** | Detailed logs of security-sensitive operations for accountability. |
| **Account isolation** | Customer data is strictly separated between accounts. |
| **No model training** | Customer content and end-user conversations are not used to train third-party AI models. |
| **GDPR support** | A DPA, data controls, and EU data residency options support customer compliance requirements. |
See the [Privacy Policy](https://biel.ai/privacy) for details on data handling.
---
## Providers
These third-party providers help Biel.ai deliver, secure, support, and bill for the service. Whether a provider processes customer personal data depends on the features and configuration a customer uses.
The locations below describe primary service regions, not a promise that every category of data remains exclusively in that region. Where personal data is transferred outside the European Economic Area, Biel uses the transfer safeguards described in the [Data Processing Agreement](https://biel.ai/dpa). Customer-specific residency commitments are documented in the applicable order or agreement.
We give customers advance notice before adding a provider that will process customer personal data on Biel's behalf. Questions or data-protection objections can be sent to [info@biel.ai](mailto:info@biel.ai).
Alphabet
Provides Gemini AI models.
Location: USA and EU
Anthropic
Provides Claude AI models.
Location: USA
Brevo
Manages email services.
Location: EU
Cloudflare
Provides secure and scalable storage.
Location: USA
GitHub
Hosts our code.
Location: USA
DigitalOcean
Provides hosting and infrastructure.
Location: USA and EU
OpenAI
Powers GPT models.
Location: USA
Sentry
Monitors errors.
Location: USA
Stripe
Handles secure payments.
Location: USA
Typesense
Provides fast and typo-tolerant search capabilities.
Location: USA
Netlify
Hosts our web content.
Location: USA
---
## Security
Security features, architecture, and compliance in Biel.ai.
Overview
Security overview and architecture
Checklist
Security checklist for deployment
Providers
Third-party service providers
---
## Support
## Documentation
- [Quickstart](https://docs.biel.ai/quickstart.md) — Create an account and test the assistant.
- [Installation](https://docs.biel.ai/installation.md) — Platform-specific setup guides.
- [Customization](https://docs.biel.ai/customization.md) — Configure appearance and behavior.
- [Administration](https://docs.biel.ai/administration.md) — Manage teams, projects, and billing.
- [Integrations](https://docs.biel.ai/integrations.md) — Connect to MCP, GitHub Actions, Zapier, and more.
## FAQs
See [Frequently asked questions](https://biel.ai/#faqs) on the Biel.ai website.
## Contact us
Email `support@biel.ai` for help. Available Monday–Friday, 9 AM–5 PM EST. Response time: within 48 hours.
## Feedback
Share your feedback