> ## 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.

# Get a Fan Voice

> Gets a Fan Voice with its prompt, the kinds of message it takes and how many each fan can send, to draw its screen.



## OpenAPI

````yaml /experiences/api-reference/experiences.openapi.yaml get /fan-voices/{fan_voice_id}
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}:
    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: Get a Fan Voice
      description: >-
        Gets a Fan Voice with its prompt, the kinds of message it takes and how
        many each fan can send, to draw its screen.
      operationId: getFanVoice
      responses:
        '200':
          description: The Fan Voice.
          headers:
            x-request-id:
              $ref: '#/components/headers/RequestId'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/FanVoice'
              examples:
                example:
                  $ref: '#/components/examples/FanVoice'
        '401':
          $ref: '#/components/responses/Unauthorised'
        '403':
          $ref: '#/components/responses/ReadForbidden'
        '404':
          $ref: '#/components/responses/FanVoiceNotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/ReadUnavailable'
components:
  schemas:
    FanVoiceId:
      type: string
      description: A Fan Voice's ID, a UUID.
      format: uuid
      examples:
        - 0192fa7b-a1a5-7ae6-8820-782ce84e0f49
    FanVoice:
      title: Fan Voice
      type: object
      description: >-
        A Fan Voice: a prompt fans reply to in their own words, with text, a
        voice note or a photo. Show the prompt and a message box, offer the
        kinds in kinds, and keep within limits. It has no results: fans see only
        their own messages.
      required:
        - id
        - type
        - status
        - starts_at
        - ends_at
        - metadata
        - locale
        - created_at
        - updated_at
        - requires_sign_in
        - prompt
        - limits
        - kinds
      properties:
        id:
          $ref: '#/components/schemas/FanVoiceId'
        type:
          type: string
          enum:
            - fan_voice
          description: Tells Fan Voices apart from other experiences in a list.
        status:
          $ref: '#/components/schemas/Status'
        starts_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When it's due to open. Null if your producers open it by hand.
        ends_at:
          type:
            - string
            - 'null'
          format: date-time
          description: When it's due to close. Null if no closing time is set.
        metadata:
          $ref: '#/components/schemas/Metadata'
        locale:
          $ref: '#/components/schemas/Locale'
          description: The language the experience's text is written in, such as en-GB.
        created_at:
          $ref: '#/components/schemas/Timestamp'
          description: When the Fan Voice was created.
        updated_at:
          $ref: '#/components/schemas/Timestamp'
          description: Changes when anything a fan can see changes.
        requires_sign_in:
          type: boolean
          description: >-
            True if only signed-in fans may take part: show a guest your sign-in
            prompt instead. A guest's vote or message here answers 403
            (sign_in_required). Voice notes and photos are always for signed-in
            fans.
        prompt:
          type: string
          minLength: 1
          maxLength: 500
          description: What fans are asked to reply to.
        placeholder:
          type: string
          description: Hint text for the message box, such as Your message.
          maxLength: 500
        confirmation_message:
          type: string
          maxLength: 500
          description: What to show the fan once their message is sent.
        kinds:
          type: array
          uniqueItems: true
          items:
            type: string
            x-extensible-enum:
              - text
              - voice
              - image
          description: >-
            What fans may send: text, voice (voice notes) or image (photos).
            More kinds may be added: offer only the ones your app knows. Voice
            notes and photos are for signed-in fans only, with fixed limits: a
            voice note is audio/mp4 or audio/webm, up to 5 MB and 60 seconds; a
            photo is image/jpeg, image/png, image/heic or image/webp, up to 10
            MB.
        limits:
          type: object
          required:
            - max_text_length
            - per_fan
          description: >-
            `max_text_length`, 1 to 500, and `per_fan`, how many messages of
            each kind one fan may send, 1 to 100.
          properties:
            max_text_length:
              type: integer
              description: The longest text message, in characters.
              minimum: 1
              maximum: 500
              default: 500
            per_fan:
              type: object
              additionalProperties:
                type: integer
                minimum: 1
                maximum: 100
              description: >-
                How many messages of each kind one fan may send to this Fan
                Voice, keyed by kind. Every message the fan sends counts,
                approved or not, and the count never resets, even if the Fan
                Voice reopens. To show what's left, count the fan's messages
                from `GET /fan-voices/{fan_voice_id}/messages/me`. More kinds
                may be added: ignore one you don't know.
              properties:
                text:
                  type: integer
                  description: Text messages each fan may send.
                  minimum: 1
                  maximum: 100
                  default: 3
                voice:
                  type: integer
                  description: Voice notes each fan may send.
                  minimum: 1
                  maximum: 100
                  default: 1
                image:
                  type: integer
                  description: Photos each fan may send.
                  minimum: 1
                  maximum: 100
                  default: 1
    Status:
      type: string
      description: >-
        Whether fans can take part now. scheduled: coming up, and goes live at
        starts_at. live: taking votes or messages. closed: taking part has
        stopped; it can reopen. An experience your producers take down or delete
        drops out of lists, and getting it answers 404. More statuses may be
        added: treat one you don't know as closed to taking part.
      x-extensible-enum:
        - scheduled
        - live
        - closed
    Metadata:
      type: object
      maxProperties: 50
      propertyNames:
        maxLength: 40
      additionalProperties:
        type: string
        maxLength: 500
      description: >-
        Tags for finding and grouping things, such as the match or show they're
        about. Filter lists by them with `metadata[key]=value`. Up to 50 keys of
        up to 40 characters, values up to 500. One key is reserved, event_id,
        set by your producers; every other key is yours, and never interpreted.
      properties:
        event_id:
          type: string
          maxLength: 64
          description: >-
            An ID for the match or show this is about, set by your producers.
            Reserved.
    Locale:
      type: string
      maxLength: 35
      pattern: ^[A-Za-z]{2,3}(-[A-Za-z0-9]{2,8})*$
      examples:
        - en-GB
      description: >-
        A BCP 47 language tag. en-GB, British English, is the only language for
        now. More may be added: show text in a locale you don't know as it is.
      x-extensible-enum:
        - en-GB
    Timestamp:
      type: string
      format: date-time
      description: A date and time, RFC 3339, in UTC.
    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.
  headers:
    RequestId:
      description: The request's ID. Quote it to support.
      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:
    FanVoice:
      summary: Fan Voice
      value:
        id: 0192fa7b-a1a5-7ae6-8820-782ce84e0f49
        type: fan_voice
        status: live
        starts_at: null
        ends_at: null
        metadata:
          event_id: ev_2041
        locale: en-GB
        created_at: '2026-11-20T15:02:11Z'
        updated_at: '2026-11-21T20:41:07Z'
        requires_sign_in: false
        prompt: What's your message for the team?
        placeholder: Type your message
        confirmation_message: Thanks! Your message is with the team.
        kinds:
          - text
          - voice
          - image
        limits:
          max_text_length: 280
          per_fan:
            text: 3
            voice: 1
            image: 1
  responses:
    Unauthorised:
      description: >-
        A missing or invalid x-api-key (invalid_api_key). Don't retry: check the
        key.
      headers:
        x-request-id:
          $ref: '#/components/headers/RequestId'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            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.

````

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