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

# List the fan's messages

> Lists the fan's own messages in a Fan Voice, with what happened to each, so your app can show them.



## OpenAPI

````yaml /experiences/api-reference/experiences.openapi.yaml get /fan-voices/{fan_voice_id}/messages/me
openapi: 3.1.0
info:
  title: 'Dizplai API: Experiences'
  version: 1.0.0
  summary: Read polls, Fan Voices and collections, and let fans vote and send messages.
  description: >
    Show polls and Fan Voices in your own apps and sites, and let fans take
    part: read experiences and collections, send

    fans' votes and messages, and read back a fan's own vote and messages.


    **Headers.** Send `x-api-key`, your organisation's API key, on every
    request. When a fan takes part, or reads

    their own vote or messages, add their token from your own login as
    `Authorization: Bearer <token>`.


    **Names.** An experience is one thing fans take part in: a poll or a Fan
    Voice. A collection groups experiences for a

    match or show, and an experience can be in many collections. Every ID is a
    UUID: store it in a UUID column or as

    text, and never parse it.


    **Conventions.** snake_case fields; `after` and `limit` paging (50 by
    default, 100 at most) with `{items, next}`;

    errors are RFC 9457 problems with a stable `code` and a `request_id`, and
    every response carries `x-request-id`.

    Types, statuses and codes can gain values within v1, so ignore one you don't
    know.


    **Refreshing.** Read an open poll every 10 seconds and lists every 30
    seconds, and wait as long as `Retry-After`

    says after a `429` or `503`. The Experiences guide has the details.
  contact:
    name: Dizplai
servers:
  - url: https://api.dizplai.com/v1
    description: The Dizplai API.
security:
  - apiKey: []
tags:
  - name: Experiences
    description: >-
      Everything fans can take part in, in one list: build a match or show
      screen from it, drawing each experience by its type.
  - name: Collections
    description: >-
      Groups of experiences, one for each match or show, to organise your
      screens. An experience can be in many collections, in its own order in
      each.
  - name: Polls
    description: >-
      A poll asks fans one question with a short list of answers. Read polls and
      their results, send a fan's vote, and read back the vote they made.
  - name: Fan Voices
    description: >-
      A Fan Voice asks fans to reply in their own words, with text, a voice note
      or a photo. Read a Fan Voice, send a fan's message, and show the fan what
      happened to it. Fans never see each other's messages.
paths:
  /fan-voices/{fan_voice_id}/messages/me:
    parameters:
      - name: fan_voice_id
        in: path
        required: true
        description: The Fan Voice's ID, from a list of experiences or Fan Voices.
        schema:
          $ref: '#/components/schemas/FanVoiceId'
    get:
      tags:
        - Fan Voices
      summary: List the fan's messages
      description: >-
        Lists the fan's own messages in a Fan Voice, with what happened to each,
        so your app can show them.
      operationId: listMyFanVoiceMessages
      parameters:
        - $ref: '#/components/parameters/After'
        - $ref: '#/components/parameters/Limit'
      responses:
        '200':
          description: >-
            The fan's messages, newest first, each with its status. A message
            that isn't approved, or is removed, comes with the reason; fans
            can't ask for a review. Not cached, as the answer belongs to one
            fan.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
            Cache-Control:
              $ref: '#/components/headers/NoStore'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/MyFanVoiceMessagePage'
              examples:
                example:
                  $ref: '#/components/examples/MyFanVoiceMessagePage'
        '401':
          $ref: '#/components/responses/FanUnauthorised'
        '403':
          $ref: '#/components/responses/ReadForbidden'
        '404':
          $ref: '#/components/responses/FanVoiceNotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/ReadUnavailable'
      security:
        - apiKey: []
          fanToken: []
