> ## Documentation Index
> Fetch the complete documentation index at: https://docs.brew.new/llms.txt
> Use this file to discover all available pages before exploring further.

# List insights

> The brand’s Brew Insights as the Insights page ranks them, most severe first and then by score, under `{ data, pagination, freshness }`. Each row is one deterministic finding of the insight engine; the engine keeps at most 200 findings in view.

**Use when** reporting what Brew found about the brand’s email: deliverability problems, campaigns that under- or over-performed, timing, audience and automation opportunities.

**Input** `state` (`open`, the default: active findings and snoozes that have ended; or `all`, which adds resolved, cleared, dismissed and stale findings), `severity` to read one severity (up to 200 of its own, however many more severe findings exist), `limit`/`cursor` to page. A `cursor` belongs to the walk that returned it: it continues only the same `state` and `severity`, and only while the findings it already returned are still the rows before it. A finding added, removed or moved further down is served when its page comes, so a walk returns each finding of the list as it stands at its last page exactly once. `include` adds the intelligence layer the page shows beside the findings: `pulse` (the last 7 days against the 7 before), `report` (the latest report the analysis agent published), `suggestions` (its proposed and launched suggestions, up to 25) and `memo` (the agent’s memory across runs).

**Returns** `200`. Each row carries `insightId`, `title`, `description` (the detector’s headline), `severity`, `confidence`, `kind`, `category`, `detectorId`, `state`, `firstSeenAt`, `lastSeenAt`, `recurrenceCount`, an optional `action` and the finding’s `url` in Brew. `freshness` is on every page: `dataAsOf` is how current the data behind the findings is, and `latestAttempt.status: failed` means they may be stale. An expansion that does not exist yet answers `null`. Read-only and free.

**Errors** `400 INVALID_REQUEST` for an unknown query key, value or `include` token, or a malformed `cursor`. Also `400 INVALID_REQUEST` with `param: cursor` when the findings changed since the cursor was issued (one it already returned left the list or moved, or a new finding ranks among them; the engine re-ran, or a finding was snoozed, dismissed or changed state): read again from the first page, without `cursor`. A cursor issued for another `state` or `severity` is refused the same way.

**See also** `getInsight`, `getAnalyticsOverview`.



## OpenAPI

````yaml /api-reference/openapi-public-v1.yaml get /v1/insights
openapi: 3.1.0
info:
  title: Brew Public API v1
  version: 1.0.0
  description: >-
    Brew Public API v1. Generated from the app Zod contracts
    (`lib/<domain>/contracts.ts`): this document is the contract, and every
    operation documents exactly the error codes it can return.


    - Base URL `https://brew.new/api`; every path starts with `/v1`; JSON in and
    out. Request bodies and query strings are strict: an unknown key is `400
    INVALID_REQUEST` and `error.param` names it.

    - Identity is always in the path. `GET /v1/<collection>` lists (`{ data,
    pagination: { limit, cursor, hasMore } }`; page until `cursor` is `null`),
    and `GET /v1/<collection>/{id}` returns the bare resource, the same object a
    write returns. `?include=` expands relations on a detail read only, and is
    `400` on a list. There is no `?<idKey>=` read anywhere.

    - Writes carry identity in the path and return the bare resource: `POST
    /v1/<collection>` creates (`201`, or `202` when work continues
    asynchronously), `PATCH` and `DELETE /v1/<collection>/{id}` update or delete
    (`DELETE` answers `{ <idField>, deleted }` and is idempotent). Lifecycle
    state changes such as publishing ride `PATCH` as attributes. Two writes
    report more than the row and say so in their shape: `POST` and `PATCH
    /v1/contacts` are upserts that answer `{ contact, created | updated, … }`
    because whether a row was created, which fields changed, and which field
    definitions were minted are facts about the write, not about the contact.

    - Non-CRUD operations are explicit action sub-paths, for example `POST
    /v1/automations/{automationId}/test`, `POST /v1/domains/{domainId}/verify`,
    `POST /v1/sends/{sendId}/cancel` and `POST
    /v1/automations/triggers/{triggerEventId}/fire`.

    - Every resource has one root. Sends read and write at `/v1/sends`, fired
    triggers at `/v1/automations/trigger-instances`, and `/v1/analytics/*` holds
    only reports (aggregates over a window). Every endpoint answers in the same
    envelopes, with no exceptions.

    - Field names are camelCase; enum values are lowercase snake_case;
    timestamps are ISO 8601 UTC strings. Identifiers are opaque strings of at
    most 64 characters (`triggerEventId` up to 256); never parse a prefix.

    - Everything that runs shares one status vocabulary: `queued`, `scheduled`,
    `running`, `paused`, `completed`, `partially_completed`, `failed`,
    `canceled`. It covers sends, automation runs, manual audience runs, audience
    builds and inbox placement tests, so one status switch reads them all. A
    step inside a run is `running`, `completed`, `failed` or `skipped`.

    - Every error on every endpoint is `{ error: { code, type, message,
    suggestion, docs, param?, retryAfter?, details? } }`. Branch on `code`: the
    closed list is the `ApiErrorCode` component and every operation documents
    exactly the codes it can return. Non-fatal caveats arrive as `warnings: [{
    code, message, field? }]` on `2xx` bodies.

    - A credential is brand-scoped (the brand is implicit; send nothing) or
    organization-scoped (name the brand with the `X-Brand-Id` header on
    brand-scoped operations, else `400 BRAND_ID_REQUIRED`; there is no default
    brand). Only `POST /v1/api-keys` carries a `brandId` field, and only a
    signed-in organization admin session may call `/v1/api-keys`. A brand
    outside your reach surfaces as `404`, never `403`.

    - Send `Idempotency-Key` (up to 100 characters) on any POST you might
    repeat: the same key and body replays the original response for 24 hours;
    the same key with a different body is `409 IDEMPOTENCY_CONFLICT`. Rate
    limits are per credential and named policy (`X-RateLimit-*` headers; `429`
    carries `Retry-After`). Credit-metered operations advertise `402` and carry
    `x-brew-credited: true` in the spec.

    - Discovery without a key: `GET /v1/help` (JSON catalog with scopes, credits
    and rate limits per operation), `GET /v1/llms.txt` (this guide) and `GET
    /v1/health`. The OpenAPI document is served at `/openapi.json`.
  contact:
    name: Brew Support
    url: https://docs.brew.new
    email: support@brew.new
