> ## 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.

# Put Recommendation Plan

> PUT /recommendations/{id}/plan {steps, budget_cents} -> the replaced
{steps, budget_cents, owner, proof_window} envelope (Task LB8).

Replaces the whole plan document — never a per-step merge (matches the
m-remplan modal's "save all steps" interaction). 404s on an unknown/
cross-workspace recommendation before touching storage. Audit-logged
(`recommendation.plan_updated`, body-hash convention — same as LB7's
`pattern.comment_added` audit) and broadcasts a real `recommendation.
updated` WS frame via this router's `_emit()` (already the real bus, not
a log-only stub).



## OpenAPI

````yaml /openapi.json put /v1/recommendations/{rec_id}/plan
openapi: 3.1.0
info:
  description: Causeloop Platform Backend
  title: Causeloop API
  version: 1.0.0
servers: []
security: []
paths:
  /v1/recommendations/{rec_id}/plan:
    put:
      tags:
        - recommendations
      summary: Put Recommendation Plan
      description: |-
        PUT /recommendations/{id}/plan {steps, budget_cents} -> the replaced
        {steps, budget_cents, owner, proof_window} envelope (Task LB8).

        Replaces the whole plan document — never a per-step merge (matches the
        m-remplan modal's "save all steps" interaction). 404s on an unknown/
        cross-workspace recommendation before touching storage. Audit-logged
        (`recommendation.plan_updated`, body-hash convention — same as LB7's
        `pattern.comment_added` audit) and broadcasts a real `recommendation.
        updated` WS frame via this router's `_emit()` (already the real bus, not
        a log-only stub).
      operationId: put_recommendation_plan_v1_recommendations__rec_id__plan_put
      parameters:
        - in: path
          name: rec_id
          required: true
          schema:
            title: Rec Id
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RecommendationPlanPutBody'
        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:
    RecommendationPlanPutBody:
      properties:
        budget_cents:
          anyOf:
            - minimum: 0
              type: integer
            - type: 'null'
          title: Budget Cents
        steps:
          items:
            $ref: '#/components/schemas/PlanStepBody'
          maxItems: 200
          title: Steps
          type: array
      title: RecommendationPlanPutBody
      type: object
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          title: Detail
          type: array
      title: HTTPValidationError
      type: object
    PlanStepBody:
      properties:
        eta_date:
          anyOf:
            - type: string
            - type: 'null'
          title: Eta Date
        id:
          maxLength: 100
          minLength: 1
          title: Id
          type: string
        note:
          anyOf:
            - maxLength: 2000
              type: string
            - type: 'null'
          title: Note
        status:
          enum:
            - todo
            - now
            - done
          title: Status
          type: string
        title:
          maxLength: 300
          minLength: 1
          title: Title
          type: string
      required:
        - id
        - title
        - status
      title: PlanStepBody
      type: object
    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

````