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

# Per Artifact Note

> POST /courses/{id}/review/note  (S2.1)

Record a reviewer note against a single artifact.
Before recording: runs check_regen_allowed (S2.3 regen-cap pre-check).
  - If the course regen cap is exhausted: returns 429 WITH code='regen_cap_reached'
    BUT the note IS still recorded (design 14.5: cap withholds the regen job,
    not the note). In Wave 1 there is no regen job to withhold anyway; the 429
    surfaces the cap to the caller for UX purposes.
After passing the cap check: calls course_reviews.record_note which upserts
status='note', appends the curated feedback entry, and returns the ledger row.

Edits-flag write for outline/notes (S2.3 / design section 7):
When artifact_type IN ('outline', 'notes'), the ledger row itself
(status='note', iteration counts as edits signal) IS the edits-flag that
Wave 2's narration needs_refine predicate reads. No separate flag file is
written. This replaces the run_dir outline_edited.flag approach for
per-stage courses (punchlist P3-4).

Phase 2 / Wave 1: returns {noted, iteration, regen_cap_reached?}.
NO regen job is enqueued (Wave 2 wires that).



## OpenAPI

````yaml /openapi.yaml post /api/v1/courses/{course_id}/review/note
openapi: 3.1.0
info:
  title: Mahara Platform
  description: >
    AI Sales Training Course Generator, a Coursera-style platform.


    ## Authentication


    Every request must carry your API key as a Bearer token:


    `Authorization: Bearer sk_live_your_key_here`


    ## Getting an API key


    API keys are provisioned by our team. They are not self-service, so there is
    no signup page to apply on. To request access, email **sales@myustadia.com**
    and we will issue a key for your account.
  version: 1.0.0
servers: []
security: []
paths:
  /api/v1/courses/{course_id}/review/note:
    post:
      tags:
        - B2B Courses v2
      summary: Per Artifact Note
      description: >-
        POST /courses/{id}/review/note  (S2.1)


        Record a reviewer note against a single artifact.

        Before recording: runs check_regen_allowed (S2.3 regen-cap pre-check).
          - If the course regen cap is exhausted: returns 429 WITH code='regen_cap_reached'
            BUT the note IS still recorded (design 14.5: cap withholds the regen job,
            not the note). In Wave 1 there is no regen job to withhold anyway; the 429
            surfaces the cap to the caller for UX purposes.
        After passing the cap check: calls course_reviews.record_note which
        upserts

        status='note', appends the curated feedback entry, and returns the
        ledger row.


        Edits-flag write for outline/notes (S2.3 / design section 7):

        When artifact_type IN ('outline', 'notes'), the ledger row itself

        (status='note', iteration counts as edits signal) IS the edits-flag that

        Wave 2's narration needs_refine predicate reads. No separate flag file
        is

        written. This replaces the run_dir outline_edited.flag approach for

        per-stage courses (punchlist P3-4).


        Phase 2 / Wave 1: returns {noted, iteration, regen_cap_reached?}.

        NO regen job is enqueued (Wave 2 wires that).
      operationId: per_artifact_note_api_v1_courses__course_id__review_note_post
      parameters:
        - name: course_id
          in: path
          required: true
          schema:
            type: string
            title: Course Id
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ReviewNoteRequest'
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema: {}
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
components:
  schemas:
    ReviewNoteRequest:
      properties:
        artifact_type:
          anyOf:
            - type: string
            - type: 'null'
          title: Artifact Type
        module_index:
          anyOf:
            - type: integer
            - type: 'null'
          title: Module Index
        scene_index:
          anyOf:
            - type: integer
            - type: 'null'
          title: Scene Index
        asset_id:
          anyOf:
            - type: integer
            - type: 'null'
          title: Asset Id
        note:
          type: string
          title: Note
      type: object
      required:
        - note
      title: ReviewNoteRequest
      description: Per-artifact note request. note is the reviewer's text.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError

````