> This page is for Expression Measurement.

> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://dev.hume.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://dev.hume.ai/_mcp/server.

# Stream images

GET /v1/expression/video/realtime

Stream JPEG frames from a camera or a video and receive, for each frame, the faces detected in it and their expression measurements.

## Sending frames

Send each frame as one binary message containing a complete JPEG. Every frame gets exactly one reply: a `measurement.result`, or an `error`.

- **Configuration:** send `session.update` before your first frame. A `session.update` after your first frame ends the session with `config_invalid`.
- **Rejected frames:** a frame that is empty, is not a JPEG, or is over the pixel limit gets `invalid_image_frame`. A frame over 2MB ends the session with `message_too_large`.
- **Send rate:** send frames as they are captured or played, up to 3 per second. A frame sent faster can get `rate_limited` and is not measured. From a live camera, drop it and send the next frame; from a recording, wait briefly and resend it. To measure a recorded video faster than it plays, send its frames to the video file endpoint.
- **Under load:** replies slow down; a frame within the send rate is never rejected because the server is busy.
- **Failures:** a frame whose measurement fails gets `internal_error`; resend it if you need its result. Five failures in a row end the session.

## Matching results to frames

Replies arrive in the order you sent the frames, so pair them by position.

- Keep a queue of the frames you have sent. Remove the oldest for each `measurement.result`, and for each `error` with code `invalid_image_frame`, `rate_limited` or `internal_error`.
- Other errors do not consume a frame: they answer a JSON message you sent, or end the session.
- Frames sent before `session.close` receive their replies before `session.closed`.
- `frame_id` counts results, not frames. It does not advance for a frame that received an `error`, so do not use it as an index into your own frames.

## Detection and measurement

The server detects the faces in each frame and lists them in `faces`. It measures the largest of them, up to the limit below, and lists those first, largest first.

- A face is skipped, and is not listed, if its detection confidence is below `face.threshold` or its bounding box is under `face.min_size` pixels on its shorter side.
- Each measured face carries its bounding box, its detection confidence, a `face_id`, and two sets of scores: `expressions` for emotional expressions such as amusement or interest, and `descriptions` for visible facial actions such as a smile or a jaw drop.
- The faces that were not measured follow, most confident first, up to 32 faces in all. Each carries its bounding box and detection confidence, with `face_id`, `expressions` and `descriptions` null.
- A frame with no faces is a normal result: a `measurement.result` with an empty `faces` array.
- `face_id` tracks a face across frames in the session. A face normally keeps its ID while it is measured, and can get it back after it leaves the view or is no longer among the largest faces. IDs restart in every session and do not identify a person.

## Limits

| Limit | Value |
|---|---|
| Message size | 2MB |
| Pixels per frame | 8,294,400 (the area of a 3840x2160 image) |
| Send rate | 3 frames per second |
| Faces measured per frame | 2 by default, the largest; contact support to raise it |
| Faces listed per frame | 32 |
| Consecutive measurement failures | 5, after which the session ends |

## Message flow

A session of four frames, the third a PNG sent by mistake. The rejected frame gets no `frame_id`, so the last result is `frame_id` 2. In `session.closed`, `received.frames` counts only the 3 frames accepted for measurement, and `produced.measurements` counts faces, so it is 4.

| Direction | Message |
|---|---|
| receive | `session.created` |
| send | `session.update` (if you change the configuration) |
| receive | `session.updated` (if you sent `session.update`) |
| send | frame |
| receive | `measurement.result` (`frame_id` 0, face 0) |
| send | frame |
| receive | `measurement.result` (`frame_id` 1, faces 0 and 1) |
| send | frame (a PNG, not a JPEG) |
| receive | `error` (`invalid_image_frame`) |
| send | frame |
| receive | `measurement.result` (`frame_id` 2, face 1) |
| send | `session.close` |
| receive | `session.closed` (`received.frames` 3, `produced.measurements` 4) |

Reference: https://dev.hume.ai/expression-measurement/reference/video/stream-images

## AsyncAPI Specification

