# Bold Documentation
Bold turns your video library into searchable, AI-queryable knowledge: hosted, transcribed, chaptered, and ready to answer your members' questions with citations to the exact moment. Whether you're uploading your first video or building a custom integration, start here.
## I want to…
* **Get my first video live** → [Quickstart](/guides/quickstart)
* **Put a video on my website** → [Embedding](/guides/embedding)
* **Set up my branded portal** → [Your Portal](/guides/portal)
* **Let members ask questions about my content** → [AI Features](/guides/ai-features)
* **Build my own frontend** → [Next.js Starter](/sdk/nextjs-starter)
* **Stop password sharing** → [Session Management](/sdk/session-management)
## Using Bold
The admin panel, from upload to portal:
## Building with Bold
APIs, SDK, and starters for custom integrations:
## Quick taste
```bash
curl "https://app.boldvideo.io/api/v1/videos" \
-H "Authorization: Bearer YOUR_API_KEY"
```
Get an API key under [Settings → Developer](https://app.boldvideo.io/settings/developer), then explore the [API docs](/api).
## For AI assistants
These docs are LLM-first: [`/llms.txt`](/llms.txt) indexes every page, [`/llms-full.txt`](/llms-full.txt) is the whole site in one file, and the API ships an [OpenAPI spec and its own llms.txt](/api/machine-readable). Point your agent at them.
# Authentication
## API keys
Create an API key under [**Settings → Developer**](https://app.boldvideo.io/settings/developer). Keys look like this:
```
bold_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
```
The full key is shown **once**, at creation. Copy it, download it as an `.env` file, or grab a ready-made SDK snippet from the same dialog.
## Making authenticated requests
Send the key as a Bearer token in the `Authorization` header:
```bash
curl "https://app.boldvideo.io/api/v1/videos" \
-H "Authorization: Bearer bold_live_XXXXXXXXXXXXXXXX"
```
Requests without a valid key receive a `401`:
```json
{ "error": "Unauthorized", "status": 401 }
```
## Keep keys server-side
Your API key grants access to your whole channel, including viewer data. Treat it like a password:
* **Never ship it in browser or mobile code.** Call Bold from your backend, or proxy requests through your server.
* Store it in environment variables, not in source control.
* If a key leaks, revoke it in **Settings → Developer** and create a new one.
Building a viewer-facing frontend? Public content endpoints still require your key, so route those calls through your backend (the [Next.js starter](/sdk/nextjs-starter) shows the pattern with server components).
## The three auth layers
Most integrations only ever need layer 1. The other two exist for session management (password-sharing prevention):
| Layer | Credential | Used by | For |
| --------------------- | ------------------------------------------------------ | ------------- | -------------------------------------------------------------------------------------------------------- |
| **1. Tenant API key** | `Authorization: Bearer bold_live_…` | Your backend | All standard endpoints: videos, viewers, AI, progress, community, server-side session management |
| **2. Viewer runtime** | Your auth provider's JWT + `X-Bold-Tenant-Slug` header | Your frontend | `/auth/sessions/*` and `/auth/challenges/*`: viewers registering and verifying their own device sessions |
| **3. Admin controls** | Tenant API key | Your backend | `/admin/*`: auth policy and per-viewer session overrides |
The [Session Management SDK guide](/sdk/session-management) walks through when each layer comes into play.
# Errors
Errors come back with an appropriate HTTP status code and a JSON body:
```json
{
"error": "Unauthorized",
"status": 401,
"timestamp": "2026-07-10 08:39:57.287380Z"
}
```
Some endpoints include additional context (for example a `message` or field-level details on validation errors). The shape above is the guaranteed baseline.
## Status codes
| Code | Meaning | Typical cause |
| ----- | -------------------- | ------------------------------------------------------------------------- |
| `200` | OK | |
| `201` | Created | Resource created (e.g. viewer, post) |
| `400` | Bad Request | Malformed JSON or invalid parameters |
| `401` | Unauthorized | Missing or invalid API key |
| `403` | Forbidden | Key is valid but not allowed to do this |
| `404` | Not Found | Wrong ID, or the resource isn't visible to the API (e.g. a private video) |
| `422` | Unprocessable Entity | Validation failed: check the response body |
| `429` | Too Many Requests | Slow down; retry with backoff |
| `5xx` | Server error | Rare; safe to retry with backoff |
## Handling errors well
* **Retry `429` and `5xx`** with exponential backoff; treat `4xx` (except `429`) as bugs to fix, not transient failures.
* **Don't parse error strings**: branch on the status code.
* A `404` on a video you know exists usually means it's **private** or the ID belongs to another channel.
The [SDK](/sdk) throws typed errors carrying the status code, so you can handle these cases without touching raw responses.
# API Overview
The Bold API gives you programmatic access to your videos, collections, playlists, viewers, and AI features. It's the same engine behind the hosted portal. Everything the portal can do, your app can do.
## Base URL
```
https://app.boldvideo.io/api/v1
```
All requests and responses are JSON (`Content-Type: application/json`), except AI endpoints which can stream [Server-Sent Events](/api/streaming).
## Authentication
Pass your API key as a Bearer token:
```bash
curl "https://app.boldvideo.io/api/v1/videos" \
-H "Authorization: Bearer YOUR_API_KEY"
```
Create keys under **Settings → Developer** in the [admin panel](https://app.boldvideo.io/settings/developer). Details and key handling in [Authentication](/api/authentication).
## Response envelope
Successful responses wrap the payload in `data`:
```json
{
"data": [
{
"id": "c03a19be-654c-46d9-985d-3094d7485425",
"title": "Building Claude Code with Boris Cherny",
"duration": 5879,
"playback_id": "UEsc00OGc...",
"chapters": [...],
"transcript": {...}
}
]
}
```
List endpoints may include a `meta` object with pagination info. Errors use a consistent shape. See [Errors](/api/errors).
## Endpoint map
| Group | What it covers |
| ------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| [Videos](/api/reference/videos) | List, fetch, and create videos |
| [Collections](/api/reference/collections) | Collections and their videos |
| [Playlists](/api/reference/playlists) | Curated, ordered playlists |
| [Search](/api/reference/search) | Keyword + semantic search over public content |
| [Settings](/api/reference/settings) | Portal configuration: branding, menus, featured playlists |
| [AI Chat](/api/reference/ai-chat) | Library-wide and per-video conversations |
| [AI Search](/api/reference/ai-search) | Search with AI-synthesized summaries |
| [AI Recommendations](/api/reference/ai-recommendations) | Topic-based video recommendations |
| [Viewers](/api/reference/viewers) | Your members: profiles, lookup, memory |
| [Progress](/api/reference/progress) | Per-viewer, per-video watch progress |
| [Community](/api/reference/community) | Posts, comments, reactions |
| [Auth Sessions](/api/reference/auth-sessions) & [Session Management](/api/reference/session-management) | Device sessions and password-sharing prevention |
Only public videos are returned by content endpoints. Unlisted videos are accessible by ID but not listed; private videos are admin-only.
## Choose your integration style
| If you're… | Use |
| --------------------------------- | ----------------------------------------------------------------------------- |
| Building in JavaScript/TypeScript | The [SDK](/sdk): typed, with streaming helpers |
| Starting a portal from scratch | The [Next.js starter](/sdk/nextjs-starter) |
| Working in another language | This REST API directly |
| Wiring up AI agents / LLM tools | The [machine-readable docs](/api/machine-readable) and the [MCP server](/mcp) |
# LLM & Machine-Readable Docs
Bold's docs and API are built LLM-first. If you're pointing an AI coding assistant (Claude Code, Cursor, …) at Bold, give it these:
## For this documentation site
| Resource | URL |
| ----------------- | ------------------------------------------------------------ |
| **llms.txt** | [`/llms.txt`](/llms.txt): index of all doc pages |
| **llms-full.txt** | [`/llms-full.txt`](/llms-full.txt): every doc page, one file |
## For the API
| Resource | URL |
| ------------------ | ---------------------------------------------------------------------------------------------------------- |
| **API llms.txt** | [`app.boldvideo.io/llms.txt`](https://app.boldvideo.io/llms.txt): compact endpoint catalog with auth notes |
| **OpenAPI (JSON)** | [`app.boldvideo.io/api/openapi`](https://app.boldvideo.io/api/openapi) |
| **OpenAPI (YAML)** | [`app.boldvideo.io/openapi.yaml`](https://app.boldvideo.io/openapi.yaml) |
| **Swagger UI** | [`app.boldvideo.io/api/docs`](https://app.boldvideo.io/api/docs) |
The OpenAPI spec is the canonical machine-readable contract. This documentation's [endpoint reference](/api/reference/videos) is generated from it.
## MCP
For agents that speak the Model Context Protocol, Bold is building an MCP server that exposes your video library as tools and resources. See [MCP](/mcp) for the current status.
## A prompt that works
```
Read https://app.boldvideo.io/llms.txt and https://docs.boldvideo.com/llms.txt.
Build against the Bold Video API (base: https://app.boldvideo.io/api/v1,
auth: "Authorization: Bearer $BOLD_API_KEY"). Prefer the @boldvideo/bold-js
SDK when working in TypeScript.
```
# Streaming (SSE)
Bold's AI endpoints ([chat](/api/reference/ai-chat), [search](/api/reference/ai-search), [recommendations](/api/reference/ai-recommendations)) stream by default, so viewers see answers appear as they're generated. Responses use standard **Server-Sent Events** (SSE).
## A streamed response, end to end
```bash
curl -N "https://app.boldvideo.io/api/v1/ai/chat" \
-X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "What does Boris say about code review?"}'
```
```
data: {"type":"message_start","status":"processing","conversation_id":"f774aa5b-…"}
data: {"type":"conversation_created","conversation_id":"f774aa5b-…"}
data: {"type":"progress","stage":"planning","message":"Working out the angle on your question…"}
data: {"type":"text_delta","delta":"Boris explains that "}
data: {"type":"text_delta","delta":"Claude Code reviews all pull requests…"}
data: {"type":"message_complete","content":"…full answer…","sources":[…],"citations":[…],"conversation_id":"f774aa5b-…","response_type":"answer"}
```
## Event types
| `type` | Payload | When |
| ---------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `message_start` | `conversation_id`, `status` | Immediately |
| `conversation_created` | `conversation_id` | New conversations only. Store this ID to support follow-up questions |
| `progress` | `stage`, `message` | While Bold plans and retrieves (great for "thinking…" UI states) |
| `text_delta` | `delta` | Repeatedly, as the answer streams; concatenate the deltas |
| `sources` | `sources[]` | When retrieval finds relevant clips |
| `message_complete` | `content`, `sources`, `citations`, `conversation_id`, `response_type` | Once, at the end: the full answer plus citations to video timestamps |
Unknown event types may be added over time, so ignore what you don't recognize.
## Non-streaming mode
Prefer a single JSON response? Pass `"stream": false` in the request body and you'll get the equivalent of `message_complete` as a regular JSON object.
## Continuing a conversation
POST to the conversation URL (or pass the `conversation_id`) to keep context across turns:
```bash
curl -N "https://app.boldvideo.io/api/v1/ai/chat/f774aa5b-…" \
-X POST \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"question": "And how does that compare to human review?"}'
```
Fetch the full history any time with `GET /ai/chat/{conversation_id}`.
Using JavaScript? The [SDK](/sdk/streaming) turns these streams into async iterators, no manual SSE parsing.
# Webhooks
Webhooks are in early access. The signing mechanism below is stable; the event catalog is still being finalized. If you want webhooks for a specific workflow, [contact us](mailto:support@boldvideo.com) and we'll set you up.
Webhooks let your systems react to events in Bold, most importantly knowing when a video has finished processing so you can publish it, notify members, or kick off your own pipeline.
## Verifying payloads
Every webhook request is signed so you can verify it genuinely came from Bold.
1. Generate your **webhook signing secret** under [**Settings → Developer**](https://app.boldvideo.io/settings/developer)
2. Each delivery includes a signature header computed as an HMAC SHA-256 of the raw request body with your secret
3. Recompute the HMAC on your side and compare (constant-time comparison, please)
```ts
import { createHmac, timingSafeEqual } from 'node:crypto';
function verify(rawBody: string, signatureHeader: string, secret: string) {
const expected = createHmac('sha256', secret).update(rawBody).digest('hex');
return timingSafeEqual(Buffer.from(expected), Buffer.from(signatureHeader));
}
```
Reject anything that doesn't verify.
## Delivery behavior
* Deliveries are `POST` requests with a JSON body
* Respond with a `2xx` quickly (do heavy work async). Non-`2xx` responses are retried
* Handle duplicates idempotently: use the event ID to deduplicate
## Typical events
The catalog is being finalized, but the workhorse is video lifecycle: *video processed / ready*, fired when transcription, chapters, and AI metadata are complete. This is the moment to flip your own publish switch or notify members of new content.
# AI Features
Bold's AI is grounded in your videos. Every answer cites the exact moment in the exact video it came from, so your members can always check the source. This page explains what each AI feature does and how to tune the voice behind them.
## The AI features at a glance
| Feature | What it does | Availability |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------- |
| **Semantic search** | Finds moments by meaning, not keywords: "how do I handle objections" finds the right clip even if nobody said those words | All plans |
| **Per-video chat** | Ask questions about a single video; answers cite timestamps | All plans |
| **Library-wide AI Coach** | Ask anything across your whole library; synthesizes answers from multiple videos, personalized to the member asking | Growth and Enterprise |
| **Recommendations** | Topic-based video recommendations for learning paths | via [API](/api/reference/ai-recommendations) / [SDK](/sdk/ai-methods) |
| **Metadata generation** | Titles, teasers, descriptions, chapters, intelligence reports | All plans |
The library-wide AI Coach (cross-library answers with member personalization) is available on Growth and Enterprise plans, with a monthly answer volume included. Per-video chat and semantic search are on every plan.
## Give your assistant a personality
Under **Settings → Channel Settings → AI Assistant** you set the basics: the assistant's **name**, **avatar**, and **greeting message**. This is what viewers see in the portal and embeds.
The deeper tuning lives under **Settings → AI Settings**:
### Organization Profile
Describe your organization, audience, and common topics (Markdown supported). This context makes answers relevant to *your* industry: a question about "pricing" means something different to a SaaS coach than to a wedding photographer.
### Personality
Four short fields that shape the voice:
* **Communication style**: e.g. "clear, practical, empathetic"
* **Field of expertise**: so Bold uses the right terminology
* **Language & formality**: regional preferences, formality level
* **Content themes**: the threads running through your content
The rule of thumb Bold suggests: *if you wouldn't say it that way, Bold shouldn't either.*
### Fine-tuning instructions (optional)
For specific preferences: how to interpret ambiguous questions, how to structure answers (length, format, timestamps), and what to focus on when analyzing uploaded images. Most channels never need these. The defaults work well.
## Answer languages
Bold answers in your **Default AI Answer Language** (Settings → Channel Settings), but viewers can simply ask in another language and Bold follows their lead.
## Where viewers meet the AI
* **In your portal**: the AI assistant and AI search (toggle under [Portal → Navigation](/guides/portal))
* **In enhanced embeds**: the chat panel (see [Embedding](/guides/embedding))
* **In your own app**: via the [AI endpoints](/api/reference/ai-chat) or the [SDK](/sdk/ai-methods)
## The AI disclaimer
If you need legal or usage guidance under the chat input ("Answers are AI-generated…"), set it under **Portal → AI → Chat Disclaimer**.
# Collections, Playlists & Tags
Bold gives you three organizational tools. They look similar but serve different jobs:
| Tool | What it is | Use it for |
| --------------- | ---------------------------- | ------------------------------------------------- |
| **Collections** | Groups a video belongs to | Course modules, event archives, content areas |
| **Playlists** | Ordered sequences you curate | Learning paths, featured series, onboarding flows |
| **Tags** | Freeform labels | Cross-cutting themes, filtering, API queries |
A video can be in many collections, many playlists, and carry many tags at once.
## Collections
Create collections from the sidebar of the **Videos** page (click **New Collection**), then add videos either from the collection itself or from a video's edit page (sidebar → **Collections**).
Collections shine as filters: the library sidebar, the portal, the API (`?collection_id=`), and AI features (scope a chat or recommendation to one collection) all understand them.
## Playlists
Playlists live in their own section of the admin panel.
Click **New Playlist**, give it a title, description, and cover image, then add videos. Drag to reorder. The order is what viewers see.
### Featured playlists
Under **Settings → Featured Playlists** you choose which playlists appear prominently in your portal (and in the `featured_playlists` field of the [Settings API](/api/reference/settings)). Click a playlist to feature it, drag to order, hit **Save**.
## Tags
Add tags on the video edit page (sidebar → **Tags**). Tags appear as filters in your library sidebar and can be used to scope API queries and AI features (`tags: ['sales']`).
# Dashboard & Analytics
The **Dashboard** is the first thing you see after logging in: a live view of your library's activity.
## What you'll find
* **Current LIVE**: how many viewers are watching right now
* **Sessions** and **Video Plays**: for the selected time range
* **Top Videos**: your most-played content
* **Currently live**: which videos are being watched at this moment
* **Devices**: what your audience watches on
* **Last Days**: plays over time
Use the range selector (Today, Yesterday, Last 7 / 30 / 90 Days, All Time) to zoom in or out.
## Portal analytics
Dashboard metrics cover playback across portal, embeds, and API-driven players. If you also want page-level web analytics for your portal (referrers, page views), connect Plausible, GA4, or Fathom under [Portal → Analytics](/guides/portal#analytics).
Engagement analytics (member-level viewing insight) is available on Growth and Enterprise plans.
## Tracking from custom frontends
Building headless? Report playback events from your own player with the [SDK's analytics methods](/sdk/analytics) so your dashboard stays accurate.
# Embedding Videos
Any video can be embedded on your website, course platform, or app with an iframe. Bold offers two embed types, and both are configured visually from the admin panel.
## Getting the embed code
Open a video and choose **Options → Configure Embed**.
### Standard Video
A clean, distraction-free player. The generated code is a responsive 16:9 iframe:
```html
```
### Enhanced Learning Experience
The full Bold experience in an iframe: player **plus AI assistant, chapters, and transcript**. When you pick this type, the dialog adds feature toggles:
* **Features**: toggle chat, chapters, and transcript individually
* **Default Tab**: which panel opens first
* **Accent Color**: match your brand
* **Start Time**: begin playback at a specific second
Your choices are encoded as URL parameters:
```html
```
| Parameter | Values | Description |
| ------------ | ------------ | --------------------------------- |
| `chat` | `0`, `1` | Show the AI assistant panel |
| `chapters` | `0`, `1` | Show the chapters panel |
| `transcript` | `0`, `1` | Show the transcript panel |
| `accent` | hex (no `#`) | Accent color for the embedded UI |
| `t` | seconds | Start playback at a specific time |
The enhanced embed uses a taller aspect ratio (the generated wrapper handles it). If you write your own wrapper, give it more vertical room than a plain 16:9 player.
## Quick embed
In a hurry? **Options → Copy Embed Link** copies the standard embed code with your current defaults, no dialog needed.
## Building your own player?
If an iframe is too constraining, go headless: fetch the video via the [API](/api) or [SDK](/sdk/videos) and use the `playback_id` / `stream_url` with any HLS-capable player. The [Next.js starter](/sdk/nextjs-starter) shows a production setup with Mux Player.
# Welcome to Bold
Bold turns your video library into something your members can actually use: every video is transcribed, chaptered, summarized, and made searchable the moment you upload it. Your viewers can ask questions and get answers with citations to the exact moment in the exact video.
Bold is built for course creators, coaching programs, and teams with large video libraries. You bring the videos; Bold handles hosting, streaming, AI enrichment, and delivery through a branded portal, embeds, or your own custom frontend.
## How Bold thinks about your content
A quick mental model before you start:
* **Videos** are the atomic unit. Each video gets a transcript, chapters, a title, a teaser, a description, and an AI intelligence report, all generated automatically and editable by you.
* **Collections** group videos for organization and filtering (think: course modules, event archives).
* **Playlists** are ordered sequences you curate for viewers (think: a learning path).
* **Tags** are lightweight labels for filtering and API queries.
* **The portal** is your branded home for all of it, hosted by Bold or headless via the [API](/api) and [SDK](/sdk).
* **Viewers** are your members. Bold tracks their progress and personalizes AI answers, while your app keeps owning login and billing.
## Start here
## Building something custom?
If you'd rather integrate Bold into your own product, head to the [API reference](/api) or the [JavaScript SDK](/sdk). The [Next.js starter](/sdk/nextjs-starter) gives you a full portal you can deploy in minutes.
# Integrations
Bold meets your content where it already lives. Connect integrations under **Settings → Channel Settings → Integrations**.
## Zoom
Connect your Zoom account and Bold imports your **cloud recordings** automatically: coaching calls, cohort sessions, and office hours land in your library already transcribed and chaptered. Click **Connect to Zoom** and authorize.
## Google Drive
Two ways to use it:
* **One-off imports**: pick videos from Drive in the [upload menu](/guides/uploading-videos)
* **Folder monitoring**: Bold watches a folder and imports new videos as they appear
Click **Connect** and authorize your Google account.
## Microsoft OneDrive / SharePoint & Teams
* **OneDrive / SharePoint**: import videos from the upload menu
* **Microsoft Teams**: connect to import your Teams meeting recordings automatically
## YouTube
Publishing works the other way around too: **Options → Push to YouTube** on any video sends it to a connected YouTube channel, useful when Bold is your source of truth and YouTube is a distribution channel.
## Auth & billing partners
Bold doesn't replace your member system. For gated content it pairs with your existing stack (Outseta, Clerk, or Auth0 for identity; Stripe for payments) through [viewer sessions](/guides/team-viewers#sessions--device-limits) and the [API](/api).
## Something missing?
The [REST API](/api) and [webhooks](/api/webhooks) cover custom pipelines: create videos from URLs, sync viewers, react to processing events. If you're missing a first-class integration, [tell us](mailto:support@boldvideo.com). The roadmap is customer-driven.
# Managing Videos
The **Videos** section is your library; the video edit page is where each video comes together. This guide covers both.
## The video library
The library lists every video with its thumbnail, duration, title, teaser, visibility, and date. From here you can:
* **Search** your library with the search box (or press ⌘K anywhere in the admin panel)
* **Filter** by privacy status, collection, or tag using the sidebar
* **Select multiple videos** with the checkboxes for bulk actions
* **Create collections** directly from the sidebar
## The video edit page
Click any video to open its edit page.
### Details
The **Details** tab holds the core metadata. Every text field has an **AI Actions** menu (the sparkle button) with five options: **Generate**, **Shorten**, **Make Punchier**, **Expand**, and **Simplify**.
| Field | Notes |
| ---------------- | ---------------------------------------------------------- |
| **Title** | Drafted by AI on upload; regenerate any time |
| **Slug** | URL-friendly identifier, used in portal URLs and the API |
| **Teaser** | A one-liner for cards and lists |
| **Description** | Longer copy; supports rich text |
| **Published At** | Set a publish date, useful for backdating imported content |
Each field shows a badge (**AI Generated** or **Manually edited**) so you always know where the text came from. Once you edit a field manually, Bold won't touch it again unless you explicitly regenerate it.
### Video Type
Above the tabs you'll find the **Video Type** selector. The type (Podcast Episode, Training Session, Sales Call, All-Hands, …) tells the AI what to pay attention to when writing titles, teasers, descriptions, chapters, and the intelligence report. Pick the closest match, or [define your own types](/guides/video-intelligence#video-types).
### Chapters
The **Chapters** tab shows AI-generated chapters as editable lines, each with a timestamp and a title. Fix a title, merge sections, or regenerate the whole list with AI Actions. Chapters appear in the player, the portal, and the API.
### Attachments
Attach files to a video: worksheets, slides, templates. Attachments are delivered alongside the video in the portal and exposed via the API.
### Sidebar: everything else
* **Video Details**: ID, created/updated timestamps, duration, detected language
* **Thumbnail**: upload a custom thumbnail or keep the auto-generated one
* **Transcript**: status plus a link to the [transcript editor](/guides/transcripts-chapters)
* **Call to Action**: attach a [CTA](/guides/settings#call-to-actions) or use your account default
* **Tags**: freeform labels for filtering and API queries
* **Collections**: add the video to one or more collections
## Visibility
The dropdown next to **Save** controls who can see the video:
| Visibility | Portal listing | Direct link | API (`/videos`) |
| ------------ | -------------- | ------------ | --------------- |
| **Public** | ✅ Listed | ✅ Works | ✅ Returned |
| **Unlisted** | ❌ Not listed | ✅ Works | ❌ Not returned |
| **Private** | ❌ Not listed | ❌ Admin only | ❌ Not returned |
New uploads start as **Unlisted**.
## The Options menu
* **Preview**: open the video in your portal
* **Copy Video Link**: direct portal URL
* **Download**: the original-quality MP4
* **Replace Video**: swap the file, keep everything else
* **Push to YouTube**: publish this video to a connected YouTube channel
* **Copy Embed Link / Configure Embed**: see [Embedding](/guides/embedding)
* **View Intelligence**: the AI analysis report, see [Video Intelligence](/guides/video-intelligence)
# Your Portal
The portal is what your viewers see: your videos, playlists, search, and AI assistant under your brand. Bold gives you two ways to run it, and you choose under **Settings → Channel Settings → Portal Type**:
* **Bold Hosted Portal**: instant portal at `your-channel.boldvideo.com`. No code required.
* **Custom Frontend (Headless)**: Bold is the engine, your site is the experience. Point Bold at your frontend's base URL and build with the [API](/api), [SDK](/sdk), or the [Next.js starter](/sdk/nextjs-starter).
## Configuring the hosted portal
Everything lives under **Portal** in the main navigation, grouped into collapsible sections. Hit **Save** when you're done. Changes go live immediately.
### Homepage
* **Layout**: whether visitors land on your **Library**, the **AI Assistant** front and center, or **None** (custom)
* **Hero Section**: none, or a custom hero (custom heroes require a component in your own frontend)
* **Videos per page**: pagination size
### Design
* **Logos**: separate light and dark mode logos
* **Colors**: background, text, and accent
* **Fonts**: heading and body fonts
* **Header size, corner radius, video display style**
### Navigation
* Toggle the **header**, the **search bar**, and **AI search**
* Add **menu links** (managed under [Settings → Main Menu](/guides/settings))
### Video Page
* Toggle **transcripts** and **chapters** panels on video pages
### AI
* **Chat disclaimer**: optional text below the AI chat input, for legal or usage guidance
### Access
* **Public**: anyone with the link
* **Password Protected**: one shared password for the portal
For per-member access with device limits and session control, use [viewer sessions](/guides/team-viewers#viewers) with your own auth provider.
### Analytics
Connect **Plausible**, **Google Analytics 4**, or **Fathom** to track portal traffic with your own analytics account.
### Custom Links
Short, branded URLs (`your-portal.com/l/something`) that redirect wherever you point them.
### Advanced
Custom CSS is the escape hatch when the design controls aren't enough.
White-label portals (removing Bold branding) are available on Growth and Enterprise plans.
## Going headless
Switch **Portal Type** to **Custom Frontend** and Bold stops being your viewers' destination and becomes your video backend. The **Frontend Base URL** you configure is used for preview links from the admin panel. From there:
* Fetch content and settings via the [REST API](/api)
* Or use the [JavaScript SDK](/sdk): the portal configuration above (colors, menus, featured playlists) is all available via [`bold.settings()`](/api/reference/settings), so your custom frontend can honor the same settings
* Or start from the [Next.js starter](/sdk/nextjs-starter), which does both out of the box
# Quickstart
This guide takes you from an empty library to a published, AI-enriched video you can share or embed. It takes about ten minutes, most of which is Bold doing the work.
## 1. Upload a video
Go to **Videos** and click **Upload Video**. You can upload a file from your computer, or import directly from Google Drive or OneDrive. (Zoom and Microsoft Teams recordings can be imported automatically. See [Integrations](/guides/integrations).)
## 2. Let Bold process it
As soon as the upload finishes, Bold gets to work. Automatically, without any configuration, your video gets:
* A **transcript** with speaker detection
* **Chapters** with timestamps
* A **title**, **teaser**, and **description**
* **Captions** in your default language
* An **intelligence report**: a structured summary of topics, key points, and participants
Processing time depends on video length; a one-hour video typically takes a few minutes.
## 3. Review and refine
Open the video from your library. Everything Bold generated is editable, and each field has **AI Actions** (Generate, Shorten, Make Punchier, Expand, Simplify) if you want a different take. Fields keep a badge showing whether they're **AI Generated** or **Manually edited**, and Bold never overwrites your manual edits.
Set the right **Video Type** (podcast, training session, sales call, …) before regenerating metadata. It shapes how the AI writes titles, teasers, descriptions, and chapters. See [Video Intelligence](/guides/video-intelligence).
## 4. Set visibility
Videos start as **Unlisted**. Use the visibility dropdown at the top of the edit page to choose:
* **Public**: listed in your portal and returned by the public API
* **Unlisted**: accessible by direct link, but not listed
* **Private**: only visible in the admin panel
## 5. Share it
From the **Options** menu you can copy a direct link, preview the video in your portal, or grab an embed code. The [embed dialog](/guides/embedding) offers a clean standard player or an **Enhanced Learning Experience** with AI chat, chapters, and transcript built in.
## Next steps
# Settings
**Settings** collects everything about your channel that isn't a video. Here's the map:
## Channel Settings
The foundation of your channel:
* **Portal Type**: Bold-hosted portal or custom frontend (headless). See [Your Portal](/guides/portal).
* **Default Video Language**: the language for automatic captions and transcription
* **Default AI Answer Language**: the variant Bold AI answers in (viewers can override by asking in another language)
* **Company Logo**: light and dark mode logos for your player and portal
* **AI Assistant**: name, greeting, and avatar for your assistant (see [AI Features](/guides/ai-features))
* **Transcription Dictionary**: your vocabulary, one term per line (see [Transcripts](/guides/transcripts-chapters#transcription-dictionary))
* **Integrations**: Zoom, Google Drive, Microsoft Teams (see [Integrations](/guides/integrations))
## Main Menu
Build your portal's navigation: add links with a label, URL, optional icon, and an "open in new tab" toggle. Drag to reorder.
## Featured Playlists
Choose and order the playlists highlighted in your portal. See [Collections & Playlists](/guides/collections-playlists#featured-playlists).
## AI Settings
The voice and knowledge of your AI assistant: organization profile, personality, fine-tuning. Covered in [AI Features](/guides/ai-features).
## Video Types
Templates that tell the AI what to extract per kind of video. Covered in [Video Intelligence](/guides/video-intelligence#video-types).
## Call to Actions
Reusable CTA templates shown alongside your videos:
* **Internal name**: for your reference
* **Title & description**: Markdown supported
* **Button text & URL**: where to send viewers
Set a **default CTA** for all videos, then override per video from the video edit page (or opt a video out with "No CTA").
## SEO / Social Settings
Control how your portal appears in search results and social shares:
* **Browser title** and optional **title suffix** (e.g. "– Acme Academy")
* **Meta description**
* **Social image** (1200×630) with live preview
* **Favicon**
* **Search indexing**: discourage search engines from indexing, if your portal shouldn't be found
## Developer
API keys and webhook signing secrets: the entry point for everything under [API](/api) and [SDK](/sdk).
* **API key**: create your key here. It's shown **once**; copy it, download an `.env`, or grab an SDK snippet on the spot.
* **Webhook signing secret**: generate the secret used to verify webhook payloads came from Bold.
## Billing
Your subscription, invoices, and plan management.
# Team & Viewers
Bold separates two kinds of people, and it pays to keep them straight:
* **Team members**: your staff. They log into the admin panel, upload videos, and change settings.
* **Viewers**: your members and customers. They watch content, chat with the AI, and have their progress tracked. They never see the admin panel.
Both live under **Users** in the main navigation.
## Team members
Click **+ Add team member** to invite a colleague by email. The list shows when each member was added and confirmed, and their role.
## Viewers
Viewers are usually created programmatically: your app registers a viewer when a member signs up, using your own user ID as the `external_id`. That link lets Bold:
* **Track progress** per member per video (power course dashboards, "continue watching")
* **Personalize AI answers** using the member's profile and history
* **Enforce device limits** to prevent password sharing
From the admin panel you can search viewers by name, email, or external ID, inspect their profile and devices, or add one manually with **+ Add viewer**.
### Progress tracking
Bold stores per-viewer, per-video progress: current position, completion percentage, completed flag. See the [Viewers SDK guide](/sdk/viewers) or the [Progress API](/api/reference/progress).
### Sessions & device limits
For paid communities, password sharing is real money. Bold can act as a headless session layer: your app authenticates the member (Auth0, Clerk, Outseta, …), then registers a device session with Bold. Bold enforces device limits, flags impossible-travel sign-ins, and lets you (or the member) revoke sessions.
Manage per-viewer limits and see active sessions from the viewer's profile, or automate everything via the [Session Management SDK](/sdk/session-management).
Bold deliberately does **not** own your member accounts or billing. It integrates with your auth (Clerk, Auth0, Outseta, …) and your payments (Stripe, …). Your stack, your data.
# Transcripts & Captions
Every video in Bold is transcribed automatically, with speakers detected and separated. The transcript powers captions, search, AI chat, and chapters, so when the transcript is right, everything downstream gets better.
## The transcript editor
Open a video and click **Edit** next to **Transcript** in the sidebar.
The editor shows the transcript segment by segment, synced to the video player:
* **Edit text inline**: click any segment to correct it
* **Assign speakers**: click a speaker label (Speaker A, B, C…) to name them
* **Play along**: the player follows your position, so you can verify against the audio
Save your changes and captions, search, and AI answers pick them up.
## Transcription dictionary
Your content has vocabulary generic transcription gets wrong: product names, industry jargon, people's names. Add these to the **Transcription Dictionary** under [Settings → Channel Settings](/guides/settings): one word or term per line. Bold uses the dictionary to improve new transcriptions, and won't "correct" the words you've listed.
There's also a per-video **pronunciation dictionary** on the video edit page for terms that only matter for one recording.
## Captions and subtitles
Captions are generated automatically in your **Default Video Language** (configurable in [Channel Settings](/guides/settings)). Viewers can toggle them in the player. Look for the `CC` badge on videos in your library.
## Chapters
Chapters are generated together with the transcript and are editable on the video's **Chapters** tab. See [Managing Videos](/guides/managing-videos#chapters).
Same-voice AI translation (translated audio tracks in the original speaker's voice) is available on Growth and Enterprise plans.
# Uploading Videos
Everything in Bold starts with an upload. There are several ways to get videos in, and they all end the same way: a fully transcribed, chaptered, searchable video.
## Upload from your computer
1. Go to **Videos** and click **Upload Video**
2. Choose **Upload from Computer**
3. Select one or more video files
Bold accepts all common video formats (MP4, MOV, WebM, and more). Uploads run in the background, so you can keep working while they finish.
## Import from cloud storage
The **Upload Video** menu also offers:
* **Import from Google Drive**: browse and pick videos from a connected Google account
* **Import from OneDrive**: same for Microsoft OneDrive / SharePoint
Connect these accounts once under [Settings → Channel Settings](/guides/settings), then import as often as you like. Google Drive can also monitor a folder and import new files automatically, handy for teams that already have a recording workflow.
## Import meeting recordings automatically
Bold connects to **Zoom** and **Microsoft Teams** and imports your cloud recordings as they appear, perfect for coaching calls, office hours, and cohort sessions. See [Integrations](/guides/integrations) for setup.
## What happens after upload
Every uploaded video is processed automatically:
1. **Transcription** with speaker detection, using your default video language (and your [transcription dictionary](/guides/transcripts-chapters#transcription-dictionary) for domain-specific terms)
2. **Chapters** are detected and titled
3. **Title, teaser, and description** are drafted based on the video's [type](/guides/video-intelligence#video-types)
4. **Captions** are generated
5. An **intelligence report** is compiled: topics, key points, participants, and details
6. The content is indexed for **search and AI chat**
New videos start **Unlisted**, so nothing goes live before you've had a look.
## Replacing a video
Need to swap the file but keep the metadata, URL, and analytics? Open the video, then **Options → Replace Video**. Bold re-runs processing on the new file.
## Uploading via API
You can also create videos programmatically from a URL. See the [Videos API reference](/api/reference/videos).
Migrating a large library from Kajabi, Vimeo, YouTube, Circle, or another platform? Bold offers a white-glove migration service: videos, members, and structure. [Get in touch](https://boldvideo.com/migrate).
# Video Intelligence
Beyond titles and chapters, Bold compiles a structured **intelligence report** for every video: what it's about, the key takeaways, who's in it, and the details worth remembering. It's the difference between "a video file" and "knowledge you can query."
## Viewing a report
Open a video and choose **Options → View Intelligence**.
A report typically includes:
* **Main topic / subject**: a paragraph-level summary
* **Key points / takeaways**: the claims and lessons that matter
* **Participants**: who appears, with context
* **Important details**: dates, numbers, technical specifics
* **Related topics**: references, people, and concepts mentioned
You can **Download** the report, **Regenerate** it (for example after fixing the transcript), or **Remove** it.
## Video Types
What the AI extracts depends on the **video type**. A sales call and a training session deserve different treatment, so Bold ships with a set of type templates, each with its own analysis sections:
| Type | Extracts (examples) |
| --------------------------- | --------------------------------------------------------------- |
| **All-Hands** | Key announcements, strategic updates, decisions communicated |
| **Implementation Workshop** | Deliverables, step-by-step process, tools used, common pitfalls |
| **Office Hours** | Questions asked, problems diagnosed, advice given |
| **Podcast Episode** | Guests, themes, notable quotes |
| **General Video** | Topic, key points, participants, important details |
Manage types under **Settings → Video Types**. You can edit the built-in templates or click **New Video Type** to define your own, with exactly the sections you want extracted.
The video type also steers how AI writes the title, teaser, description, and chapters. Setting the right type before generating metadata is the one AI setting that pays off most in Bold.
## Assigning a type
On the video edit page, pick the type from the **Video Type** selector above the tabs. Videos default to **General Video**.
# Bold MCP Server
The Bold MCP server is in development and this page describes the intended design. Names, transport, and setup will be finalized at launch, so treat everything below as subject to change. Want early access? [Get in touch](mailto:support@boldvideo.com).
The Bold MCP server exposes your video library through the [Model Context Protocol](https://modelcontextprotocol.io), so AI tools your members already use (Claude, Cursor, and whatever comes next) can search your library, pull transcripts, and answer questions grounded in your content.
## Why this matters
Your library stops being a destination people have to visit and becomes a knowledge source that follows your members into their tools. A developer can ask Cursor "how did the workshop say to structure this?" and get the answer, cited to the exact clip, without leaving their editor.
## What the server will expose
**Tools**
| Tool | What it does |
| ---------------------------- | ---------------------------------------------------------------------------------------- |
| Search | Semantic search across the library, returning clips with timestamps |
| Ask | Question answering with citations (the same engine as [AI chat](/api/reference/ai-chat)) |
| Get video | Metadata, chapters, and transcript for a specific video |
| List collections / playlists | Browse the library's structure |
**Resources**: video transcripts and intelligence reports, addressable by video.
## Expected setup
Configuration will follow the standard MCP remote-server pattern, authenticated with a Bold API key:
```json
{
"mcpServers": {
"bold": {
"url": "https://mcp.boldvideo.io",
"headers": { "Authorization": "Bearer YOUR_API_KEY" }
}
}
}
```
## Today, without MCP
You can already give AI agents everything they need to build against Bold. See [LLM & machine-readable docs](/api/machine-readable). For end-user Q\&A inside your own product, the [AI endpoints](/api/reference/ai-chat) and [SDK](/sdk/ai-methods) are production-ready now.
# AI Methods
The `ai` namespace is how your app talks to Bold's AI. Every method streams by default (see [Streaming](/sdk/streaming)) and accepts `stream: false` for plain JSON.
## `ai.chat(options)`
Library-wide Q\&A, or scoped to one video by passing `videoId`.
```typescript
// Streaming (default)
const stream = await bold.ai.chat({ prompt: 'How do I price my SaaS?' });
for await (const event of stream) {
if (event.type === 'text_delta') process.stdout.write(event.delta);
if (event.type === 'sources') console.log('Sources:', event.sources);
}
// Non-streaming
const response = await bold.ai.chat({
prompt: 'What are the best closing techniques?',
stream: false
});
console.log(response.content);
```
**Scoped to one video** (uses only that video's transcript as context):
```typescript
const stream = await bold.ai.chat({
videoId: 'video-id',
prompt: 'What is discussed at the 5 minute mark?',
currentTime: 300 // optional playback position
});
```
**Continue a conversation:**
```typescript
const stream = await bold.ai.chat({
prompt: 'Tell me more about that',
conversationId: 'conv-id' // from message_start / message_complete events
});
```
| Option | Type | Default | Description |
| ---------------- | -------------- | ------- | --------------------------------------------------------------- |
| `prompt` | `string` | - | The question (required) |
| `stream` | `boolean` | `true` | SSE stream vs JSON |
| `videoId` | `string` | - | Scope to a single video |
| `currentTime` | `number` | - | Playback position (with `videoId`) |
| `conversationId` | `string` | - | Continue an existing conversation |
| `collectionId` | `string` | - | Restrict context to a collection |
| `tags` | `string[]` | - | Restrict context by tags |
| `images` | `ImageInput[]` | - | Attach images (e.g. homework review): `File`, `Blob`, or base64 |
Library-wide chat (no `videoId`) is the AI Coach, available on Growth and Enterprise plans. Video-scoped chat works on every plan.
## `ai.search(options)`
Semantic search with a short AI-written summary of the results.
```typescript
const stream = await bold.ai.search({ prompt: 'pricing strategies', limit: 10 });
for await (const event of stream) {
if (event.type === 'sources') console.log(`Found ${event.sources.length} clips`);
if (event.type === 'text_delta') process.stdout.write(event.delta);
}
```
| Option | Type | Default | Description |
| ----------------------------------- | -------------------- | ------- | ------------------------------------- |
| `prompt` | `string` | - | Search query (required) |
| `stream` | `boolean` | `true` | SSE stream vs JSON |
| `limit` | `number` | - | Max results |
| `collectionId` / `tags` / `videoId` | - | - | Scope the search |
| `context` | `AIContextMessage[]` | - | Previous turns, for follow-up queries |
## `ai.recommendations(options)`
Topic-based recommendations, ideal for learning paths and "what should I watch next."
```typescript
const stream = await bold.ai.recommendations({
topics: ['contract law', 'ethics', 'client management']
});
for await (const event of stream) {
if (event.type === 'recommendations') {
for (const rec of event.recommendations) {
console.log(rec.topic, rec.videos.map(v => v.title));
}
}
if (event.type === 'text_delta') process.stdout.write(event.delta); // AI guidance
}
```
| Option | Type | Default | Description |
| ----------------------- | -------------------- | ------- | ----------------------------- |
| `topics` | `string[]` | - | Topics to cover (required) |
| `limit` | `number` | `5` | Max videos per topic (max 20) |
| `includeGuidance` | `boolean` | `true` | Narrative learning-path text |
| `collectionId` / `tags` | - | - | Scope the pool |
| `context` | `AIContextMessage[]` | - | Previous turns |
| `stream` | `boolean` | `true` | SSE stream vs JSON |
## `ai.getConversation(id)`
```typescript
const conversation = await bold.ai.getConversation('conv-id');
for (const message of conversation.messages) {
console.log(`${message.role}: ${message.content}`);
}
```
## Multi-turn without conversations
Search and recommendations accept a `context` array instead of a conversation ID:
```typescript
const first = await bold.ai.search({ prompt: 'How do indie designers find clients?', stream: false });
const followUp = await bold.ai.search({
prompt: 'What about cold outreach specifically?',
context: first.context,
stream: false
});
```
## Deprecated aliases
`ai.ask()`, `ai.coach()` → use `ai.chat()`. `ai.recommend()` → use `ai.recommendations()`. The old names still work but will be removed in v2.
# Analytics
If you build a custom frontend, report playback events so your [dashboard](/guides/dashboard) reflects reality.
## `trackEvent(video, event)`
Pass the Bold video object and the raw player event. The SDK extracts what it needs (event type, position):
```typescript
const { data: video } = await bold.videos.get('video-id');
playerEl.addEventListener('play', (e) => bold.trackEvent(video, e));
playerEl.addEventListener('pause', (e) => bold.trackEvent(video, e));
playerEl.addEventListener('timeupdate', (e) => bold.trackEvent(video, e));
playerEl.addEventListener('ended', (e) => bold.trackEvent(video, e));
```
This works with a plain `