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

# Close a hub Action Item as Done or Cancelled.

> Close a hub Action Item as Done or Cancelled.

    Exactly one target form is accepted:

      * ``producer`` + ``producer_id`` — close the row at that upsert key, or
      * ``akiflow_task_id`` — resolve through task links, then connector
        metadata, then Akiflow-native (Producer ``Akiflow``, Producer ID =
        the task id). Returns ``not_found`` if no hub row matches.

    Idempotent: a second identical close call writes nothing and reports
    ``already_closed``. Closing an item in a different terminal status is a
    real state change and writes.

    Only ``Status`` and ``Status since`` are written. Promotion, Rank,
    Priority, Metrics, and every producer-owned field are left untouched.

    actor:           the calling process — must be in the valid-actor list
                     (see VALID_ACTORS). Rejected before any HTTP call.
    status:          ``Done`` or ``Cancelled``.
    producer:        hub Producer name (e.g. ``Linear``, ``Akiflow``).
    producer_id:     hub Producer ID (e.g. ``SAG-2650``, an Akiflow task uuid).
    akiflow_task_id: Akiflow task uuid. Resolves to a hub row via the order
                     described above.

    Returns a JSON string with one of these shapes:

      * ``{"status": "closed", "page_id": ..., "previous_status": ...,
         "new_status": ...}`` — a row was closed
      * ``{"status": "already_closed", "page_id": ..., "current_status": ...}``
        — the row was already in the requested status; nothing was written
      * ``{"status": "not_found"}`` — no hub row matched the key
      * ``{"status": "ambiguous", "match_count": N}`` — more than one row
        matched; nothing was written
      * ``{"status": "error", "error": "..."}`` — actor/status invalid or
        no target form was provided



## OpenAPI

````yaml /openapi/private/specs/mcp/sagescreen.yml post /tools/close_action_item
openapi: 3.1.0
info:
  title: SageScreen — MCP Tool Catalog
  description: >-
    Agent-callable tools exposed by the SageScreen MCP server at
    `https://mcp.sagescreen.net`.


    These are the same tools served over the Model Context Protocol; this
    reference documents their **REST** surface (`POST /tools/{name}`, body = the
    tool's arguments), which is what the playground below invokes. The live,
    machine-readable catalog is `GET /tools/list`.


    **This page is generated deterministically** from the server's tool registry
    (`apps/docs/scripts/generate_mcp_spec.py`), not hand-written and not
    AI-generated — it cannot drift from the shipped tools.


    All calls authenticate with the `X-Service-Token` header (or `?token=`).
  version: 1.0.0
servers:
  - url: https://mcp.sagescreen.net
    description: Production MCP server
security:
  - serviceToken: []
  - tokenQuery: []
tags:
  - name: Agents
  - name: Contact Push
  - name: Image Generation
  - name: Other
  - name: Productlane
  - name: Reply.io
  - name: Sequences
  - name: Spaces
  - name: WordPress
paths:
  /tools/close_action_item:
    post:
      tags:
        - Other
      summary: Close a hub Action Item as Done or Cancelled.
      description: |-
        Close a hub Action Item as Done or Cancelled.

            Exactly one target form is accepted:

              * ``producer`` + ``producer_id`` — close the row at that upsert key, or
              * ``akiflow_task_id`` — resolve through task links, then connector
                metadata, then Akiflow-native (Producer ``Akiflow``, Producer ID =
                the task id). Returns ``not_found`` if no hub row matches.

            Idempotent: a second identical close call writes nothing and reports
            ``already_closed``. Closing an item in a different terminal status is a
            real state change and writes.

            Only ``Status`` and ``Status since`` are written. Promotion, Rank,
            Priority, Metrics, and every producer-owned field are left untouched.

            actor:           the calling process — must be in the valid-actor list
                             (see VALID_ACTORS). Rejected before any HTTP call.
            status:          ``Done`` or ``Cancelled``.
            producer:        hub Producer name (e.g. ``Linear``, ``Akiflow``).
            producer_id:     hub Producer ID (e.g. ``SAG-2650``, an Akiflow task uuid).
            akiflow_task_id: Akiflow task uuid. Resolves to a hub row via the order
                             described above.

            Returns a JSON string with one of these shapes:

              * ``{"status": "closed", "page_id": ..., "previous_status": ...,
                 "new_status": ...}`` — a row was closed
              * ``{"status": "already_closed", "page_id": ..., "current_status": ...}``
                — the row was already in the requested status; nothing was written
              * ``{"status": "not_found"}`` — no hub row matched the key
              * ``{"status": "ambiguous", "match_count": N}`` — more than one row
                matched; nothing was written
              * ``{"status": "error", "error": "..."}`` — actor/status invalid or
                no target form was provided
      operationId: close_action_item
      requestBody:
        required: true
        content:
          application/json:
            schema:
              properties:
                actor:
                  title: Actor
                  type: string
                status:
                  title: Status
                  type: string
                producer:
                  anyOf:
                    - type: string
                    - type: 'null'
                  default: null
                  title: Producer
                producer_id:
                  anyOf:
                    - type: string
                    - type: 'null'
                  default: null
                  title: Producer Id
                akiflow_task_id:
                  anyOf:
                    - type: string
                    - type: 'null'
                  default: null
                  title: Akiflow Task Id
              required:
                - actor
                - status
              type: object
      responses:
        '200':
          description: >-
            Tool result. The shape is tool-specific; most tools return a JSON
            object, some a `{"result": ...}` envelope.
          content:
            application/json:
              schema:
                type: object
                additionalProperties: true
        '400':
          description: Bad arguments (unknown kwargs, malformed JSON body).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Unknown tool name.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Tool raised an error during execution.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
          description: Human-readable error message.
        detail:
          type: string
          description: Optional additional context.
      required:
        - error
  responses:
    Unauthorized:
      description: Missing or invalid service token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: Unauthorized
  securitySchemes:
    serviceToken:
      type: apiKey
      in: header
      name: X-Service-Token
    tokenQuery:
      type: apiKey
      in: query
      name: token

````