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

# Complete an action (informational cards' "Got it")



## OpenAPI

````yaml /api-reference/openapi.json post /api/v2/brands/{brand_id}/weekly_actions/{action_id}/complete
openapi: 3.0.1
info:
  title: Cognizo Public API
  version: v1
  description: >-
    Public REST API for Cognizo. Authenticate with an API key via the
    `X-API-KEY` header.
servers:
  - url: https://core.cognizo.ai
security:
  - apiKey: []
paths:
  /api/v2/brands/{brand_id}/weekly_actions/{action_id}/complete:
    parameters:
      - name: brand_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: action_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
    post:
      tags:
        - BrandActions
      summary: Complete an action (informational cards' "Got it")
      operationId: complete_brand_weekly_action
      responses:
        '200':
          description: action completed
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/brand_action'
                required:
                  - data
        '403':
          description: >-
            organization access revoked (ORGANIZATION_ACCESS_REVOKED): the
            access token's organization is no longer one of the user's
            memberships (they left, were removed, or the organization was
            deleted). The session itself is still valid: drop the organization's
            client state and refresh the session, which moves it to another
            organization.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
        '404':
          description: action not found
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/error'
components:
  schemas:
    brand_action:
      type: object
      properties:
        id:
          type: string
          format: uuid
        brand_id:
          type: string
          format: uuid
        action_type:
          type: string
          enum:
            - create_article
            - feed_leads
            - quota_remaining
            - ready_to_review
            - publish_changes
            - request_indexing
            - brief_waiting
            - generating
            - generation_failed
            - new_competitor_spotted
            - stale_published_article
            - watched_page_signal
            - entered_shortlist
            - first_citation
            - gap_widening
            - overtook_you
            - gap_closing
            - overtook_rival
            - gaining_on_rival
            - confirm_guidelines
            - add_audience
            - add_competitors
            - connect_feed
            - connect_gsc
            - monthly_review
            - auto_published
            - fix_audit_issue
            - rerun_audit
          description: >-
            Card type — the FE renders each card from action_type + payload +
            cta alone. `request_indexing` carries the Search Console inspect
            screen in payload.inspect_url — it is an external destination, not a
            deep link, so the card opens it itself rather than through cta.link.
            `generating` is the pipeline task's running phase: it is dealt the
            moment generation starts and the SAME (source) task flips to
            ready_to_review when the draft lands (or generation_failed when
            retries run dry) — clients should treat the brief_id in payload as
            the task's identity across those flips. `fix_audit_issue` names ONE
            high-priority finding of the brand's main-domain Technical audit (at
            most one a week); its source_type is TechnicalAuditFinding and its
            source_id a stable id per domain + check, so dismissing the card
            retires that finding only. `rerun_audit` is a nudge (exempt from the
            weekly cap) when that audit's last finished run is over 30 days old.
        state:
          type: string
          enum:
            - pending
            - completed
            - dismissed
            - snoozed
            - auto_resolved
            - expired
        title:
          type: string
          description: >-
            The card's complete human-readable headline ("Ready to review:
            <brief title>") — render it verbatim. Composed server-side from the
            type label + payload subject; always present (falls back to the type
            label alone).
        type_label:
          type: string
          description: >-
            The card's imperative chip/task label ("Review and publish this
            article") — verbatim.
        subject:
          type: string
          nullable: true
          description: >-
            The headline's subject alone (brief title, prompt text, rival name…)
            — for layouts that show the chip and the subject separately. Null on
            setup nudges, whose title is already a full sentence. Never
            re-derive it from title.
        description:
          type: string
          description: >-
            The card body: what happened, in sentences, composed server-side
            from the payload (rec reason, counts, rival names…). INLINE MARKDOWN
            restricted to exactly two markers: double-asterisk bold (two *
            characters on each side) and single-underscore italics (one _ on
            each side). Never single-asterisk emphasis, headings, links or
            lists; a lone * or _ is a literal character. Always present.
        tone:
          type: string
          enum:
            - positive
            - negative
            - warning
            - info
            - neutral
          description: >-
            The card's emotional register, decided server-side
            (watched_page_signal is direction-dependent). Map tones to your
            palette (positive→success tint, negative→destructive, …); never
            re-derive tone from action_type.
        next_step:
          type: string
          nullable: true
          description: >-
            The pinned "here's what you do" line. Verbatim. ALL card copy is
            server-composed (English, matching the product runtime; composed
            per-request, so a locale can be threaded through later without data
            migration).
        outcome:
          type: string
          nullable: true
          description: >-
            "What you'll get" — the concrete payoff of acting on the card (what
            goes live, what comes back, what unlocks). Inline markdown under the
            same two-marker rule as description. Rendered as its own labeled
            card section.
        impact_score:
          type: integer
          description: 0–100 ordering + weekly-cap score
        source_type:
          type: string
          nullable: true
        source_id:
          type: string
          format: uuid
          nullable: true
        payload:
          $ref: '#/components/schemas/brand_action_payload'
        cta:
          $ref: '#/components/schemas/brand_action_cta'
        week_start:
          type: string
          format: date
        state_changed_at:
          type: string
          format: date-time
          nullable: true
        created_at:
          type: string
          format: date-time
          nullable: true
      required:
        - id
        - brand_id
        - action_type
        - state
        - title
        - type_label
        - description
        - tone
        - outcome
        - impact_score
        - payload
        - cta
        - week_start
    error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: Stable machine-readable reason; see `error_code`.
            message:
              type: string
            details:
              type: array
              items:
                $ref: '#/components/schemas/error_detail'
          required:
            - code
            - message
      required:
        - error
    brand_action_payload:
      type: object
      additionalProperties: true
      properties:
        title:
          type: string
          nullable: true
        reason:
          type: string
          nullable: true
        reason_code:
          type: string
          nullable: true
          description: >-
            Machine-readable trigger behind a create_article card (e.g.
            dropped_from_answers, new_competitor_content, no_owned_page) — use
            for badges/styling; `reason` stays the human sentence
        rec_type:
          type: string
          nullable: true
        impact:
          type: string
          nullable: true
        format:
          type: string
          nullable: true
        target_word_count:
          type: integer
          nullable: true
        prompt_count:
          type: integer
          nullable: true
          description: >-
            How many tracked searches the piece covers — always
            target_prompts.length
        target_prompts:
          type: array
          nullable: true
          description: >-
            create_article: every tracked search the piece is aimed at, in the
            recommendation's own order. Same shape as a content brief's
            target_prompts. Only searches the brand still tracks are listed, so
            region_id is always present here and the reference can be opened.
          items:
            type: object
            properties:
              prompt_id:
                type: string
                format: uuid
              prompt:
                type: string
              region_id:
                type: string
                format: uuid
                nullable: true
                description: >-
                  The prompt's canonical region for this brand — every prompt
                  read is per-region, so the prompt panel needs it to open
              country_codes:
                type: array
                items:
                  type: string
              volume_range:
                type: string
                enum:
                  - <10
                  - 10-50
                  - 50-150
                  - 150-250
                  - 250-500
                  - 500-1k
                  - 1k-2.5k
                  - 2.5k-5k
                  - 5k-15k
                  - 15k-50k
                  - 50k-150k
                  - 150k-500k
                  - 500k-1m
                  - 1m+
                description: >-
                  Monthly search volume bracket for the prompt's canonical
                  region, the same bucket the prompts page shows. Absent — not
                  null — on cards the weekly build stamped before this field
                  existed; the next build fills it in. Never null when present:
                  a prompt with no stored estimate falls back to the smallest
                  bucket.
            required:
              - prompt_id
              - prompt
              - region_id
              - country_codes
        top_competitor:
          type: object
          nullable: true
          description: 'create_article: the strongest rival on these searches today'
          properties:
            name:
              type: string
              nullable: true
            prompts_dominated:
              type: integer
              nullable: true
        count:
          type: integer
          nullable: true
        remaining:
          type: integer
          nullable: true
        limit:
          type: integer
          nullable: true
        brief_id:
          type: string
          format: uuid
          nullable: true
        article_id:
          type: string
          format: uuid
          nullable: true
        word_count:
          type: integer
          nullable: true
        generated_at:
          type: string
          format: date-time
          nullable: true
        waiting_days:
          type: integer
          nullable: true
          description: >-
            brief_waiting: whole days the brief has sat untouched. The card only
            exists inside a window — at least 3 days (the user may still be
            editing) and under 30 (a brief left a month was abandoned, not
            forgotten, so the deck stops re-dealing it and the backlog stays in
            Content Studio)
        days_behind:
          type: integer
          nullable: true
        prompt_id:
          type: string
          format: uuid
          nullable: true
          description: >-
            A single prompt reference — entered_shortlist's subject, or
            create_article's first target (same as target_prompts[0]). Always
            paired with region_id; never open a prompt from this id alone, since
            the same prompt reads differently per region
        prompt_text:
          type: string
          nullable: true
        region_id:
          type: string
          format: uuid
          nullable: true
          description: >-
            The canonical region of the prompt_id above — the oldest tracked
            variety of that prompt for this brand, the same value target_prompts
            carries. Every prompt read in the product is per-region, so this is
            what makes the reference openable. NULL means the brand no longer
            tracks the prompt in any region: render the reference as plain text
            on purpose, and do not substitute a region of your own (core#402)
        name:
          type: string
          nullable: true
        appearances:
          type: integer
          nullable: true
        total_runs:
          type: integer
          nullable: true
        visibility_percentage:
          type: number
          nullable: true
        rival_name:
          type: string
          nullable: true
        gap:
          type: number
          nullable: true
        gap_delta:
          type: number
          nullable: true
        share:
          type: number
          nullable: true
        new_cited_pages:
          type: integer
          nullable: true
        answers_entered:
          type: integer
          nullable: true
        prompts_taken:
          type: array
          items:
            type: string
          nullable: true
        drafts_ready:
          type: integer
          nullable: true
        bookable_type:
          type: string
          nullable: true
        target:
          type: string
          nullable: true
        direction:
          type: string
          nullable: true
        note:
          type: string
          nullable: true
        published_url:
          type: string
          nullable: true
        inspect_url:
          type: string
          nullable: true
          description: >-
            request_indexing only — Search Console's URL-inspection screen,
            pre-filled with the property and the published page. It is an
            EXTERNAL destination, so it does not ride on cta.link (that
            vocabulary is deep links into this app plus mutations); the card
            opens it itself and the cta stays the complete mutation.
        prev_citations:
          type: integer
          nullable: true
        titles:
          type: array
          items:
            type: string
          nullable: true
          description: >-
            auto_published only — the articles the autopilot put live this week,
            capped at five; `count` carries the true total.
        citations:
          type: integer
          nullable: true
        citations_total:
          type: object
          nullable: true
          properties:
            current:
              type: integer
              nullable: true
            previous:
              type: integer
              nullable: true
        rival_visibility:
          type: number
          nullable: true
        rival_prev_visibility:
          type: number
          nullable: true
        visibility_growth_pct:
          type: number
          nullable: true
        rival_display_name:
          type: string
          nullable: true
        own_visibility:
          type: number
          nullable: true
        own_prev_visibility:
          type: number
          nullable: true
        gap_prev:
          type: number
          nullable: true
          description: >-
            Last week's rival-minus-you gap; negative on an overtook_you card by
            definition
        month:
          type: string
          nullable: true
        period_start:
          type: string
          format: date
          nullable: true
        visibility:
          type: object
          nullable: true
          properties:
            current:
              type: number
              nullable: true
            previous:
              type: number
              nullable: true
        articles_published:
          type: integer
          nullable: true
        best_move:
          type: string
          nullable: true
        domain:
          type: string
          nullable: true
          description: >-
            fix_audit_issue / rerun_audit — the audited site (the brand's main
            domain)
        check_key:
          type: string
          nullable: true
          description: >-
            fix_audit_issue — the Technical audit check the finding belongs to
            (access.ai_bots for the AI crawlers' one row), as the audit's
            top_issues name it
        found:
          type: string
          nullable: true
          description: >-
            fix_audit_issue — the audit's site-wide sentence for what it found.
            Null when the run has no sentence for that check
        pages_to_fix:
          type: integer
          nullable: true
          description: >-
            fix_audit_issue — pages that still carry the problem; null for a
            site-level check (robots.txt, the AI crawlers, the homepage…)
        ran_at:
          type: string
          format: date-time
          nullable: true
          description: >-
            fix_audit_issue / rerun_audit — when the audit run behind the card
            finished
    brand_action_cta:
      oneOf:
        - $ref: '#/components/schemas/brand_action_cta_deep_link'
        - $ref: '#/components/schemas/brand_action_cta_mutation'
      discriminator:
        propertyName: kind
        mapping:
          deep_link: '#/components/schemas/brand_action_cta_deep_link'
          mutation: '#/components/schemas/brand_action_cta_mutation'
    error_detail:
      type: object
      properties:
        field:
          type: string
          nullable: true
        code:
          type: string
        message:
          type: string
      required:
        - code
        - message
        - field
    brand_action_cta_deep_link:
      type: object
      properties:
        kind:
          type: string
          enum:
            - deep_link
        to:
          type: string
          enum:
            - audiences
            - brand_guidelines
            - brief_detail
            - citations
            - competitors
            - connect_search_console
            - content_studio
            - feed_leads
            - feed_settings
            - integrations
            - prompt_detail
            - prompts
            - recommendations
            - reports
            - send_audit_fix
            - technical_audit
            - technical_audit_check
            - watchlist
          description: >-
            Where the card's action happens. Most targets are routes; two are
            surfaces the client opens in place — prompt_detail (the prompt
            panel) and connect_search_console (the Search Console connect
            dialog, so the setup nudge is finished on the card instead of three
            screens away). Params per target: brief_detail → brief_id (+
            optional document: brief|article — which editor tab to open;
            article-facing cards like ready_to_review send article);
            prompt_detail → prompt_id + region_id (the prompt's canonical region
            — the per-region detail route needs both, core#378); reports →
            report_id + period (the monthly_review card, whose report is listed
            on the reports surface); competitors → competitor_id; citations →
            url; technical_audit → domain_id (the audit page on that domain);
            technical_audit_check → domain_id + check_key (the audit page with
            that check opened — check_key access.ai_bots is the AI crawlers' one
            row, opened as the AI assistants panel); send_audit_fix → domain_id
            + check_key + check_keys (comma-separated checks the problem stands
            for) — the client opens the "Send to your dev team" dialog for them
            in place, and finishing it completes the card; others take none.
        params:
          type: object
          additionalProperties:
            type: string
            nullable: true
          description: Target-specific route params (string values)
        secondary:
          $ref: '#/components/schemas/brand_action_cta_secondary'
        snooze:
          allOf:
            - $ref: '#/components/schemas/brand_action_cta_mutation'
          nullable: true
          description: >-
            Always-present snooze affordance (POST
            weekly_actions/{action_id}/snooze — drops the card this week, it
            re-enters next week's set). Explicit on every card so schema-driven
            consumers (the MCP server included) can discover it instead of
            inferring it from the transition endpoints.
      required:
        - kind
        - to
    brand_action_cta_mutation:
      type: object
      properties:
        kind:
          type: string
          enum:
            - mutation
        name:
          type: string
          enum:
            - create_article
            - publish_changes
            - add_competitor
            - generate_article
            - regenerate_article
            - retry_generation
            - run_technical_audit
            - complete
            - dismiss
            - snooze
            - restore
          description: >-
            create_article → POST
            .../content_studio/recommendations/{params.recommendation_id}/create_draft
            (the ROUTE keeps the old name) — the brief chains straight into
            article generation and returns as a ready_to_review card;
            publish_changes → POST
            .../content_studio/articles/{params.article_id}/publish
            (re-publishing a live post refreshes its snapshot); add_competitor →
            POST /brands/{brand_id}/competitors with { name:
            params.competitor_name, domain: params.domain } (domain rides along
            when already known; optional on the endpoint); generate_article →
            POST .../content_studio/briefs/{params.brief_id}/generate_article;
            regenerate_article → POST
            .../content_studio/articles/{params.article_id}/regenerate;
            retry_generation → POST
            .../content_studio/briefs/{params.brief_id}/retry;
            run_technical_audit → POST /brands/{brand_id}/technical_audit {
            domain_id: params.domain_id, action_id: <this card's id> } (starts a
            run on the brand's main domain and completes the card in the same
            transaction — no separate complete call; uses the monthly audit
            quota — 409 AUDIT_RUNNING, 429 AUDIT_QUOTA_EXHAUSTED, the card left
            open on either); complete / dismiss / snooze / restore are the card
            transitions (POST weekly_actions/{action_id}/…) — a snoozed or
            dismissed row's cta is EXACTLY the restore mutation (the undo back
            onto the deck), nothing else. PRODUCTION mutations (create_article,
            generate_article, regenerate_article, retry_generation) start
            background work: their responses return the brief/article, and
            clients can show live progress via GET
            .../content_studio/briefs/{id}/progress (or the progress stream)
            until the result lands back on the feed as a ready_to_review card.
        params:
          type: object
          additionalProperties:
            type: string
            nullable: true
        link:
          allOf:
            - $ref: '#/components/schemas/brand_action_cta_deep_link'
          nullable: true
          description: >-
            Optional destination. NEVER present on the decision deck
            (weekly_actions) — deck cards are single-action (primary + dismiss +
            snooze) and the serializer strips it. It appears on /weekly_tasks
            rows only: live work rows carry the open-the-work link
            (publish_changes, generation_failed), completed info rows carry
            where-it-happened (the prompt, the citations, Content Studio).
        label_hint:
          type: string
          nullable: true
          description: >-
            Optional copy hint (e.g. not_a_competitor on the dismiss of
            new_competitor_spotted)
        secondary:
          $ref: '#/components/schemas/brand_action_cta_secondary'
        snooze:
          allOf:
            - $ref: '#/components/schemas/brand_action_cta_mutation'
          nullable: true
          description: >-
            Always-present snooze affordance (POST
            weekly_actions/{action_id}/snooze — drops the card this week, it
            re-enters next week's set). Explicit on every card so schema-driven
            consumers (the MCP server included) can discover it instead of
            inferring it from the transition endpoints.
      required:
        - kind
        - name
    brand_action_cta_secondary:
      nullable: true
      oneOf:
        - $ref: '#/components/schemas/brand_action_cta_deep_link'
        - $ref: '#/components/schemas/brand_action_cta_mutation'
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: X-API-KEY

````

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