servers:
  - url: https://brew.new/api
    description: Production
  - url: http://localhost:3000/api
    description: Local development
security:
  - bearerAuth: []
  - apiKeyAuth: []
tags:
  - name: Emails
    description: >-
      Email designs and sending. Generate a design with the Brew email agent,
      edit, version, restore — then send it: `POST /v1/sends` delivers a design
      to a target (a saved audience, an inline list, or a single address) via a
      verified domain, and `POST /v1/sends` with `test: true` fires a one-off
      test. Sending is not campaign-specific. Send reads live under Sends
      (`/v1/sends`).
  - name: Sends
    description: >-
      The unit of delivery and analytics. `POST /v1/sends` delivers a design to
      a target; `GET /v1/sends` lists campaign sends (with lifetime stats) or,
      with a join filter, one automation’s per-recipient deliveries; `GET
      /v1/sends/{sendId}` reads one send and its events. Cancel, pause and
      resume are action sub-paths.
  - name: Brands
    description: >-
      Brand lifecycle for ORGANIZATION-scoped credentials: list the brands a
      credential can reach, read one, and create a new one (extraction runs
      asynchronously — poll `GET /v1/brands/{brandId}` until `status:
      completed`). These endpoints act on the organization, so they take no
      `X-Brand-Id`.
  - name: Analytics
    description: >-
      Read-only cross-resource reports: the brand overview, windowed automation
      performance and the unified event feed. Send rows (with lifetime stats)
      live at `/v1/sends`; fired triggers at
      `/v1/automations/trigger-instances`.
  - name: Automations
    description: >-
      Automation graphs — deterministic create from explicit `nodes` +
      `connections`, update, version, publish / unpublish, test. Includes
      trigger event definitions + the fire endpoint (`/v1/automations/triggers`)
      and run history (`/v1/automations/runs`).
  - name: Contacts
    description: Create, search, patch, and delete contacts. Email is the primary key.
  - name: Contact Fields
    description: List, create, and delete custom contact field definitions.
  - name: Audiences
    description: Saved contact filter sets — a recipient target for sends.
  - name: Domains
    description: 'Sending domains: add, read DNS records, verify, configure sender defaults.'
  - name: Templates
    description: Public template gallery (read-only) usable as generation references.
  - name: Brand
    description: The single brand bound to the API key.
  - name: Chats
    description: >-
      List the brand's Brew chats, and read a brand-scoped digest of one —
      referenced emails/automations/triggers + a trimmed transcript — so an
      external agent can resume the conversation.
  - name: Notifications
    description: >-
      The brand's notification feed, as the app's bell shows it. Each row is
      gated by the credential's access to its feature, and a comment mention
      reaches only the person it names.
  - name: Insights
    description: >-
      Brew Insights, read-only: the insight engine’s deterministic findings
      about the brand, ranked as the Insights page shows them, one finding in
      full with its frozen metrics and evidence, and the intelligence layer
      beside them (weekly pulse, latest report, open suggestions, agent memo).
  - name: Integrations
    description: >-
      Brand-scoped catalog of connectable providers plus which ones are already
      connected. Connect itself stays in Settings (`/integrations/{provider}`).
  - name: API Keys
    description: >-
      Mint, list, and revoke API keys through a signed-in Clerk session whose
      active organization role is exactly `org:admin`. API-key and OAuth actors
      receive `403`. `POST` body `brandId` is the new key's binding (the only v1
      body field named `brandId`).
  - name: Meta
    description: >-
      Public discovery surface (no auth): the machine-readable API catalog
      (`/v1/help`).
