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

# Get Marketing Agent state

> <Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Returns the Marketing Agent's plan for an app and the state of its latest run. That covers the setup step it's on, the channels, KPIs, and strategy it proposed, and the competitors it found.

The plan is shared by everyone who edits the app. An app that never used the Marketing Agent returns `status` of `idle` and `setup_stage` of `not_started`, rather than a 404.

Poll this while a run is working. The agent's replies appear in the app's chat, which you read with [Read conversation messages](/api-reference/read-conversation-messages).

This is limited to 120 requests a minute per app for each workspace's personal API keys, so every key in a workspace shares one allowance, across every Marketing Agent endpoint. Some workspaces have a different limit.

<Note>This endpoint accepts a personal API key belonging to a user with editor access to the app and an editor role in its workspace. Read-only keys and workspace API keys are refused.</Note>

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time.</Warning>



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json get /api/apps/{app_id}/cmo/state
openapi: 3.1.0
info:
  title: Base44 App Management API
  version: 1.0.0
servers:
  - url: https://app.base44.com
security:
  - PersonalAccessTokenAuth: []
paths:
  /api/apps/{app_id}/cmo/state:
    get:
      summary: Get Marketing Agent state
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        Returns the Marketing Agent's plan for an app and the state of its
        latest run. That covers the setup step it's on, the channels, KPIs, and
        strategy it proposed, and the competitors it found.


        The plan is shared by everyone who edits the app. An app that never used
        the Marketing Agent returns `status` of `idle` and `setup_stage` of
        `not_started`, rather than a 404.


        Poll this while a run is working. The agent's replies appear in the
        app's chat, which you read with [Read conversation
        messages](/api-reference/read-conversation-messages).


        This is limited to 120 requests a minute per app for each workspace's
        personal API keys, so every key in a workspace shares one allowance,
        across every Marketing Agent endpoint. Some workspaces have a different
        limit.


        <Note>This endpoint accepts a personal API key belonging to a user with
        editor access to the app and an editor role in its workspace. Read-only
        keys and workspace API keys are refused.</Note>


        <Warning>The response includes fields beyond the ones documented here.
        Don't rely on undocumented response fields, as they can change at any
        time.</Warning>
      operationId: get_cmo_state_api_apps__app_id__cmo_state_get
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app.
            title: App Id
          description: ID of the app.
          example: 6820f3a4e7b91d003c45a1f2
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MarketingAgentStateResponse'
        '401':
          description: Missing or invalid credentials.
        '403':
          description: >-
            You don't have editor access to this app or an editor role in its
            workspace, the app is a mobile app, Superagent is turned off for the
            workspace, or you used a read-only or workspace API key.
        '404':
          description: App not found.
        '429':
          description: Rate limit exceeded.
