---
title: "Search the caller’s bubbles by keyword, returning matching bubble summaries ranked by relevance. Matches fuzzily (prefix/typo-tolerant) against each bubble’s title, its author’s name, and its AI-generated meeting notes/summary — so a keyword that appears only inside the notes still finds the bubble; title matches rank highest, then author, then notes. Requires current Home, visit, or visible-Space discovery in addition to read access — a bubble the caller cannot read is never returned (a notes-only match on an unreadable bubble never surfaces). Each result row includes the bubble’s AI meeting-notes/summary text (summary, capped at 1000 characters; null when there are no notes) so an agent can read why it matched inline. q is required (non-empty, ≤256 chars); an empty or overlong q yields 400 invalid_request. Supports the same team_id/space_id/type/created_after/created_before filters as the list endpoint. Search pagination covers authorized matches within the first 1,000 fuzzy-ranked candidates; has_more and next_cursor refer to that window. Pagination is by opaque cursor (relevance-ordered); rows exclude transcripts and comments (fetch a bubble by id for those)."
method: GET
path: "/v1/bubbles/search"
---

# Search the caller’s bubbles by keyword, returning matching bubble summaries ranked by relevance. Matches fuzzily (prefix/typo-tolerant) against each bubble’s title, its author’s name, and its AI-generated meeting notes/summary — so a keyword that appears only inside the notes still finds the bubble; title matches rank highest, then author, then notes. Requires current Home, visit, or visible-Space discovery in addition to read access — a bubble the caller cannot read is never returned (a notes-only match on an unreadable bubble never surfaces). Each result row includes the bubble’s AI meeting-notes/summary text (summary, capped at 1000 characters; null when there are no notes) so an agent can read why it matched inline. q is required (non-empty, ≤256 chars); an empty or overlong q yields 400 invalid_request. Supports the same team_id/space_id/type/created_after/created_before filters as the list endpoint. Search pagination covers authorized matches within the first 1,000 fuzzy-ranked candidates; has_more and next_cursor refer to that window. Pagination is by opaque cursor (relevance-ordered); rows exclude transcripts and comments (fetch a bubble by id for those).

`GET /v1/bubbles/search`

## Request

- Base URL: `https://api.usebubbles.com`
- URL: `https://api.usebubbles.com/v1/bubbles/search`
- Auth: HTTP bearer

## Query parameters

- `q` string
- `team_id` string
- `space_id` string
- `type` string
- `created_after` string
- `created_before` string
- `limit` string
- `cursor` string

## Response `200`

Success.

- BubbleSearchResults: Search pages cover authorized matches within the first 1000 fuzzy-ranked candidates.
  - `data` BubblesSummary[], required: Authorized matches in this page.
    - `id` string, required: The bubble uuid.
    - `type` 'meeting_recording' | 'screen_recording' | 'custom_image', required: The bubble classification.
    - `title` string, nullable, required: The bubble title, or null.
    - `url` string, required: The app deep link to the bubble.
    - `created_at` string, nullable, required: Creation instant (ISO-8601 UTC), or null.
    - `team_id` string, nullable, required: Owning team id, or null.
    - `channel_id` string, nullable, required: Owning channel id, or null.
    - `author_id` string, nullable, required: Raw creator id (no name — list is unhydrated), or null.
    - `thumbnail_url` string, nullable, required: The thumbnail image URL, or null.
    - `duration_seconds` number, nullable, required: Media duration in seconds, or null.
    - `comment_count` integer, required: Number of comments on the bubble.
    - `expires_at` string, nullable, required: Expiry instant (ISO-8601 UTC), or null.
    - `has_summary` boolean, required: Whether an AI meeting-notes summary exists (see summary).
    - `summary` string, nullable, required: The AI-generated meeting notes/summary text (the same text GET /v1/bubbles/{id} returns as summary), or null when there are no notes. Capped at 1000 characters for row size — a truncated value ends with an ellipsis; fetch the bubble by id for the full text.
  - `has_more` boolean, required: Whether another page exists within the search window.
  - `next_cursor` string, nullable, required: Next page within the window, or null.
  - `search_window_limit` number, required: Maximum ranked candidates examined (1000).

## Other responses

- `400`: A query parameter or request body was malformed (invalid_request).
- `401`: Missing, malformed, or wrong-kind credential (unauthorized / token_revoked / account_deleted).
- `429`: Rate limit exceeded (rate_limited); see the Retry-After header.
- `500`: An unexpected server error occurred (internal_error).

---

[API](https://skmtc.dev/usebubbles/apis/bubbles-public-api.md) - [All operations](https://skmtc.dev/usebubbles/apis/bubbles-public-api/llms.txt) - [OpenAPI document](https://skmtc.dev/usebubbles/apis/bubbles-public-api/revisions/31570f5d4b05?raw)