```yaml
asyncapi: 2.6.0
info:
  title: Stream images
  version: subpackage_video.Stream images
  description: >-
    Stream JPEG frames from a camera or a video and receive, for each frame, the
    faces detected in it and their expression measurements.


    ## Sending frames


    Send each frame as one binary message containing a complete JPEG. Every
    frame gets exactly one reply: a `measurement.result`, or an `error`.


    - **Configuration:** send `session.update` before your first frame. A
    `session.update` after your first frame ends the session with
    `config_invalid`.

    - **Rejected frames:** a frame that is empty, is not a JPEG, or is over the
    pixel limit gets `invalid_image_frame`. A frame over 2MB ends the session
    with `message_too_large`.

    - **Send rate:** send frames as they are captured or played, up to 3 per
    second. A frame sent faster can get `rate_limited` and is not measured. From
    a live camera, drop it and send the next frame; from a recording, wait
    briefly and resend it. To measure a recorded video faster than it plays,
    send its frames to the video file endpoint.

    - **Under load:** replies slow down; a frame within the send rate is never
    rejected because the server is busy.

    - **Failures:** a frame whose measurement fails gets `internal_error`;
    resend it if you need its result. Five failures in a row end the session.


    ## Matching results to frames


    Replies arrive in the order you sent the frames, so pair them by position.


    - Keep a queue of the frames you have sent. Remove the oldest for each
    `measurement.result`, and for each `error` with code `invalid_image_frame`,
    `rate_limited` or `internal_error`.

    - Other errors do not consume a frame: they answer a JSON message you sent,
    or end the session.

    - Frames sent before `session.close` receive their replies before
    `session.closed`.

    - `frame_id` counts results, not frames. It does not advance for a frame
    that received an `error`, so do not use it as an index into your own frames.


    ## Detection and measurement


    The server detects the faces in each frame and lists them in `faces`. It
    measures the largest of them, up to the limit below, and lists those first,
    largest first.


    - A face is skipped, and is not listed, if its detection confidence is below
    `face.threshold` or its bounding box is under `face.min_size` pixels on its
    shorter side.

    - Each measured face carries its bounding box, its detection confidence, a
    `face_id`, and two sets of scores: `expressions` for emotional expressions
    such as amusement or interest, and `descriptions` for visible facial actions
    such as a smile or a jaw drop.

    - The faces that were not measured follow, most confident first, up to 32
    faces in all. Each carries its bounding box and detection confidence, with
    `face_id`, `expressions` and `descriptions` null.

    - A frame with no faces is a normal result: a `measurement.result` with an
    empty `faces` array.

    - `face_id` tracks a face across frames in the session. A face normally
    keeps its ID while it is measured, and can get it back after it leaves the
    view or is no longer among the largest faces. IDs restart in every session
    and do not identify a person.


    ## Limits


    | Limit | Value |

    |---|---|

    | Message size | 2MB |

    | Pixels per frame | 8,294,400 (the area of a 3840x2160 image) |

    | Send rate | 3 frames per second |

    | Faces measured per frame | 2 by default, the largest; contact support to
    raise it |

    | Faces listed per frame | 32 |

    | Consecutive measurement failures | 5, after which the session ends |


    ## Message flow


    A session of four frames, the third a PNG sent by mistake. The rejected
    frame gets no `frame_id`, so the last result is `frame_id` 2. In
    `session.closed`, `received.frames` counts only the 3 frames accepted for
    measurement, and `produced.measurements` counts faces, so it is 4.


    | Direction | Message |

    |---|---|

    | receive | `session.created` |

    | send | `session.update` (if you change the configuration) |

    | receive | `session.updated` (if you sent `session.update`) |

    | send | frame |

    | receive | `measurement.result` (`frame_id` 0, face 0) |

    | send | frame |

    | receive | `measurement.result` (`frame_id` 1, faces 0 and 1) |

    | send | frame (a PNG, not a JPEG) |

    | receive | `error` (`invalid_image_frame`) |

    | send | frame |

    | receive | `measurement.result` (`frame_id` 2, face 1) |

    | send | `session.close` |

    | receive | `session.closed` (`received.frames` 3, `produced.measurements`
    4) |
channels:
  /v1/expression/video/realtime:
    description: >-
      Stream JPEG frames from a camera or a video and receive, for each frame,
      the faces detected in it and their expression measurements.


      ## Sending frames


      Send each frame as one binary message containing a complete JPEG. Every
      frame gets exactly one reply: a `measurement.result`, or an `error`.


      - **Configuration:** send `session.update` before your first frame. A
      `session.update` after your first frame ends the session with
      `config_invalid`.

      - **Rejected frames:** a frame that is empty, is not a JPEG, or is over
      the pixel limit gets `invalid_image_frame`. A frame over 2MB ends the
      session with `message_too_large`.

      - **Send rate:** send frames as they are captured or played, up to 3 per
      second. A frame sent faster can get `rate_limited` and is not measured.
      From a live camera, drop it and send the next frame; from a recording,
      wait briefly and resend it. To measure a recorded video faster than it
      plays, send its frames to the video file endpoint.

      - **Under load:** replies slow down; a frame within the send rate is never
      rejected because the server is busy.

      - **Failures:** a frame whose measurement fails gets `internal_error`;
      resend it if you need its result. Five failures in a row end the session.


      ## Matching results to frames


      Replies arrive in the order you sent the frames, so pair them by position.


      - Keep a queue of the frames you have sent. Remove the oldest for each
      `measurement.result`, and for each `error` with code
      `invalid_image_frame`, `rate_limited` or `internal_error`.

      - Other errors do not consume a frame: they answer a JSON message you
      sent, or end the session.

      - Frames sent before `session.close` receive their replies before
      `session.closed`.

      - `frame_id` counts results, not frames. It does not advance for a frame
      that received an `error`, so do not use it as an index into your own
      frames.


      ## Detection and measurement


      The server detects the faces in each frame and lists them in `faces`. It
      measures the largest of them, up to the limit below, and lists those
      first, largest first.


      - A face is skipped, and is not listed, if its detection confidence is
      below `face.threshold` or its bounding box is under `face.min_size` pixels
      on its shorter side.

      - Each measured face carries its bounding box, its detection confidence, a
      `face_id`, and two sets of scores: `expressions` for emotional expressions
      such as amusement or interest, and `descriptions` for visible facial
      actions such as a smile or a jaw drop.

      - The faces that were not measured follow, most confident first, up to 32
      faces in all. Each carries its bounding box and detection confidence, with
      `face_id`, `expressions` and `descriptions` null.

      - A frame with no faces is a normal result: a `measurement.result` with an
      empty `faces` array.

      - `face_id` tracks a face across frames in the session. A face normally
      keeps its ID while it is measured, and can get it back after it leaves the
      view or is no longer among the largest faces. IDs restart in every session
      and do not identify a person.


      ## Limits


      | Limit | Value |

      |---|---|

      | Message size | 2MB |

      | Pixels per frame | 8,294,400 (the area of a 3840x2160 image) |

      | Send rate | 3 frames per second |

      | Faces measured per frame | 2 by default, the largest; contact support to
      raise it |

      | Faces listed per frame | 32 |

      | Consecutive measurement failures | 5, after which the session ends |


      ## Message flow


      A session of four frames, the third a PNG sent by mistake. The rejected
      frame gets no `frame_id`, so the last result is `frame_id` 2. In
      `session.closed`, `received.frames` counts only the 3 frames accepted for
      measurement, and `produced.measurements` counts faces, so it is 4.


      | Direction | Message |

      |---|---|

      | receive | `session.created` |

      | send | `session.update` (if you change the configuration) |

      | receive | `session.updated` (if you sent `session.update`) |

      | send | frame |

      | receive | `measurement.result` (`frame_id` 0, face 0) |

      | send | frame |

      | receive | `measurement.result` (`frame_id` 1, faces 0 and 1) |

      | send | frame (a PNG, not a JPEG) |

      | receive | `error` (`invalid_image_frame`) |

      | send | frame |

      | receive | `measurement.result` (`frame_id` 2, face 1) |

      | send | `session.close` |

      | receive | `session.closed` (`received.frames` 3, `produced.measurements`
      4) |
    publish:
      operationId: subpackage_video.Stream images-publish
      summary: Server messages
      message:
        oneOf:
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-server-0-videoReceiveSessionCreated
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-server-1-videoReceiveSessionUpdated
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-server-2-videoReceiveMeasurementResult
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-server-3-videoReceiveError
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-server-4-videoReceiveSessionClosed
    subscribe:
      operationId: subpackage_video.Stream images-subscribe
      summary: Client messages
      message:
        oneOf:
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-client-0-videoSendSessionUpdate
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-client-1-videoSendSessionClose
          - $ref: >-
              #/components/messages/subpackage_video.Stream
              images-client-2-videoSendImageFrame
servers:
  Production:
    url: wss://api.cloud.hume.ai/
    protocol: wss
    x-default: true
components:
  messages:
    subpackage_video.Stream images-server-0-videoReceiveSessionCreated:
      name: videoReceiveSessionCreated
      title: session.created
      description: >-
        Sent when the connection opens, before you send anything. Carries the
        session ID and the default configuration, which stays in effect unless
        you change it with `session.update`.
      payload:
        $ref: '#/components/schemas/video_sessionCreated'
    subpackage_video.Stream images-server-1-videoReceiveSessionUpdated:
      name: videoReceiveSessionUpdated
      title: session.updated
      description: >-
        Sent when a `session.update` is accepted. Carries the full configuration
        now in effect, including defaults for any fields you omitted.
      payload:
        $ref: '#/components/schemas/video_sessionUpdated'
    subpackage_video.Stream images-server-2-videoReceiveMeasurementResult:
      name: videoReceiveMeasurementResult
      title: measurement.result
      description: >-
        Sent once for every frame that was measured, in the order you sent the
        frames, including frames in which no face was found.
      payload:
        $ref: '#/components/schemas/video_measurementResult'
    subpackage_video.Stream images-server-3-videoReceiveError:
      name: videoReceiveError
      title: error
      description: >-
        Sent when a message you sent is rejected or the server fails to process
        it. For a recoverable error the message is rejected and the session
        continues; for a session-ending error, `session.closed` with `reason`
        `error` follows. `ErrorCode` lists each code, its class, and what to do.
      payload:
        $ref: '#/components/schemas/video_error'
    subpackage_video.Stream images-server-4-videoReceiveSessionClosed:
      name: videoReceiveSessionClosed
      title: session.closed
      description: >-
        Sent as the last message of the session. Carries the reason the session
        ended and totals of what was received and produced. The connection
        closes immediately after it, with the close code for the `reason`.
      payload:
        $ref: '#/components/schemas/video_sessionClosed'
    subpackage_video.Stream images-client-0-videoSendSessionUpdate:
      name: videoSendSessionUpdate
      title: session.update
      description: >-
        Replaces the whole configuration; any field you omit returns to its
        default. Send it before your first frame, because once a frame has
        passed the rate check, whether or not it decoded, a `session.update`
        ends the session with `config_invalid`. The server confirms with
        `session.updated`, or ends the session with `config_invalid` if the
        message contains an unrecognized field or an unsupported value.
      payload:
        $ref: '#/components/schemas/video_sessionUpdate'
    subpackage_video.Stream images-client-1-videoSendSessionClose:
      name: videoSendSessionClose
      title: session.close
      description: >-
        Ends the session. The server sends any final results, then
        `session.closed`, and closes the connection with code 1000; on the audio
        endpoint, if the final measurement fails, `error` and `session.closed`
        with `reason` `error` follow instead. Prefer this to closing the
        WebSocket yourself, which ends the session immediately and discards any
        final results and the totals.
      payload:
        $ref: '#/components/schemas/video_sessionClose'
    subpackage_video.Stream images-client-2-videoSendImageFrame:
      name: videoSendImageFrame
      title: image frame
      description: >-
        A binary message containing one complete JPEG image. The server detects
        the faces in it and answers with one `measurement.result`, or with an
        `error` if the frame is rejected or its measurement fails. Frames
        rejected with `invalid_image_frame` or `rate_limited` are skipped and
        the session continues; a message over the size limit ends the session
        with `message_too_large`.
      payload:
        $ref: '#/components/schemas/video_imageFrame'
  schemas:
    SessionId:
      type: string
      format: uuid
      description: >-
        Unique identifier for the session. It is also the `run_id` of the run
        the session is recorded as. Include it when contacting support about a
        session.
      title: SessionId
    ImageConfig:
      type: object
      properties:
        type:
          type: string
          enum:
            - image/jpeg
      required:
        - type
      description: The image format.
      title: ImageConfig
    FaceConfig:
      type: object
      properties:
        threshold:
          type: number
          format: double
          minimum: 0
          maximum: 1
          description: >-
            Minimum detection confidence for a face to be measured. Lower values
            include more faces at the risk of false detections. This scale is
            specific to this API; thresholds tuned for other face detection APIs
            do not carry over. Reported rounded to four decimal places.
        min_size:
          type: integer
          minimum: 1
          maximum: 4294967295
          description: >-
            Minimum face size to measure, as the shorter side of the face's
            bounding box in pixels of the submitted image.
      required:
        - threshold
        - min_size
      description: The face detection settings.
      title: FaceConfig
    video_sessionCreated:
      type: object
      properties:
        type:
          type: string
          enum:
            - session.created
        session_id:
          $ref: '#/components/schemas/SessionId'
        image:
          $ref: '#/components/schemas/ImageConfig'
        face:
          $ref: '#/components/schemas/FaceConfig'
      required:
        - type
        - session_id
        - image
        - face
      description: >-
        The session ID and the configuration in effect when the connection
        opened.
      title: video_sessionCreated
    video_sessionUpdated:
      type: object
      properties:
        type:
          type: string
          enum:
            - session.updated
        image:
          $ref: '#/components/schemas/ImageConfig'
        face:
          $ref: '#/components/schemas/FaceConfig'
      required:
        - type
        - image
        - face
      description: >-
        The full configuration in effect after a `session.update`, including
        defaults for any fields you omitted.
      title: video_sessionUpdated
    BoundingBox:
      type: array
      items:
        type: number
        format: double
      description: >-
        The location of the face in the submitted image, as `[x0, y0, x1, y1]`:
        the top-left and bottom-right corners in pixels, with the origin at the
        top-left of the image. Coordinates are in the pixels as stored in the
        file: EXIF orientation is not applied.
      title: BoundingBox
    VideoExpressionName:
      type: string
      description: >-
        The name of an expression that can be detected on a face, from a
        vocabulary that differs from that of audio expressions; see the [full
        list of video
        expressions](/expression-measurement/docs/video/measurements#expressions).
        Names are lowercase and may contain spaces and punctuation. New names
        may be added over time; treat a name you do not recognize as a new
        prediction.
      title: VideoExpressionName
    VideoExpressionScore:
      type: object
      properties:
        name:
          $ref: '#/components/schemas/VideoExpressionName'
        probability:
          type: number
          format: double
          minimum: 0
          maximum: 1
          description: >-
            The probability that this expression is present, rounded to four
            decimal places.
      required:
        - name
        - probability
      description: A scored expression detected on the face.
      title: VideoExpressionScore
    VideoDescriptionName:
      type: string
      description: >-
        The name of a visible facial action; see the [full list of video
        descriptions](/expression-measurement/docs/video/measurements#descriptions).
        Names are lowercase and may contain spaces and punctuation. New names
        may be added over time; treat a name you do not recognize as a new
        prediction.
      title: VideoDescriptionName
    VideoDescriptionScore:
      type: object
      properties:
        name:
          $ref: '#/components/schemas/VideoDescriptionName'
        probability:
          type: number
          format: double
          minimum: 0
          maximum: 1
          description: >-
            The probability that this action is present, rounded to four decimal
            places.
      required:
        - name
        - probability
      description: A scored facial action.
      title: VideoDescriptionScore
    Face:
      type: object
      properties:
        face_id:
          type:
            - integer
            - 'null'
          minimum: 0
          description: >-
            Tracks this face across the images of a realtime session or a file
            request. IDs are assigned from 0 in the order faces are first
            measured, largest first within an image. A face normally keeps its
            ID while it is measured, and can get it back after it leaves the
            view or is no longer among the largest faces. The server remembers
            up to 32 faces, so a face that returns after many others have been
            measured may receive a new ID. IDs restart in every session and
            every file request, unless a file request continues them with a
            `face_state`, and do not identify a person. Null for a face that was
            not measured.
        bbox:
          $ref: '#/components/schemas/BoundingBox'
        confidence:
          type: number
          format: double
          minimum: 0
          maximum: 1
          description: >-
            Confidence that the bounding box contains a face. Always at or above
            the configured `threshold`. Unrelated to the expression scores.
        expressions:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/VideoExpressionScore'
          description: >-
            Expressions detected on the face, such as `amusement`, `interest`
            and `surprise (positive)`, in descending order of probability, then
            by name. Only scores above 0.1 are included, so the array may be
            empty. `probability` is the chance a human rater would name the
            expression for this face, independently for each expression. Null
            for a face that was not measured.
        descriptions:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/VideoDescriptionScore'
          description: >-
            Visible facial actions, such as `smile`, `jaw drop` and `wide-eyed`,
            in descending order of probability, then by name. Only scores above
            0.1 are included, so the array may be empty. Null for a face that
            was not measured.
      required:
        - face_id
        - bbox
        - confidence
        - expressions
        - descriptions
      description: >-
        A face detected in the image, with its expression measurements if it was
        measured. Only the largest faces in an image are measured; the others
        carry their bounding box and detection confidence, with `face_id`,
        `expressions` and `descriptions` null.
      title: Face
    video_measurementResult:
      type: object
      properties:
        type:
          type: string
          enum:
            - measurement.result
        frame_id:
          type: integer
          minimum: 0
          description: >-
            Sequential identifier of the frame within the session, starting at
            0. Only frames answered with a `measurement.result` receive an ID,
            so the Nth result is for the Nth frame that was not answered with an
            `error`.
        faces:
          type: array
          items:
            $ref: '#/components/schemas/Face'
          description: >-
            The faces detected in the frame: the measured faces first, largest
            first, then the faces that were not measured, in descending order of
            confidence.
      required:
        - type
        - frame_id
        - faces
      description: >-
        Expression measurements for every face in one frame. `faces` is empty
        when no face was detected; this is a normal result, not an error.
      title: video_measurementResult
    ErrorCode:
      type: string
      enum:
        - invalid_audio_frame
        - invalid_image_frame
        - message_invalid
        - rate_limited
        - config_invalid
        - message_too_large
        - internal_error
      description: >-
        Identifies what went wrong and whether the session continues.


        **Recoverable.** The message is rejected and the session continues.


        - `invalid_audio_frame`: the audio frame was empty, had an odd number of
        bytes, or held more than 10 seconds of audio. Check how you slice audio
        and keep sending. Audio only.

        - `invalid_image_frame`: the frame was empty, was not a JPEG, or
        exceeded the pixel limit. Check the image and keep sending. Video only.

        - `message_invalid`: a text message was not valid JSON, had no `type`,
        or had an unrecognized `type`. Correct the message and keep sending.

        - `rate_limited`: media arrived faster than the send rate and was not
        processed. Audio: wait briefly and send the same frame again, so that
        the stream stays continuous. Video: from a live camera, drop the frame
        and send the next; from a recording, wait briefly and send the same
        frame again.


        **Depends on the endpoint.**


        - `internal_error`: the server failed while processing media. Audio: the
        session ends as for a session-ending error; open a new connection.
        Video: the frame is skipped and the session continues; resend it if you
        need a result for it. Five consecutive failures end the session; frames
        that are rejected or have no faces to measure do not reset the count.


        **Session-ending.** `error` is followed by `session.closed` with
        `reason` `error`, and the connection closes with code 1008.


        - `config_invalid`: a `session.update` contained an unrecognized field
        or an unsupported value, or arrived after you started sending media.
        Correct the message and open a new connection.

        - `message_too_large`: a message exceeded the size limit. Reduce the
        frame size and open a new connection.
      title: ErrorCode
    video_error:
      type: object
      properties:
        type:
          type: string
          enum:
            - error
        code:
          $ref: '#/components/schemas/ErrorCode'
        message:
          type: string
          description: >-
            A human-readable description of the error, intended for logging and
            debugging. The wording may change; use `code` for programmatic
            handling.
        retryable:
          type: boolean
          description: >-
            `false` for every error that ends the session. `true` for every
            error the session survives, except `internal_error` on the video
            endpoint, where it reports whether the failure was temporary and the
            frame is worth resending.
      required:
        - type
        - code
        - message
        - retryable
      description: >-
        A rejected message or a processing failure. `code` says what happened
        and whether the session continues.
      title: video_error
    CloseReason:
      type: string
      enum:
        - client_request
        - server_shutdown
        - idle_timeout
        - error
      description: >-
        Why the session ended. `session.closed` is the last message, and the
        WebSocket close code that follows it depends on the reason.


        - `client_request`: you sent `session.close`. Close code 1000.

        - `server_shutdown`: the server is restarting; reconnect at once to
        start a new session. Close code 1012.

        - `idle_timeout`: the server received no media frame it could use for 30
        seconds; open a new session to continue. Close code 1000.

        - `error`: a session-ending error, reported in the preceding `error`
        message. Close code 1008.
      title: CloseReason
    VideoReceived:
      type: object
      properties:
        frames:
          type: integer
          minimum: 0
          description: >-
            Number of frames accepted for measurement. Frames rejected before
            detection are not counted, so comparing this with the number you
            sent tells you how many were rejected. A frame whose measurement
            then failed with `internal_error` is counted although it produced no
            result, so this can exceed the number of results you received.
      required:
        - frames
      description: What the server received during the session.
      title: VideoReceived
    VideoProduced:
      type: object
      properties:
        measurements:
          type: integer
          minimum: 0
          description: >-
            Number of faces measured across all frames: a frame with two
            measured faces counts as two, and a frame with none counts as zero.
            A face listed without measurements is not counted. This counts
            faces; the audio endpoint's field of the same name counts messages.
      required:
        - measurements
      description: What the server produced during the session.
      title: VideoProduced
    video_sessionClosed:
      type: object
      properties:
        type:
          type: string
          enum:
            - session.closed
        session_id:
          $ref: '#/components/schemas/SessionId'
        reason:
          $ref: '#/components/schemas/CloseReason'
        received:
          $ref: '#/components/schemas/VideoReceived'
        produced:
          $ref: '#/components/schemas/VideoProduced'
      required:
        - type
        - session_id
        - reason
        - received
        - produced
      description: Why the session ended, and totals of what was received and produced.
      title: video_sessionClosed
    ImageConfigUpdate:
      type: object
      properties:
        type:
          type: string
          enum:
            - image/jpeg
          default: image/jpeg
      description: >-
        The format of the frames you send. Only one format is supported; any
        other value is rejected with `config_invalid`.
      title: ImageConfigUpdate
    FaceConfigUpdate:
      type: object
      properties:
        threshold:
          type: number
          format: double
          minimum: 0
          maximum: 1
          default: 0.9
          description: >-
            Minimum detection confidence for a face to be measured. Lower values
            include more faces at the risk of false detections. This scale is
            specific to this API; thresholds tuned for other face detection APIs
            do not carry over.
        min_size:
          type: integer
          minimum: 1
          maximum: 4294967295
          default: 60
          description: >-
            Minimum face size to measure, as the shorter side of the face's
            bounding box in pixels of the submitted image.
      description: The face detection settings to apply.
      title: FaceConfigUpdate
    video_sessionUpdate:
      type: object
      properties:
        type:
          type: string
          enum:
            - session.update
        image:
          $ref: '#/components/schemas/ImageConfigUpdate'
        face:
          $ref: '#/components/schemas/FaceConfigUpdate'
      required:
        - type
      description: >-
        The configuration to apply to the session. Omitted fields are reset to
        their defaults.
      title: video_sessionUpdate
    video_sessionClose:
      type: object
      properties:
        type:
          type: string
          enum:
            - session.close
      required:
        - type
      description: A request to end the session.
      title: video_sessionClose
    video_imageFrame:
      type: string
      format: binary
      description: >-
        One complete JPEG image, within the size and pixel limits given in the
        channel description.
      title: video_imageFrame

```