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

# Attach meeting transcripts to a project in a bounded batch

> Attach between 1 and 50 owned meetings. Work is processed with bounded
concurrency and results retain request order. Every requested item receives
an independent outcome, so valid items continue when another item is invalid,
unavailable, restricted, over quota, or fails. Repeated meeting IDs and
partial retries are idempotent and return the existing source. Knowledge
extraction is scheduled after the response with separately bounded concurrency.
Requires a Pro, LTD, or ENTERPRISE subscription.




## OpenAPI

````yaml /api-reference/openapi.yaml post /projects/{id}/context-sources/meetings
openapi: 3.1.0
info:
  title: Harmonica API
  version: 1.0.0
  description: >
    REST API for the Harmonica structured deliberation platform.

    Provides access to sessions and their data, including creating, updating,
    and querying sessions, plus response submission for active sessions.
  contact:
    name: Harmonica
    url: https://harmonica.chat
servers:
  - url: https://app.harmonica.chat/api/v1
    description: Production
  - url: http://localhost:3000/api/v1
    description: Local development
security:
  - apiKey: []
paths:
  /projects/{id}/context-sources/meetings:
    post:
      tags:
        - Context Sources
      summary: Attach meeting transcripts to a project in a bounded batch
      description: >
        Attach between 1 and 50 owned meetings. Work is processed with bounded

        concurrency and results retain request order. Every requested item
        receives

        an independent outcome, so valid items continue when another item is
        invalid,

        unavailable, restricted, over quota, or fails. Repeated meeting IDs and

        partial retries are idempotent and return the existing source. Knowledge

        extraction is scheduled after the response with separately bounded
        concurrency.

        Requires a Pro, LTD, or ENTERPRISE subscription.
      operationId: addProjectContextSourceMeetings
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                meetings:
                  type: array
                  minItems: 1
                  maxItems: 50
                  items:
                    $ref: '#/components/schemas/MeetingAttachmentBatchItem'
              required:
                - meetings
      responses:
        '200':
          description: Ordered per-item attachment outcomes
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MeetingAttachmentBatchResponse'
        '400':
          description: >-
            Invalid outer batch request: malformed JSON, empty meetings, or more
            than 50 items
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: Insufficient project permissions or subscription tier
components:
  schemas:
    MeetingAttachmentBatchItem:
      type: object
      properties:
        meeting_id:
          type: string
          format: uuid
        title:
          type: string
          description: >-
            Optional project-source title. Blank values fall back to the meeting
            title.
      required:
        - meeting_id
    MeetingAttachmentBatchResponse:
      type: object
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/MeetingAttachmentBatchResult'
        summary:
          type: object
          properties:
            requested:
              type: integer
              minimum: 1
              maximum: 50
            succeeded:
              type: integer
              minimum: 0
              maximum: 50
            failed:
              type: integer
              minimum: 0
              maximum: 50
            created:
              type: integer
              minimum: 0
              maximum: 50
            existing:
              type: integer
              minimum: 0
              maximum: 50
            processing:
              type: integer
              minimum: 0
              maximum: 50
          required:
            - requested
            - succeeded
            - failed
            - created
            - existing
            - processing
      required:
        - results
        - summary
    MeetingAttachmentBatchResult:
      type: object
      properties:
        index:
          type: integer
          minimum: 0
          description: Zero-based position in the requested meetings array.
        meeting_id:
          type: string
          format: uuid
          nullable: true
        status:
          type: string
          enum:
            - created
            - existing
            - processing
            - meeting_not_found
            - transcript_not_found
            - transcript_not_ready
            - restricted
            - quota_exceeded
            - invalid
            - failed
        source:
          $ref: '#/components/schemas/MeetingAttachmentSource'
        transcript_status:
          type: string
          description: Present when status is transcript_not_ready.
        error:
          type: object
          properties:
            code:
              type: string
            message:
              type: string
          required:
            - code
            - message
      required:
        - index
        - meeting_id
        - status
    Error:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              enum:
                - unauthorized
                - forbidden
                - not_found
                - validation_error
                - rate_limited
                - internal_error
                - unprocessable
            message:
              type: string
          required:
            - code
            - message
      required:
        - error
    MeetingAttachmentSource:
      type: object
      description: >-
        Safe attachment row. Stored source content, file metadata, and MCP
        configuration are omitted.
      properties:
        id:
          type: string
          format: uuid
        workspace_id:
          type: string
          format: uuid
          nullable: true
        source_type:
          type: string
          enum:
            - file
        title:
          type: string
        content_mode:
          type: string
          enum:
            - verbatim
            - chunked
          nullable: true
        source_ref:
          type: string
          nullable: true
        token_estimate:
          type: integer
          nullable: true
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - workspace_id
        - source_type
        - title
        - content_mode
        - source_ref
        - token_estimate
        - created_at
        - updated_at
  responses:
    Unauthorized:
      description: Missing or invalid API key
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error:
              code: unauthorized
              message: Invalid or missing API key
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: |
        API key authentication. Pass your key as a Bearer token.
        Keys use the format `hm_live_<32 hex chars>`.
        Generate keys from your Harmonica dashboard settings.

````