paths:
  /v1/insights:
    get:
      tags:
        - Insights
      summary: List insights
      description: >-
        The brand’s Brew Insights as the Insights page ranks them, most severe
        first and then by score, under `{ data, pagination, freshness }`. Each
        row is one deterministic finding of the insight engine; the engine keeps
        at most 200 findings in view.


        **Use when** reporting what Brew found about the brand’s email:
        deliverability problems, campaigns that under- or over-performed,
        timing, audience and automation opportunities.


        **Input** `state` (`open`, the default: active findings and snoozes that
        have ended; or `all`, which adds resolved, cleared, dismissed and stale
        findings), `severity` to read one severity (up to 200 of its own,
        however many more severe findings exist), `limit`/`cursor` to page. A
        `cursor` belongs to the walk that returned it: it continues only the
        same `state` and `severity`, and only while the findings it already
        returned are still the rows before it. A finding added, removed or moved
        further down is served when its page comes, so a walk returns each
        finding of the list as it stands at its last page exactly once.
        `include` adds the intelligence layer the page shows beside the
        findings: `pulse` (the last 7 days against the 7 before), `report` (the
        latest report the analysis agent published), `suggestions` (its proposed
        and launched suggestions, up to 25) and `memo` (the agent’s memory
        across runs).


        **Returns** `200`. Each row carries `insightId`, `title`, `description`
        (the detector’s headline), `severity`, `confidence`, `kind`, `category`,
        `detectorId`, `state`, `firstSeenAt`, `lastSeenAt`, `recurrenceCount`,
        an optional `action` and the finding’s `url` in Brew. `freshness` is on
        every page: `dataAsOf` is how current the data behind the findings is,
        and `latestAttempt.status: failed` means they may be stale. An expansion
        that does not exist yet answers `null`. Read-only and free.


        **Errors** `400 INVALID_REQUEST` for an unknown query key, value or
        `include` token, or a malformed `cursor`. Also `400 INVALID_REQUEST`
        with `param: cursor` when the findings changed since the cursor was
        issued (one it already returned left the list or moved, or a new finding
        ranks among them; the engine re-ran, or a finding was snoozed, dismissed
        or changed state): read again from the first page, without `cursor`. A
        cursor issued for another `state` or `severity` is refused the same way.


        **See also** `getInsight`, `getAnalyticsOverview`.
      operationId: listInsights
      parameters:
        - schema:
            type: string
            enum:
              - open
              - all
            description: >-
              `open` (default) lists active findings and snoozes that have
              ended. `all` adds resolved, cleared, dismissed and stale findings
              and snoozes still in effect.
          required: false
          description: >-
            `open` (default) lists active findings and snoozes that have ended.
            `all` adds resolved, cleared, dismissed and stale findings and
            snoozes still in effect.
          name: state
          in: query
        - schema:
            type: string
            enum:
              - critical
              - warning
              - opportunity
              - info
            description: >-
              Only findings of this severity: `critical`, `warning`,
              `opportunity` or `info`, up to 200 of its own.
          required: false
          description: >-
            Only findings of this severity: `critical`, `warning`, `opportunity`
            or `info`, up to 200 of its own.
          name: severity
          in: query
        - schema:
            type: string
            description: >-
              Comma-separated expansions: `pulse` adds the weekly pulse,
              `report` the latest intelligence report, `suggestions` its open
              suggestions (up to 25), `memo` the analysis agent’s memo.
            x-brew-include-tokens:
              - pulse
              - report
              - suggestions
              - memo
          required: false
          description: >-
            Comma-separated expansions: `pulse` adds the weekly pulse, `report`
            the latest intelligence report, `suggestions` its open suggestions
            (up to 25), `memo` the analysis agent’s memo.
          name: include
          in: query
        - schema:
            type: integer
            minimum: 1
            maximum: 100
            description: Page size (1-100). Defaults to 100.
            example: 50
          required: false
          description: Page size (1-100). Defaults to 100.
          name: limit
          in: query
          example: 50
        - schema:
            type: string
            minLength: 1
            maxLength: 512
          required: false
          name: cursor
          in: query
        - name: X-Brand-Id
          in: header
          required: false
          description: >-
            The brand this request acts on. REQUIRED for organization-scoped
            credentials (otherwise `400 BRAND_ID_REQUIRED` — there is no default
            brand); list ids with `GET /v1/brands`. Brand-scoped credentials may
            omit it, and sending a different brand returns `403
            BRAND_SCOPE_MISMATCH`. A brand outside your organization returns
            `404 BRAND_NOT_FOUND`.
          schema:
            type: string
            minLength: 1
            maxLength: 64
          example: kx7b3s7fapqz8mjm12ekz1kxdx87yceg
      responses:
        '200':
          description: >-
            A page of findings, the engine’s freshness and any expansions asked
            for.
          headers:
            x-request-id:
              schema:
                type: string
                description: >-
                  Unique request identifier. Share this with support when
                  debugging a request.
                example: req_8cac13fd94e6420cacdd75a1aa403a28
              required: true
              description: >-
                Unique request identifier. Share this with support when
                debugging a request.
            X-RateLimit-Limit:
              schema:
                type: integer
                description: Requests allowed in the current rolling rate limit window.
                example: 100
              required: true
              description: Requests allowed in the current rolling rate limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
                description: Requests remaining in the current rolling rate limit window.
                example: 99
              required: true
              description: Requests remaining in the current rolling rate limit window.
            X-RateLimit-Reset:
              schema:
                type: integer
                description: >-
                  Unix timestamp in seconds for when the rolling window fully
                  resets.
                example: 1712592360
              required: true
              description: >-
                Unix timestamp in seconds for when the rolling window fully
                resets.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InsightList'
              example:
                data:
                  - insightId: k17a8m2v4w5x6y7z8a9b0c1d2e3f4g5h
                    title: Spring sale
                    description: Spring sale bounced 6.2% of sends, above the 6% line.
                    severity: critical
                    confidence: high
                    kind: insight
                    category: deliverability
                    detectorId: deliv.bounce_rate_breach
                    state: active
                    firstSeenAt: '2026-10-01T12:00:00.000Z'
                    lastSeenAt: '2026-10-02T06:04:12.000Z'
                    recurrenceCount: 1
                    action:
                      kind: navigate
                      label: Open campaign analytics
                      url: https://brew.new/analytics/sends/Vx2mZ8t9QbY3sW1vR0pLd
                    url: https://brew.new/insights/k17a8m2v4w5x6y7z8a9b0c1d2e3f4g5h
                pagination:
                  limit: 100
                  cursor: null
                  hasMore: false
                freshness:
                  dataAsOf: '2026-10-02T06:00:00.000Z'
                  lastSuccessfulRunAt: '2026-10-02T06:04:12.000Z'
                  latestAttempt:
                    status: succeeded
                    at: '2026-10-02T06:04:12.000Z'
                pulse:
                  windowEnd: '2026-10-02T00:00:00.000Z'
                  delivered: 12400
                  priorDelivered: 11900
                  uniqueOpens: 4960
                  priorUniqueOpens: 4400
                  uniqueClicks: 620
                  priorUniqueClicks: 590
                  unsubscribed: 18
                  priorUnsubscribed: 21
                  openRatePct: 40
                  priorOpenRatePct: 37
                  clickRatePct: 5
                  priorClickRatePct: 5
                  openDirection: up
                  clickDirection: steady
                  countsOnly: false
                  measured: true
        '400':
          description: >-
            `BRAND_ID_REQUIRED`: An organization-scoped credential called a
            brand-scoped operation without naming the brand.


            `INVALID_REQUEST`: The body or query failed validation: an unknown
            key, a wrong type, or a missing required field. `param` names the
            offender.
          headers:
            x-request-id:
              schema:
                type: string
                description: >-
                  Unique request identifier. Share this with support when
                  debugging a request.
                example: req_8cac13fd94e6420cacdd75a1aa403a28
              required: true
              description: >-
                Unique request identifier. Share this with support when
                debugging a request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
              examples:
                brandIdRequired:
                  summary: BRAND_ID_REQUIRED
                  value:
                    error:
                      code: BRAND_ID_REQUIRED
                      type: invalid_request
                      message: >-
                        An organization-scoped credential called a brand-scoped
                        operation without naming the brand.
                      suggestion: >-
                        List brands with GET /v1/brands, then name one with the
                        X-Brand-Id header. There is no default brand.
                      docs: https://docs.brew.new/api-reference/api/authentication
                invalidRequest:
                  summary: INVALID_REQUEST
                  value:
                    error:
                      code: INVALID_REQUEST
                      type: invalid_request
                      message: >-
                        The body or query failed validation: an unknown key, a
                        wrong type, or a missing required field. `param` names
                        the offender.
                      suggestion: Fix the field reported in `param` and retry.
                      docs: https://docs.brew.new/api-reference/api/errors
        '401':
          description: >-
            `API_KEY_REVOKED`: The API key was revoked.


            `AUTHENTICATION_REQUIRED`: No API key or session accompanied the
            request.


            `INVALID_API_KEY`: The API key is malformed or unknown.
          headers:
            x-request-id:
              schema:
                type: string
                description: >-
                  Unique request identifier. Share this with support when
                  debugging a request.
                example: req_8cac13fd94e6420cacdd75a1aa403a28
              required: true
              description: >-
                Unique request identifier. Share this with support when
                debugging a request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
              examples:
                apiKeyRevoked:
                  summary: API_KEY_REVOKED
                  value:
                    error:
                      code: API_KEY_REVOKED
                      type: authentication_error
                      message: The API key was revoked.
                      suggestion: Create a new active API key and retry.
                      docs: https://docs.brew.new/api-reference/api/authentication
                authenticationRequired:
                  summary: AUTHENTICATION_REQUIRED
                  value:
                    error:
                      code: AUTHENTICATION_REQUIRED
                      type: authentication_error
                      message: No API key or session accompanied the request.
                      suggestion: >-
                        Provide a valid API key or sign in with an organization
                        session.
                      docs: https://docs.brew.new/api-reference/api/authentication
                invalidApiKey:
                  summary: INVALID_API_KEY
                  value:
                    error:
                      code: INVALID_API_KEY
                      type: authentication_error
                      message: The API key is malformed or unknown.
                      suggestion: >-
                        Check the API key format and retry with a valid active
                        key.
                      docs: https://docs.brew.new/api-reference/api/authentication
        '403':
          description: >-
            `ACCOUNT_SUSPENDED`: The organization behind the credential is
            suspended.


            `BRAND_SCOPE_MISMATCH`: A brand-scoped credential named a brand
            other than the one it is bound to.


            `INSUFFICIENT_PERMISSIONS`: The credential lacks the permission
            scope the operation needs.


            `INSUFFICIENT_ROLE`: The caller lacks the access the operation
            needs: `param` names `member` (access to the brand) or `org_admin`
            (the organization role).
          headers:
            x-request-id:
              schema:
                type: string
                description: >-
                  Unique request identifier. Share this with support when
                  debugging a request.
                example: req_8cac13fd94e6420cacdd75a1aa403a28
              required: true
              description: >-
                Unique request identifier. Share this with support when
                debugging a request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
              examples:
                accountSuspended:
                  summary: ACCOUNT_SUSPENDED
                  value:
                    error:
                      code: ACCOUNT_SUSPENDED
                      type: authorization_error
                      message: The organization behind the credential is suspended.
                      suggestion: >-
                        The organization behind this credential is suspended.
                        Contact support@brew.new; do not retry.
                      docs: https://docs.brew.new/api-reference/api/authentication
                brandScopeMismatch:
                  summary: BRAND_SCOPE_MISMATCH
                  value:
                    error:
                      code: BRAND_SCOPE_MISMATCH
                      type: authorization_error
                      message: >-
                        A brand-scoped credential named a brand other than the
                        one it is bound to.
                      suggestion: >-
                        Omit the brand to use the one this credential is bound
                        to, or use an organization-scoped credential to reach
                        other brands.
                      docs: https://docs.brew.new/api-reference/api/authentication
                insufficientPermissions:
                  summary: INSUFFICIENT_PERMISSIONS
                  value:
                    error:
                      code: INSUFFICIENT_PERMISSIONS
                      type: authorization_error
                      message: >-
                        The credential lacks the permission scope the operation
                        needs.
                      suggestion: Use an API key or session with the required permission.
                      docs: https://docs.brew.new/api-reference/api/authentication
                insufficientRole:
                  summary: INSUFFICIENT_ROLE
                  value:
                    error:
                      code: INSUFFICIENT_ROLE
                      type: authorization_error
                      message: >-
                        The caller lacks the access the operation needs: `param`
                        names `member` (access to the brand) or `org_admin` (the
                        organization role).
                      suggestion: >-
                        Ask an organization admin to run this, to add you to the
                        brand, or to make you an admin.
                      docs: https://docs.brew.new/api-reference/api/authentication
        '404':
          description: >-
            `BRAND_NOT_FOUND`: The named or bound brand does not exist in this
            organization (unknown, deleting, or another organization).
          headers:
            x-request-id:
              schema:
                type: string
                description: >-
                  Unique request identifier. Share this with support when
                  debugging a request.
                example: req_8cac13fd94e6420cacdd75a1aa403a28
              required: true
              description: >-
                Unique request identifier. Share this with support when
                debugging a request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
              examples:
                brandNotFound:
                  summary: BRAND_NOT_FOUND
                  value:
                    error:
                      code: BRAND_NOT_FOUND
                      type: not_found
                      message: >-
                        The named or bound brand does not exist in this
                        organization (unknown, deleting, or another
                        organization).
                      suggestion: >-
                        List the brands this credential can reach with GET
                        /v1/brands.
                      docs: https://docs.brew.new/api-reference/api/errors
        '429':
          description: >-
            `RATE_LIMITED`: The credential exhausted the rolling window for this
            route policy; Retry-After says when it reopens.
          headers:
            x-request-id:
              schema:
                type: string
                description: >-
                  Unique request identifier. Share this with support when
                  debugging a request.
                example: req_8cac13fd94e6420cacdd75a1aa403a28
              required: true
              description: >-
                Unique request identifier. Share this with support when
                debugging a request.
            X-RateLimit-Limit:
              schema:
                type: integer
                description: Requests allowed in the current rolling rate limit window.
                example: 100
              required: true
              description: Requests allowed in the current rolling rate limit window.
            X-RateLimit-Remaining:
              schema:
                type: integer
                description: Requests remaining in the current rolling rate limit window.
                example: 99
              required: true
              description: Requests remaining in the current rolling rate limit window.
            X-RateLimit-Reset:
              schema:
                type: integer
                description: >-
                  Unix timestamp in seconds for when the rolling window fully
                  resets.
                example: 1712592360
              required: true
              description: >-
                Unix timestamp in seconds for when the rolling window fully
                resets.
            Retry-After:
              schema:
                type: integer
                description: Seconds to wait before retrying the request.
                example: 42
              required: true
              description: Seconds to wait before retrying the request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
              examples:
                rateLimited:
                  summary: RATE_LIMITED
                  value:
                    error:
                      code: RATE_LIMITED
                      type: rate_limit
                      message: >-
                        The credential exhausted the rolling window for this
                        route policy; Retry-After says when it reopens.
                      suggestion: >-
                        Wait for the retry window before sending another
                        request.
                      docs: https://docs.brew.new/api-reference/api/rate-limits
                      retryAfter: 42
        '500':
          description: >-
            `INTERNAL_ERROR`: An unexpected failure; the x-request-id header
            identifies it.
          headers:
            x-request-id:
              schema:
                type: string
                description: >-
                  Unique request identifier. Share this with support when
                  debugging a request.
                example: req_8cac13fd94e6420cacdd75a1aa403a28
              required: true
              description: >-
                Unique request identifier. Share this with support when
                debugging a request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorEnvelope'
              examples:
                internalError:
                  summary: INTERNAL_ERROR
                  value:
                    error:
                      code: INTERNAL_ERROR
                      type: internal_error
                      message: >-
                        An unexpected failure; the x-request-id header
                        identifies it.
                      suggestion: >-
                        Retry the request. If it keeps failing, contact support
                        with the x-request-id header.
                      docs: https://docs.brew.new/api-reference/api/errors
