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

# Record Canvas Interaction

> Record a Magic Canvas interaction (submit, skip, dismiss, clear, error, or heartbeat) while a conversation is **active**.

The Tavus-hosted embed and `@tavus/cvi-ui` post interactions for you. Call this endpoint directly only if you build your own renderer.

**Authentication:** No API key is required while the conversation is active. Never put your Tavus API key in a browser. Once the conversation ends, every POST is rejected.

**Idempotency:** Retries with the same `(conversation_id, interaction_id)` and identical `tool_call_id`, `component`, `component_version`, `type`, and `value` return `200` without firing a second webhook. `metadata` is excluded from the match.

**Rate limiting:** 120 POSTs per 60-second window per `(client IP, conversation_id)`. Exceeding the limit returns `429` with `{ "error": "Too many requests" }` and a `Retry-After` header (seconds until the window resets). Custom renderers posting `heartbeat` interactions count toward this limit.

See [Canvas interactions](/sections/conversational-video-interface/magic-canvas/api/interactions) for per-component `value` rules, webhook delivery, and the full error catalog.


<Info>
  For AI agents, use `https://docs.tavus.io/openapi.yaml` for the full HTTP API contract.
</Info>

See [Canvas interactions, webhooks, and history](/sections/conversational-video-interface/magic-canvas/api/interactions) for per-component `value` rules, webhook delivery, and the full error catalog.


## OpenAPI

````yaml post /v2/conversations/{conversation_id}/canvas/interactions
openapi: 3.0.3
info:
  title: Tavus Developer API Collection
  version: 1.0.0
  contact: {}
servers:
  - url: https://tavusapi.com
security:
  - apiKey: []
tags:
  - name: Videos
  - name: Faces
  - name: Voices
  - name: Conversations
  - name: Deployments
  - name: PALs
  - name: Tools
  - name: PAL Tools
  - name: Pronunciation Dictionaries
  - name: Replacements
  - name: Transcriptions
  - name: Documents
paths:
  /v2/conversations/{conversation_id}/canvas/interactions:
    parameters:
      - name: conversation_id
        in: path
        required: true
        description: The unique identifier of the conversation.
        schema:
          type: string
          example: c123456
    post:
      tags:
        - Conversations
      summary: Record Canvas Interaction
      description: >
        Record a Magic Canvas interaction (submit, skip, dismiss, clear, error,
        or heartbeat) while a conversation is **active**.


        The Tavus-hosted embed and `@tavus/cvi-ui` post interactions for you.
        Call this endpoint directly only if you build your own renderer.


        **Authentication:** No API key is required while the conversation is
        active. Never put your Tavus API key in a browser. Once the conversation
        ends, every POST is rejected.


        **Idempotency:** Retries with the same `(conversation_id,
        interaction_id)` and identical `tool_call_id`, `component`,
        `component_version`, `type`, and `value` return `200` without firing a
        second webhook. `metadata` is excluded from the match.


        **Rate limiting:** 120 POSTs per 60-second window per `(client IP,
        conversation_id)`. Exceeding the limit returns `429` with `{ "error":
        "Too many requests" }` and a `Retry-After` header (seconds until the
        window resets). Custom renderers posting `heartbeat` interactions count
        toward this limit.


        See [Canvas
        interactions](/sections/conversational-video-interface/magic-canvas/api/interactions)
        for per-component `value` rules, webhook delivery, and the full error
        catalog.
      operationId: recordCanvasInteraction
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/canvasInteractionRequest'
            examples:
              question_submit:
                summary: Question submit
                value:
                  interaction_id: ci_call_8f2d41_submit_5e0b7c2a
                  tool_call_id: call_8f2d41
                  component: canvas.question
                  component_version: v1
                  type: submit
                  value:
                    selected_option_ids:
                      - opt_2
                    skipped: false
                  metadata:
                    client: kiosk-web
      responses:
        '200':
          description: Interaction recorded (or idempotent replay)
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    example: true
        '400':
          description: >-
            Bad Request - invalid payload, unknown conversation, or conversation
            not active
          content:
            application/json:
              schema:
                oneOf:
                  - type: object
                    description: >-
                      Schema validation failure on the public route (field names
                      only).
                    properties:
                      error:
                        type: string
                        example: Invalid canvas interaction payload.
                      fields:
                        type: array
                        items:
                          type: string
                        example:
                          - component
                          - value
                  - type: object
                    description: Business-rule rejection.
                    properties:
                      message:
                        type: string
                        example: >-
                          Canvas interactions can only be recorded for active
                          conversations.
        '409':
          description: >-
            Conflict - interaction does not match the issued canvas instance, or
            interaction_id reused with a different payload
          content:
            application/json:
              schema:
                type: object
                properties:
                  message:
                    type: string
                    example: >-
                      Interaction does not match the issued canvas instance for
                      this tool_call_id.
        '429':
          description: >-
            Too Many Requests - rate limit exceeded (120 POSTs per 60-second
            window per client IP and conversation)
          headers:
            Retry-After:
              description: Seconds until the current rate-limit window resets.
              schema:
                type: integer
                example: 60
          content:
            application/json:
              schema:
                type: object
                properties:
                  error:
                    type: string
                    example: Too many requests
      security: []
components:
  schemas:
    canvasInteractionRequest:
      type: object
      description: >-
        Body for [Record Canvas
        Interaction](/api-reference/canvas-interactions/record-canvas-interaction).
        `value` validation depends on `component` and `type` - see [Canvas
        interactions](/sections/conversational-video-interface/magic-canvas/api/interactions#value-rules-per-component).
      required:
        - interaction_id
        - tool_call_id
        - component
        - component_version
        - type
        - value
      properties:
        interaction_id:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            Idempotency key. Unique per logical interaction; reuse verbatim on
            retries. Tavus clients use `ci_{tool_call_id}_{type}_{uuid}`.
          example: ci_call_8f2d41_submit_5e0b7c2a
        tool_call_id:
          type: string
          minLength: 1
          maxLength: 128
          description: >-
            The id of the Canvas invocation that showed the card. Ties the
            interaction to a specific card instance.
          example: call_8f2d41
        component:
          type: string
          enum:
            - canvas.question
            - canvas.input
            - canvas.calendar
            - canvas.scheduling_embed
            - canvas.text
            - canvas.image
            - canvas.video
            - canvas.chart
            - canvas.alert
          description: Component id.
          example: canvas.question
        component_version:
          type: string
          description: Component contract version. `v1` for all current components.
          example: v1
        type:
          type: string
          enum:
            - submit
            - skip
            - dismiss
            - clear
            - error
            - heartbeat
          description: >-
            Interaction type. Submit-capable components also allow `submit` and
            `skip`.
          example: submit
        value:
          type: object
          description: >-
            Interaction payload. At most 16 KB serialized. Shape depends on
            `component` and `type`.
          example:
            selected_option_ids:
              - opt_2
            skipped: false
        metadata:
          type: object
          description: >-
            Optional client annotations, at most 4 KB serialized. Not part of
            idempotency matching.
          default: {}
          example:
            client: kiosk-web
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key

````