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

# Remove a reaction

> Idempotent. Removes only the reaction the student left.



## OpenAPI

````yaml /api-reference/openapi.json delete /api/chat/messages/{id}/reactions/{emoji}
openapi: 3.1.0
info:
  title: Lala Client API
  description: >-
    The HTTP API behind Lala, the AI study companion for Turkish YKS and LGS
    students. This document is generated from the Zod schemas that validate each
    request at runtime. Do not hand-edit openapi.json. Student-visible text is
    Turkish. All identifiers are English.
  version: 1.0.0
servers:
  - url: https://client-api.lala.ist
    description: production
  - url: http://localhost:3000
    description: local dev
security:
  - supabaseJwt: []
tags:
  - name: chat
    description: The chat stream, the message history, and reactions
  - name: media
    description: Upload and read message attachments
  - name: plan
    description: The study planner — blocks of work on a day
  - name: journey
    description: Deneme results, topic performance, study-hours stats, and the streak
  - name: profile
    description: The student profile and onboarding
  - name: devices
    description: Push notification devices
  - name: system
    description: Health check
paths:
  /api/chat/messages/{id}/reactions/{emoji}:
    delete:
      tags:
        - chat
      summary: Remove a reaction
      description: Idempotent. Removes only the reaction the student left.
      operationId: deleteApiChatMessagesByIdReactionsByEmoji
      parameters:
        - schema:
            type: string
          in: path
          name: id
          required: true
        - schema:
            type: string
          in: path
          name: emoji
          required: true
      responses:
        '200':
          description: The message, with its reactions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MessageResponse'
        '401':
          description: The token is missing, expired, or invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: No such message in this conversation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    MessageResponse:
      type: object
      properties:
        message:
          $ref: '#/components/schemas/ChatMessage'
      required:
        - message
    ErrorResponse:
      type: object
      properties:
        error:
          type: string
        issues:
          description: >-
            Present only on a 400 raised by request validation, capped at 10
            entries. Every other error carries `error` alone.
          type: array
          items:
            $ref: '#/components/schemas/ValidationIssue'
      required:
        - error
      description: Error body. `error` is a short English string.
    ChatMessage:
      type: object
      properties:
        id:
          type: string
        role:
          $ref: '#/components/schemas/MessageRole'
        content:
          type: string
        media:
          type: array
          items:
            $ref: '#/components/schemas/Media'
        reactions:
          type: array
          items:
            $ref: '#/components/schemas/MessageReaction'
        replyTo:
          anyOf:
            - $ref: '#/components/schemas/MessageRef'
            - type: 'null'
        turnIndex:
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
          description: >-
            Position in one Lala turn. 0 unless Lala answered in several
            messages.
        cursor:
          type: string
          description: Opaque. Pass as `before` to page backwards.
        timestamp:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
      required:
        - id
        - role
        - content
        - media
        - reactions
        - replyTo
        - turnIndex
        - cursor
        - timestamp
    ValidationIssue:
      type: object
      properties:
        path:
          type: string
          description: Dotted path to the offending field, empty at the root.
        message:
          type: string
      required:
        - path
        - message
    MessageRole:
      type: string
      enum:
        - user
        - lala
      description: Who wrote the message. Lala's role is `lala`.
    Media:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        kind:
          $ref: '#/components/schemas/MediaKind'
        mimeType:
          type: string
        sizeBytes:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        width:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        height:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        durationMs:
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        fileName:
          anyOf:
            - type: string
            - type: 'null'
        status:
          type: string
          enum:
            - pending
            - ready
          description: '`ready` when the bytes are in storage. Only ready media can be sent.'
        url:
          anyOf:
            - type: string
            - type: 'null'
          description: >-
            Short-lived signed URL, null while the media is pending. It expires
            — read the media or the message again for a new one. Do not cache
            it.
        urlExpiresAt:
          anyOf:
            - type: string
              format: date-time
              pattern: >-
                ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
            - type: 'null'
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
      required:
        - id
        - kind
        - mimeType
        - sizeBytes
        - width
        - height
        - durationMs
        - fileName
        - status
        - url
        - urlExpiresAt
        - createdAt
    MessageReaction:
      type: object
      properties:
        emoji:
          type: string
        actor:
          $ref: '#/components/schemas/MessageRole'
        createdAt:
          type: string
          format: date-time
          pattern: >-
            ^(?:(?:\d\d[2468][048]|\d\d[13579][26]|\d\d0[48]|[02468][048]00|[13579][26]00)-02-29|\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\d|30)|(?:02)-(?:0[1-9]|1\d|2[0-8])))T(?:(?:[01]\d|2[0-3]):[0-5]\d(?::[0-5]\d(?:\.\d+)?)?(?:Z))$
      required:
        - emoji
        - actor
        - createdAt
    MessageRef:
      type: object
      properties:
        id:
          type: string
          format: uuid
          pattern: >-
            ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
        role:
          $ref: '#/components/schemas/MessageRole'
        content:
          type: string
          description: The first 200 characters, for the quote.
        mediaKind:
          anyOf:
            - $ref: '#/components/schemas/MediaKind'
            - type: 'null'
      required:
        - id
        - role
        - content
        - mediaKind
      description: The message a reply points at.
    MediaKind:
      type: string
      enum:
        - image
        - audio
        - video
        - file
  securitySchemes:
    supabaseJwt:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'Supabase access token: `Authorization: Bearer <token>`'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.