components:
  schemas:
    MarketingAgentStateResponse:
      properties:
        status:
          type: string
          enum:
            - idle
            - provisioning
            - analyzing
            - ready
            - error
          title: Status
          description: >-
            State of the latest run. Either `"idle"` before any run,
            `"provisioning"` while the workspace's Marketing Agent is created,
            `"analyzing"` while a run is working, `"ready"` once it finished, or
            `"error"` if it failed. A run that stops reporting for 15 minutes
            reads as `"error"`.
          example: ready
        run_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Run Id
          description: >-
            ID of the latest run, or `null` if no run has started. Compare it
            between polls to tell a new run from the one you started.
          example: 68a1c9b7f0b3d9001a7e5d04
        last_error:
          anyOf:
            - type: string
            - type: 'null'
          title: Last Error
          description: Why the latest run failed, or `null` if it didn't.
          example: The scan did not complete. Retry the setup.
        setup_stage:
          type: string
          enum:
            - not_started
            - scanning
            - channels
            - kpis
            - budget
            - generating
            - complete
          title: Setup Stage
          description: >-
            How far setup has got. Either `"not_started"`, `"scanning"`,
            `"channels"`, `"kpis"`, `"budget"`, `"generating"`, or `"complete"`.
            At `channels`, `kpis`, and `budget` the agent is waiting for an
            answer.
          example: channels
        reset_epoch:
          type: integer
          title: Reset Epoch
          description: >-
            Number of times the plan was reset. Send it back as `reset_epoch`
            when you answer a setup step.
          example: 0
        channels:
          items:
            $ref: '#/components/schemas/MarketingChannel'
          type: array
          title: Channels
          description: >-
            The marketing channels the agent proposed. Empty until the opening
            scan finishes.
        channels_revision_suggestion:
          anyOf:
            - type: string
            - type: 'null'
          title: Channels Revision Suggestion
          description: >-
            A change to the channels the agent offers to make, or `null` if it
            offers none. Send it as a message to accept it.
          example: Swap LinkedIn for Product Hunt
        kpis:
          items:
            $ref: '#/components/schemas/MarketingKpi'
          type: array
          title: Kpis
          description: The KPIs the agent proposed. Empty until the opening scan finishes.
        kpis_revision_suggestion:
          anyOf:
            - type: string
            - type: 'null'
          title: Kpis Revision Suggestion
          description: >-
            A change to the KPIs the agent offers to make, or `null` if it
            offers none. Send it as a message to accept it.
          example: Track paid conversions instead of signups
        strategy:
          anyOf:
            - $ref: '#/components/schemas/MarketingStrategy'
            - type: 'null'
          description: The marketing strategy, or `null` until setup writes one.
        suggestions:
          items:
            $ref: '#/components/schemas/MarketingSuggestion'
          type: array
          title: Suggestions
          description: Growth ideas the agent generated for the app.
        budget:
          anyOf:
            - $ref: '#/components/schemas/MarketingBudget'
            - type: 'null'
          description: >-
            The marketing budget given during setup, or `null` if none was given
            yet.
        competitor_research_opt_in:
          type: boolean
          title: Competitor Research Opt In
          description: Whether competitor research runs alongside the strategy.
          example: true
        competitor_research_answer:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Competitor Research Answer
          description: >-
            Whether competitor research was accepted (`true`) or declined
            (`false`), or `null` if the question wasn't answered yet.
          example: true
        setup_paused:
          type: boolean
          title: Setup Paused
          description: >-
            Whether setup is paused because the user asked the agent to stop.
            Sending a message resumes it.
          example: false
        competitors:
          items:
            $ref: '#/components/schemas/MarketingCompetitor'
          type: array
          title: Competitors
          description: Competitors found by the research, with verified URLs.
        competitor_scan_status:
          anyOf:
            - type: string
              enum:
                - running
                - done
                - failed
            - type: 'null'
          title: Competitor Scan Status
          description: >-
            State of the competitor research. Either `"running"`, `"done"`, or
            `"failed"`, or `null` if it never ran.
          example: done
        cmo_agent_app_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Cmo Agent App Id
          description: >-
            ID of the workspace's Marketing Agent app your conversation runs on,
            or `null` if you haven't talked to it on this app yet.
          example: 68a1c2e4f0b3d9001a7e5c21
      type: object
      required:
        - status
        - run_id
        - last_error
        - setup_stage
        - reset_epoch
        - channels
        - channels_revision_suggestion
        - kpis
        - kpis_revision_suggestion
        - strategy
        - suggestions
        - budget
        - competitor_research_opt_in
        - competitor_research_answer
        - setup_paused
        - competitors
        - competitor_scan_status
        - cmo_agent_app_id
      title: MarketingAgentStateResponse
      description: The Marketing Agent's plan for an app and the state of its latest run.
    MarketingChannel:
      properties:
        name:
          type: string
          title: Name
          description: Name of the channel.
          example: Reddit communities
        why:
          type: string
          title: Why
          description: Why this channel fits the app.
          example: Freelancers already trade CRM tips in r/freelance.
        tactics:
          items:
            type: string
          type: array
          title: Tactics
          description: Concrete tactics for the channel. Up to 3.
          example:
            - Share a build-in-public thread
            - Answer lead-tracking questions
        priority:
          anyOf:
            - type: integer
            - type: 'null'
          title: Priority
          description: >-
            How much to invest in this channel, from `1` to `5`, where `5` means
            invest here first. Omitted when the agent didn't rank it.
          example: 5
      type: object
      required:
        - name
        - why
        - tactics
      title: MarketingChannel
    MarketingKpi:
      properties:
        name:
          type: string
          title: Name
          description: The KPI in one measurable line.
          example: Weekly signups
        why:
          type: string
          title: Why
          description: Why this KPI matters for the app.
          example: Signups are the first sign the Reddit threads convert.
        baseline:
          anyOf:
            - type: string
            - type: 'null'
          title: Baseline
          description: >-
            Current value, when the agent could tell it from the app. Omitted
            otherwise.
          example: About 10 a week
        target:
          anyOf:
            - type: string
            - type: 'null'
          title: Target
          description: Target at the recommended budget, with a time horizon.
          example: 50 a week in 90 days
        targets:
          anyOf:
            - additionalProperties:
                type: string
              type: object
            - type: 'null'
          title: Targets
          description: >-
            The target at each budget band, keyed by `none`, `low`, `mid`, and
            `high`. A band that's missing means spend at that level can't move
            this KPI.
          example:
            mid: 50 a week in 90 days
            none: 20 a week in 90 days
        target_values:
          anyOf:
            - additionalProperties:
                type: number
              type: object
            - type: 'null'
          title: Target Values
          description: The number inside each band's target, keyed like `targets`.
          example:
            mid: 50
            none: 20
        metric:
          anyOf:
            - $ref: '#/components/schemas/KpiMetric'
            - type: 'null'
          description: >-
            How the KPI is measured against the app's analytics. Omitted on KPIs
            created before measurement was added.
        instrument:
          anyOf:
            - $ref: '#/components/schemas/KpiInstrument'
            - type: 'null'
          description: >-
            How to start recording the KPI's event. Omitted when the app already
            records it.
      type: object
      required:
        - name
        - why
      title: MarketingKpi
    MarketingStrategy:
      properties:
        summary:
          type: string
          title: Summary
          description: The strategy in up to 2 sentences.
          example: >-
            Win early freelancers in the communities they already use, then turn
            them into referrals.
        positioning:
          anyOf:
            - type: string
            - type: 'null'
          title: Positioning
          description: How the app is positioned against its competitors.
          example: The CRM for freelancers who never wanted a CRM.
        channel_plan:
          items:
            $ref: '#/components/schemas/MarketingChannel'
          type: array
          title: Channel Plan
          description: The channels the strategy invests in.
        key_metrics:
          items:
            type: string
          type: array
          title: Key Metrics
          description: The metrics the strategy is judged by.
          example:
            - Weekly signups
            - Week-one retention
        budget_fit:
          anyOf:
            - type: string
            - type: 'null'
          title: Budget Fit
          description: How the strategy fits the workspace's stated budget.
          example: Organic first, with $100 a month for Reddit promoted posts.
      type: object
      required:
        - summary
        - channel_plan
        - key_metrics
      title: MarketingStrategy
    MarketingSuggestion:
      properties:
        id:
          type: string
          title: Id
          description: ID of the suggestion.
          example: 68a1d0c2f0b3d9001a7e5e10
        title:
          type: string
          title: Title
          description: Short title of the growth idea.
          example: Add a referral link to the dashboard
        builder_prompt:
          type: string
          title: Builder Prompt
          description: Prompt to send to the app builder to build the idea.
          example: >-
            Add a Refer a friend card to the dashboard with a copyable invite
            link.
        category:
          anyOf:
            - type: string
            - type: 'null'
          title: Category
          description: Kind of growth idea.
          example: Referral
        rationale:
          anyOf:
            - type: string
            - type: 'null'
          title: Rationale
          description: Why the idea should help.
          example: Freelancers recommend tools to each other.
        impact:
          anyOf:
            - type: string
            - type: 'null'
          title: Impact
          description: Expected impact. Either `"high"`, `"medium"`, or `"low"`.
          example: high
        effort:
          anyOf:
            - type: string
            - type: 'null'
          title: Effort
          description: Rough build effort. Either `"low"`, `"medium"`, or `"high"`.
          example: low
        dismissed:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Dismissed
          description: Whether someone dismissed the suggestion.
          example: false
      type: object
      required:
        - id
        - title
        - builder_prompt
      title: MarketingSuggestion
    MarketingBudget:
      properties:
        description:
          type: string
          title: Description
          description: The budget as it was stated.
          example: $500 a month
        band:
          anyOf:
            - type: string
              enum:
                - none
                - low
                - mid
                - high
            - type: 'null'
          title: Band
          description: >-
            Budget band that selects each KPI's target. Either `"none"`,
            `"low"`, `"mid"`, or `"high"`. Omitted when the budget was stated in
            free text.
          example: mid
      type: object
      required:
        - description
      title: MarketingBudget
    MarketingCompetitor:
      properties:
        name:
          type: string
          title: Name
          description: Name of the competitor.
          example: HubSpot
        url:
          type: string
          title: Url
          description: URL of the competitor's site.
          example: https://www.hubspot.com
        angle:
          type: string
          title: Angle
          description: How the competitor positions itself.
          example: A full CRM suite for sales teams.
        gap:
          type: string
          title: Gap
          description: What the competitor leaves open for this app.
          example: Too heavy for a solo freelancer.
      type: object
      required:
        - name
        - url
        - angle
        - gap
      title: MarketingCompetitor
    KpiMetric:
      properties:
        template:
          type: string
          enum:
            - event_count
            - unique_sessions
            - unique_users
            - retention_dn
          title: Template
          description: >-
            How the KPI is counted. Either `"event_count"`, `"unique_sessions"`,
            `"unique_users"`, or `"retention_dn"`.
          example: event_count
        event_name:
          type: string
          title: Event Name
          description: Analytics event the KPI is measured against.
          example: lead_created
        window_days:
          anyOf:
            - type: integer
            - type: 'null'
          title: Window Days
          description: Number of days the value is counted over. Either `7` or `30`.
          example: 7
        'n':
          anyOf:
            - type: integer
            - type: 'null'
          title: 'N'
          description: Day the return is measured at, for a `retention_dn` KPI only.
          example: 7
      type: object
      required:
        - template
        - event_name
      title: KpiMetric
    KpiInstrument:
      properties:
        builder_prompt:
          type: string
          title: Builder Prompt
          description: >-
            Prompt for the app builder that adds the missing analytics event.
            Present only while the app doesn't record `metric.event_name` yet.
          example: Track a lead_created event when a lead is saved on the Leads page.
        where:
          anyOf:
            - type: string
            - type: 'null'
          title: Where
          description: >-
            Where in the app's code the outcome already happens. Omitted when
            the agent didn't find it.
          example: src/pages/Leads.jsx:42
        requested_at:
          anyOf:
            - type: string
            - type: 'null'
          title: Requested At
          description: >-
            When the build that adds the event was requested, as an ISO 8601
            timestamp, or `null` if it hasn't been.
          example: '2026-08-24T09:20:00+00:00'
      type: object
      required:
        - builder_prompt
      title: KpiInstrument
  securitySchemes:
    PersonalAccessTokenAuth:
      type: http
      scheme: bearer
      description: 'Personal access token, sent as `Authorization: Bearer <token>`.'

````