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

# Patch Pattern

> PATCH /patterns/{pattern_id}

V2 fix (API-IMPLEMENTATION-SPEC.md §2 disposition table, I4): allowed
fields shrink to {status, assignee, notes} — patterns are engine outputs;
name/fingerprint/cluster_id are no longer client-patchable (they come
from taxonomy config / top-terms / pins, per §6.3/§6.4). Returns the full
updated Pattern.

Task LB6: `owner_user_id` (migration 0069) — the frontend's pinned owner
concept, distinct from the legacy `assignee` field above — is also
accepted here (extends this handler rather than a second PATCH route).
A non-null value MUST be a real member of `auth.workspace_id` (400
`non_member` otherwise); `null` unassigns. The change is audit-logged
(`pattern.owner_changed`, surfaced via GET /patterns/{id}/events like the
pin audit trail) and, like every other field this route touches, broadcast
as a real `pattern.updated` WS frame (app/events.py — see
app/ws/stream.py's canonical event contract).



## OpenAPI

````yaml /openapi.json patch /v1/patterns/{pattern_id}
openapi: 3.1.0
info:
  description: Causeloop Platform Backend
  title: Causeloop API
  version: 1.0.0
servers: []
security: []
paths:
  /v1/patterns/{pattern_id}:
    patch:
      tags:
        - patterns
      summary: Patch Pattern
      description: >-
        PATCH /patterns/{pattern_id}


        V2 fix (API-IMPLEMENTATION-SPEC.md §2 disposition table, I4): allowed

        fields shrink to {status, assignee, notes} — patterns are engine
        outputs;

        name/fingerprint/cluster_id are no longer client-patchable (they come

        from taxonomy config / top-terms / pins, per §6.3/§6.4). Returns the
        full

        updated Pattern.


        Task LB6: `owner_user_id` (migration 0069) — the frontend's pinned owner

        concept, distinct from the legacy `assignee` field above — is also

        accepted here (extends this handler rather than a second PATCH route).

        A non-null value MUST be a real member of `auth.workspace_id` (400

        `non_member` otherwise); `null` unassigns. The change is audit-logged

        (`pattern.owner_changed`, surfaced via GET /patterns/{id}/events like
        the

        pin audit trail) and, like every other field this route touches,
        broadcast

        as a real `pattern.updated` WS frame (app/events.py — see

        app/ws/stream.py's canonical event contract).
      operationId: patch_pattern_v1_patterns__pattern_id__patch
      parameters:
        - in: path
          name: pattern_id
          required: true
          schema:
            title: Pattern Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatternPatch'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema: {}
          description: Successful Response
        '422':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
          description: Validation Error
      security:
        - HTTPBearer: []
components:
  schemas:
    PatternPatch:
      description: >-
        V2 fix (API-IMPLEMENTATION-SPEC.md §2 disposition table, I4): allowed

        fields shrink to {status, assignee, notes} — name/fingerprint/cluster_id

        are engine-owned outputs, not client-patchable. `assignee` maps to the

        `assignee_id` column (migration 0048); `notes` maps to the existing

        `resolution_note` column (storage name kept, API name renamed).


        Task LB6: `owner_user_id` (migration 0069) is a NEW, separately-tracked

        column — the frontend's pinned Pattern.owner_user_id shape — validated
        in

        the router as a real member of the pattern's workspace (400 on a

        non-member); `null` explicitly unassigns. Deliberately not merged with

        the legacy, unvalidated `assignee`/`assignee_id` pair above.
      properties:
        assignee:
          anyOf:
            - type: string
            - type: 'null'
          title: Assignee
        notes:
          anyOf:
            - maxLength: 5000
              type: string
            - type: 'null'
          title: Notes
        owner_user_id:
          anyOf:
            - type: string
            - type: 'null'
          title: Owner User Id
        status:
          anyOf:
            - $ref: '#/components/schemas/PatternStatus'
            - type: 'null'
      title: PatternPatch
      type: object
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          title: Detail
          type: array
      title: HTTPValidationError
      type: object
    PatternStatus:
      enum:
        - emerging
        - active
        - mitigating
        - resolved
      title: PatternStatus
      type: string
    ValidationError:
      properties:
        ctx:
          title: Context
          type: object
        input:
          title: Input
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          title: Location
          type: array
        msg:
          title: Message
          type: string
        type:
          title: Error Type
          type: string
      required:
        - loc
        - msg
        - type
      title: ValidationError
      type: object
  securitySchemes:
    HTTPBearer:
      scheme: bearer
      type: http

````