components:
  schemas:
    FanVoiceId:
      type: string
      description: A Fan Voice's ID, a UUID.
      format: uuid
      examples:
        - 0192fa7b-a1a5-7ae6-8820-782ce84e0f49
    MyFanVoiceMessagePage:
      type: object
      required:
        - items
        - next
      properties:
        items:
          type: array
          description: The fan's messages, newest first.
          items:
            $ref: '#/components/schemas/MyFanVoiceMessage'
        next:
          type:
            - string
            - 'null'
          description: Pass as after for the next page. Null on the last page.
    MyFanVoiceMessage:
      type: object
      required:
        - message_id
        - fan_voice_id
        - kind
        - status
        - sent_at
      description: >-
        One of the fan's own messages. Only ever returned to the fan who sent
        it.
      properties:
        message_id:
          $ref: '#/components/schemas/MessageId'
        fan_voice_id:
          $ref: '#/components/schemas/FanVoiceId'
        kind:
          type: string
          x-extensible-enum:
            - text
            - voice
            - image
          description: >-
            What kind of message it is: text, voice (a voice note) or image (a
            photo). More kinds may be added: for one you don't know, show its
            text if it has any.
        text:
          type: string
          description: The message, or a photo's caption. Absent for a voice note.
        media_url:
          type: string
          format: uri
          description: >-
            The voice note or photo, served once a moderator approves it. Absent
            while it waits, and gone once it's not approved or removed.
        transcript:
          type: string
          description: A voice note's transcript, once it's approved.
        status:
          type: string
          x-extensible-enum:
            - sent
            - approved
            - not_approved
            - removed
          description: >-
            Where the message stands. sent: received, waiting for your team to
            review it. approved: your team approved it; it's used on air only if
            on_air_consent was true. not_approved: it won't be used; see reason.
            removed: it was approved, then taken down; see reason. More statuses
            may be added: treat one you don't know as still waiting.
        sent_at:
          $ref: '#/components/schemas/Timestamp'
          description: When the fan sent it.
        decided_at:
          $ref: '#/components/schemas/Timestamp'
          description: >-
            When it was approved, not approved or removed. Absent while it
            waits.
        reason:
          type: object
          required:
            - code
            - statement
          description: >-
            Why it wasn't used, in words to show the fan, and whether an
            automatic check was involved. Present when not approved or removed.
            Fans can't ask for a review.
          properties:
            code:
              type: string
              x-extensible-enum:
                - illegal_content
                - hate_or_abuse
                - defamatory
                - spam
                - personal_data
                - copyright
                - contains_child
                - off_topic
                - other
              description: >
                Why, as a code. More codes may be added: for one you don't know,
                show the statement.


                - illegal_content: it's illegal.

                - hate_or_abuse: it's hateful or abusive.

                - defamatory: it makes damaging claims about someone.

                - spam: it's spam or advertising.

                - personal_data: it shares someone's personal details.

                - copyright: it uses someone else's work without permission.

                - contains_child: it shows or identifies a child.

                - off_topic: it isn't about the prompt.

                - other: another reason, given in the statement.
            statement:
              type: string
              description: Why, in plain words, to show the fan.
            automated_check:
              type: boolean
              description: >-
                True if an automatic check was involved. Automatic checks can
                only reject a message; a person makes every approval.
    Problem:
      type: object
      required:
        - type
        - code
        - title
        - status
        - request_id
      description: >-
        What went wrong, in the same shape for every error: an RFC 9457 problem
        with a stable code. Act on code, which never changes meaning within a
        version, and on the HTTP status for a code you don't know. Quote
        request_id to support.
      properties:
        type:
          type: string
          format: uri-reference
          description: >-
            One URL per code: https://api.dizplai.com/problems/ followed by the
            code with hyphens, such as
            https://api.dizplai.com/problems/unknown-option for unknown_option.
        code:
          type: string
          x-extensible-enum:
            - invalid_request
            - unknown_option
            - not_open
            - media_not_accepted
            - invalid_upload
            - invalid_api_key
            - invalid_fan_token
            - forbidden
            - fan_blocked
            - sign_in_required
            - message_limit_reached
            - not_found
            - idempotency_conflict
            - rate_limited
            - unavailable
          description: >
            More codes may be added: for one you don't know, act on the HTTP
            status.


            | code | Status | Retry? | Meaning |

            |---|---|---|---|

            | invalid_request | 400 | No | The body or a parameter is invalid,
            or a required header such as Idempotency-Key is missing. |

            | unknown_option | 400 | No; read the poll again | An option ID the
            poll doesn't have. |

            | not_open | 400 | No; read the experience again | The experience
            isn't taking votes or messages: it isn't live yet, or votes have
            stopped. |

            | media_not_accepted | 400 | No | The Fan Voice doesn't take this
            kind of message, or the file's type or size is outside the limits. |

            | invalid_upload | 400 | No; upload again | The upload_id is
            unknown, already used or another fan's, or the file was never
            uploaded or its type or size differs from what you asked for. |

            | invalid_api_key | 401 | No | A missing or invalid x-api-key. |

            | invalid_fan_token | 401 | Once, with a fresh token | A missing,
            invalid or expired fan token, or one from another organisation's
            login. It carries WWW-Authenticate. |

            | forbidden | 403 | No | Your API key isn't allowed to make this
            request. |

            | fan_blocked | 403 | No | The fan is blocked from this Fan Voice. |

            | sign_in_required | 403 | No; ask the fan to sign in | A guest on
            an experience that needs a signed-in fan, or a guest's voice note or
            photo. |

            | message_limit_reached | 403 | No | The fan has used up this Fan
            Voice's messages of this kind. |

            | not_found | 404 | No | Not found, or not yours. |

            | idempotency_conflict | 409 | No | An Idempotency-Key reused with a
            different body while it's kept: 24 hours, or 5 minutes for an
            upload. |

            | rate_limited | 429 | After Retry-After | Too many requests. |

            | unavailable | 503 | After Retry-After | Votes or messages can't be
            taken right now. |
        title:
          type: string
          description: A short title for the code, such as Not open. It doesn't change.
        status:
          type: integer
          description: The HTTP status code.
          minimum: 400
          maximum: 599
        detail:
          type: string
          description: >-
            What went wrong, in plain English. It can change, so don't act on
            it.
        request_id:
          type: string
          description: Matches the x-request-id response header.
        errors:
          type: array
          description: Field-level validation errors, with invalid_request.
          items:
            type: object
            required:
              - pointer
              - message
            properties:
              pointer:
                type: string
                description: A JSON Pointer to the field.
              message:
                type: string
                description: What's wrong with that field.
    MessageId:
      type: string
      description: A Fan Voice message's ID, a UUID.
      format: uuid
    Timestamp:
      type: string
      format: date-time
      description: A date and time, RFC 3339, in UTC.
  parameters:
    After:
      name: after
      in: query
      required: false
      schema:
        type: string
      description: >-
        Where the next page starts, the next value from the previous page. Leave
        it out for the first page.
    Limit:
      name: limit
      in: query
      required: false
      description: How many items a page holds, 1 to 100. 50 by default.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 50
  headers:
    RequestId:
      description: The request's ID. Quote it to support.
      schema:
        type: string
    NoStore:
      description: 'no-store: the answer belongs to one fan, so no cache may keep it.'
      schema:
        type: string
        const: no-store
    WwwAuthenticate:
      description: >-
        With invalid_fan_token only: Bearer error="invalid_token", with an
        error_description.
      schema:
        type: string
    RetryAfter:
      description: >-
        How long to wait before retrying, as a whole number of seconds. Sent
        with every 429 and 503.
      schema:
        type: integer
        minimum: 0
  examples:
    MyFanVoiceMessagePage:
      value:
        items:
          - message_id: 0192fa8a-1346-78cb-ba87-213c0a571aaa
            fan_voice_id: 0192fa7b-a1a5-7ae6-8820-782ce84e0f49
            kind: voice
            status: approved
            sent_at: '2026-11-21T20:44:10Z'
            decided_at: '2026-11-21T20:45:02Z'
            media_url: >-
              https://media.example.com/fan-voices/0192fa7b-a1a5-7ae6-8820-782ce84e0f49/0192fa8a-9346-78b7-9664-3cb0e5caf78d.m4a
            transcript: What a goal. Best atmosphere all season!
          - message_id: 0192fa8a-0f25-7ada-b6ef-44f5b3349023
            fan_voice_id: 0192fa7b-a1a5-7ae6-8820-782ce84e0f49
            kind: text
            text: Ref needs glasses
            status: not_approved
            sent_at: '2026-11-21T20:12:40Z'
            decided_at: '2026-11-21T20:13:05Z'
            reason:
              code: hate_or_abuse
              statement: It targets a person rather than the match, so we won't use it.
              automated_check: false
          - message_id: 0192fa8a-0ae4-728d-a8ba-cafc119ba65f
            fan_voice_id: 0192fa7b-a1a5-7ae6-8820-782ce84e0f49
            kind: text
            text: Brilliant second half. Keep pressing!
            status: approved
            sent_at: '2026-11-21T20:05:02Z'
            decided_at: '2026-11-21T20:05:30Z'
        next: null
  responses:
    FanUnauthorised:
      description: >-
        A missing or invalid x-api-key (invalid_api_key), or a missing, invalid
        or expired fan token, or one from another organisation's login
        (invalid_fan_token). Only invalid_fan_token carries WWW-Authenticate:
        refresh the fan's token and retry once.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
        WWW-Authenticate:
          $ref: '#/components/headers/WwwAuthenticate'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            invalid_fan_token:
              summary: invalid_fan_token
              value:
                type: https://api.dizplai.com/problems/invalid-fan-token
                code: invalid_fan_token
                title: Invalid fan token
                status: 401
                detail: The fan's token has expired.
                request_id: 01JBX8P2R4T6V8X0Z2B4D6F8H0
            invalid_api_key:
              summary: invalid_api_key
              value:
                type: https://api.dizplai.com/problems/invalid-api-key
                code: invalid_api_key
                title: Invalid API key
                status: 401
                detail: The x-api-key isn't recognised.
                request_id: 01JBX8P2R4T6V8X0Z2B4D6F8H0
    ReadForbidden:
      description: >-
        Not allowed for this caller or origin (forbidden), such as a browser
        Origin your organisation hasn't registered, or a platform key sent from
        a browser. Retrying won't help: check the key and your registered
        origins.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            forbidden:
              summary: forbidden
              value:
                type: https://api.dizplai.com/problems/forbidden
                code: forbidden
                title: Forbidden
                status: 403
                detail: This origin isn't registered for this organisation.
                request_id: 01JBX8P2R4T6V8X0Z2B4D6F8H0
    FanVoiceNotFound:
      description: >-
        The Fan Voice doesn't exist, isn't yours, or was taken down or deleted
        (not_found).
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            not_found:
              summary: not_found
              value:
                type: https://api.dizplai.com/problems/not-found
                code: not_found
                title: Not found
                status: 404
                detail: No such Fan Voice.
                request_id: 01JBX8P2R4T6V8X0Z2B4D6F8H0
    TooManyRequests:
      description: >-
        Too many requests (rate_limited). Wait the number of seconds in
        Retry-After, then retry.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            rate_limited:
              summary: rate_limited
              value:
                type: https://api.dizplai.com/problems/rate-limited
                code: rate_limited
                title: Rate limited
                status: 429
                detail: Too many requests. Retry after 2 seconds.
                request_id: 01JBX8P2R4T6V8X0Z2B4D6F8H0
    ReadUnavailable:
      description: >-
        This can't be read right now (unavailable). Wait the number of seconds
        in Retry-After, then retry, and keep showing what you last read.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
        Retry-After:
          $ref: '#/components/headers/RetryAfter'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            unavailable:
              summary: unavailable
              value:
                type: https://api.dizplai.com/problems/unavailable
                code: unavailable
                title: Unavailable
                status: 503
                detail: This can't be read right now. Retry after 5 seconds.
                request_id: 01JBX8P2R4T6V8X0Z2B4D6F8H0
  securitySchemes:
    apiKey:
      type: apiKey
      in: header
      name: x-api-key
      description: >-
        Your organisation's API key, supplied by Dizplai. Send it on every
        request. It isn't a secret, so it can ship in your app: what a fan does
        is protected by the fan's token.
    fanToken:
      type: http
      scheme: bearer
      description: >-
        The fan's token from your own login, sent as `Authorization: Bearer
        <token>`: a signed-in fan's or a guest's. Dizplai checks it against your
        login's details, agreed when you're set up, and a guest's token carries
        the guest claim agreed at the same time. Needed to vote, upload, send a
        message, and read the fan's own vote or messages.

````

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