components:
  schemas:
    InsightList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/InsightListRow'
        pagination:
          type: object
          properties:
            limit:
              type: integer
              minimum: 1
              maximum: 100
            cursor:
              type:
                - string
                - 'null'
            hasMore:
              type: boolean
          required:
            - limit
            - cursor
            - hasMore
          additionalProperties: false
        freshness:
          type: object
          properties:
            dataAsOf:
              type:
                - string
                - 'null'
              format: date-time
              description: >-
                How current the data behind the findings is; null before the
                first successful run.
            lastSuccessfulRunAt:
              type:
                - string
                - 'null'
              format: date-time
            latestAttempt:
              type:
                - object
                - 'null'
              properties:
                status:
                  type: string
                  enum:
                    - succeeded
                    - failed
                    - running
                    - unknown
                at:
                  type: string
                  format: date-time
              required:
                - status
                - at
              additionalProperties: false
              description: >-
                The newest engine run and its outcome; `failed` means the
                findings may be stale.
          required:
            - dataAsOf
            - lastSuccessfulRunAt
            - latestAttempt
          additionalProperties: false
        pulse:
          type:
            - object
            - 'null'
          properties:
            windowEnd:
              type: string
              format: date-time
              description: >-
                Exclusive end of the 7-day window: the start of the newest
                incomplete day.
            delivered:
              type: number
            priorDelivered:
              type: number
            uniqueOpens:
              type: number
            priorUniqueOpens:
              type: number
            uniqueClicks:
              type: number
            priorUniqueClicks:
              type: number
            unsubscribed:
              type: number
            priorUnsubscribed:
              type: number
            openRatePct:
              type:
                - number
                - 'null'
              description: Percent, one decimal; null when counts-only or not measured.
            priorOpenRatePct:
              type:
                - number
                - 'null'
            clickRatePct:
              type:
                - number
                - 'null'
            priorClickRatePct:
              type:
                - number
                - 'null'
            openDirection:
              type: string
              enum:
                - up
                - down
                - steady
              description: '`up` or `down` only when the change is statistically real.'
            clickDirection:
              type: string
              enum:
                - up
                - down
                - steady
            countsOnly:
              type: boolean
              description: Too few deliveries for rates; read the counts.
            measured:
              type: boolean
              description: 'False when engagement tracking is off: opens are unknown.'
          required:
            - windowEnd
            - delivered
            - priorDelivered
            - uniqueOpens
            - priorUniqueOpens
            - uniqueClicks
            - priorUniqueClicks
            - unsubscribed
            - priorUnsubscribed
            - openRatePct
            - priorOpenRatePct
            - clickRatePct
            - priorClickRatePct
            - openDirection
            - clickDirection
            - countsOnly
            - measured
          additionalProperties: false
          description: >-
            With `include` pulse: the weekly pulse, or null before the first
            run.
        report:
          type:
            - object
            - 'null'
          properties:
            reportId:
              type: string
            chatId:
              type: string
              description: The Brew chat whose analysis run wrote the report.
            runTrigger:
              type: string
              enum:
                - manual
                - scheduled
            createdAt:
              type: string
              format: date-time
            insights:
              type: array
              items:
                type: object
                properties:
                  key:
                    type: string
                  kind:
                    type: string
                    enum:
                      - performance
                      - audience
                      - trend
                      - risk
                      - content
                      - setup
                  title:
                    type: string
                  body:
                    type: string
                  impact:
                    type:
                      - string
                      - 'null'
                  suggestionId:
                    type:
                      - string
                      - 'null'
                    description: The suggestion this insight proposes, if any.
                required:
                  - key
                  - kind
                  - title
                  - body
                  - impact
                  - suggestionId
                additionalProperties: false
          required:
            - reportId
            - chatId
            - runTrigger
            - createdAt
            - insights
          additionalProperties: false
          description: >-
            With `include` report: the latest intelligence report, or null when
            none was published.
        suggestions:
          type: array
          items:
            type: object
            properties:
              suggestionId:
                type: string
              title:
                type: string
              prompt:
                type: string
                description: Exactly what launching the suggestion asks Brew to do.
              kind:
                type: string
                enum:
                  - audience
                  - campaign
                  - automation
                  - deliverability
                  - schedule
              status:
                type: string
                enum:
                  - proposed
                  - launched
                  - dismissed
                  - concluded
              rationale:
                type:
                  - string
                  - 'null'
              sourceInsightKeys:
                type: array
                items:
                  type: string
                description: The report insight keys that motivated it.
              executionChatId:
                type:
                  - string
                  - 'null'
                description: The chat a launched suggestion runs in.
              createdAt:
                type: string
                format: date-time
              updatedAt:
                type: string
                format: date-time
            required:
              - suggestionId
              - title
              - prompt
              - kind
              - status
              - rationale
              - sourceInsightKeys
              - executionChatId
              - createdAt
              - updatedAt
            additionalProperties: false
          maxItems: 25
          description: >-
            With `include` suggestions: proposed and launched suggestions, most
            recently updated first.
        memo:
          type:
            - object
            - 'null'
          properties:
            markdown:
              type: string
              description: >-
                Learnings, Watchlist, Experiments and History sections; at most
                8192 bytes.
            version:
              type: integer
            updatedAt:
              type: string
              format: date-time
            updatedByChatId:
              type:
                - string
                - 'null'
          required:
            - markdown
            - version
            - updatedAt
            - updatedByChatId
          additionalProperties: false
          description: 'With `include` memo: the memo, or null before the first run.'
      required:
        - data
        - pagination
        - freshness
      additionalProperties: false
    ApiErrorEnvelope:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              $ref: '#/components/schemas/ApiErrorCode'
            type:
              type: string
              enum:
                - authentication_error
                - authorization_error
                - invalid_request
                - not_found
                - not_implemented
                - conflict
                - rate_limit
                - payment_required
                - service_unavailable
                - internal_error
            message:
              type: string
              minLength: 1
            param:
              type: string
              minLength: 1
            suggestion:
              type: string
              minLength: 1
            docs:
              type: string
              format: uri
            retryAfter:
              type: integer
              minimum: 0
            details:
              type: object
              additionalProperties: {}
          required:
            - code
            - type
            - message
            - suggestion
            - docs
      required:
        - error
    InsightListRow:
      type: object
      properties:
        insightId:
          type: string
        title:
          type: string
          description: What the finding is about.
        description:
          type: string
          description: >-
            The detector’s deterministic headline; quote it, never restate its
            numbers.
        severity:
          type: string
          enum:
            - critical
            - warning
            - opportunity
            - info
        confidence:
          type: string
          enum:
            - high
            - medium
            - low
        kind:
          type: string
          enum:
            - answer
            - insight
            - strategy
          description: >-
            `answer` reports what happened, `insight` a change that passed its
            statistical test, `strategy` a recommended next step.
        category:
          type: string
        detectorId:
          type: string
        state:
          type: string
          enum:
            - active
            - snoozed
            - cleared
            - dismissed
            - resolved
            - stale
          description: A snooze that has ended reads as `active`.
        firstSeenAt:
          type: string
          format: date-time
        lastSeenAt:
          type: string
          format: date-time
        recurrenceCount:
          type: integer
          minimum: 0
        action:
          oneOf:
            - type: object
              properties:
                kind:
                  type: string
                  enum:
                    - navigate
                label:
                  type: string
                url:
                  type: string
                  description: Absolute link to the page in Brew.
              required:
                - kind
                - label
                - url
              additionalProperties: false
            - type: object
              properties:
                kind:
                  type: string
                  enum:
                    - assistant
                label:
                  type: string
                intent:
                  type: string
                  enum:
                    - review_domain_health
                    - validate_contacts
                    - create_campaign
                    - repeat_campaign
                    - review_recommendation
                prompt:
                  type: string
                  description: The request the Insights page sends to Brew’s assistant.
              required:
                - kind
                - label
                - intent
                - prompt
              additionalProperties: false
        url:
          type: string
          description: The finding’s page in Brew.
      required:
        - insightId
        - title
        - description
        - severity
        - confidence
        - kind
        - category
        - detectorId
        - state
        - firstSeenAt
        - lastSeenAt
        - recurrenceCount
        - url
      additionalProperties: false
    ApiErrorCode:
      type: string
      enum:
        - ACCOUNT_SUSPENDED
        - API_KEY_REVOKED
        - AUDIENCE_BUILD_ACTIVE
        - AUDIENCE_BUILD_ALREADY_ACTIVE
        - AUDIENCE_EDIT_CONFLICT
        - AUDIENCE_MEMBERSHIP_NOT_EXPRESSIBLE
        - AUDIENCE_NOT_FOUND
        - AUDIENCE_RUN_NOT_FOUND
        - AUDIT_NOT_FOUND
        - AUTHENTICATION_REQUIRED
        - AUTOMATION_GRAPH_INVALID
        - AUTOMATION_NOT_FOUND
        - AUTOMATION_NOT_PAUSABLE
        - AUTOMATION_NOT_PUBLISHED
        - AUTOMATION_RUN_NOT_FOUND
        - AUTOMATION_VERSION_CONFLICT
        - AUTOMATION_VERSION_NOT_FOUND
        - BATCH_TOO_LARGE
        - BRAND_DOMAIN_CONFLICT
        - BRAND_ID_REQUIRED
        - BRAND_LIMIT_REACHED
        - BRAND_NOT_FOUND
        - BRAND_NOT_READY
        - BRAND_SCOPE_MISMATCH
        - CHAT_NOT_FOUND
        - COMMENT_NOT_FOUND
        - CONSENT_REQUIRED
        - CONTACT_NOT_FOUND
        - CONTENT_OPERATION_FAILED
        - CONTRACT_LOCKED_BY_PUBLISHED_AUTOMATIONS
        - CORE_FIELD_IMMUTABLE
        - DOMAIN_ALREADY_EXISTS
        - DOMAIN_CLAIMED_ELSEWHERE
        - DOMAIN_NOT_FOUND
        - DOMAIN_NOT_READY
        - DOMAIN_OTHER_BRAND
        - DOMAIN_PROVIDER_ERROR
        - DOMAIN_PURPOSE_NOT_ALLOWED
        - DOMAIN_VERIFICATION_FAILED
        - DOMAIN_VERIFIED_ELSEWHERE
        - EMAIL_GENERATION_FAILED
        - EMAIL_GROUP_NAME_CONFLICT
        - EMAIL_GROUP_NOT_FOUND
        - EMAIL_IMAGES_MISSING
        - EMAIL_IMPORT_FAILED
        - EMAIL_IN_PROGRESS
        - EMAIL_IN_USE_BY_AUTOMATION
        - EMAIL_NOT_FOUND
        - EMAIL_NOT_READY
        - EMAIL_RUN_AMBIGUOUS
        - EMAIL_TEMPLATE_INVALID
        - EMAIL_VERSION_NOT_FOUND
        - EXPORT_PROVIDER_ERROR
        - EXPORT_UNSUPPORTED
        - FIELD_NOT_FOUND
        - FIELD_TYPE_MISMATCH
        - FIGMA_ACCESS_DENIED
        - FIGMA_CONVERSION_FAILED
        - FIGMA_FRAME_NOT_FOUND
        - FIGMA_NOT_CONNECTED
        - FIGMA_UNAVAILABLE
        - FIGMA_URL_INVALID
        - FLOW_NOT_FOUND
        - IDEMPOTENCY_CONFLICT
        - IDEMPOTENCY_IN_PROGRESS
        - INSIGHT_NOT_FOUND
        - INSUFFICIENT_CREDITS
        - INSUFFICIENT_PERMISSIONS
        - INSUFFICIENT_ROLE
        - INTEGRATION_NOT_CONNECTED
        - INTERNAL_ERROR
        - INVALID_API_KEY
        - INVALID_EMAIL
        - INVALID_PAYLOAD
        - INVALID_REQUEST
        - LIQUID_RENDER_ERROR
        - METHOD_NOT_ALLOWED
        - MISSING_EMAIL
        - NO_ELIGIBLE_RECIPIENTS
        - NO_PUBLISHED_AUTOMATION
        - NOT_FOUND
        - NOT_IMPLEMENTED
        - ORG_SCOPE_REQUIRED
        - PAYLOAD_SCHEMA_EMAIL_REQUIRED
        - PAYLOAD_TOO_LARGE
        - PREVIEW_NOT_FOUND
        - PUBLISH_VALIDATION_FAILED
        - RATE_LIMITED
        - RECIPIENT_UNSUBSCRIBED
        - REFERENCE_EMAIL_NOT_FOUND
        - RESUBSCRIBE_NOT_ALLOWED
        - RUN_IN_PROGRESS
        - RUN_NOT_CANCELLABLE
        - RUN_NOT_PAUSABLE
        - RUN_NOT_PAUSED
        - RUN_NOT_RESUMABLE
        - RUN_START_FAILED
        - RUN_STOP_FAILED
        - SEND_NOT_CANCELLABLE
        - SEND_NOT_FOUND
        - SEND_NOT_PAUSABLE
        - SEND_NOT_RESUMABLE
        - SEND_QUOTA_EXCEEDED
        - SERVICE_UNAVAILABLE
        - TEMPLATE_NOT_FOUND
        - TRIGGER_ALREADY_EXISTS
        - TRIGGER_EVENT_NOT_FOUND
        - TRIGGER_HAS_DEPENDENT_AUTOMATIONS
        - TRIGGER_IMMUTABLE
        - TRIGGER_INSTANCE_NOT_FOUND
        - TRIGGER_LIMIT_REACHED
        - UPLOAD_IN_PROGRESS
        - UPLOAD_NOT_FOUND
        - UPLOAD_NOT_RECEIVED
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key
      description: 'Send your Brew API key as `Authorization: Bearer brew_xxx`.'
      x-default: Bearer brew_your_api_key
    apiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key
      description: 'Send your Brew API key as `X-API-Key: brew_xxx`.'
      x-default: brew_your_api_key

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.