DEV Community surveys API

The surveys API from DEV Community — 4 operation(s) for surveys.

OpenAPI Specification

devto-surveys-api-openapi.yml Raw ↑
openapi: 3.0.3
info:
  title: Forem API V1 agent_sessions surveys API
  version: 1.0.0
  description: "Access Forem articles, users and other resources via API.\n        For a real-world example of Forem in action, check out [DEV](https://www.dev.to).\n        All endpoints can be accessed with the 'api-key' header and a accept header, but\n        some of them are accessible publicly without authentication.\n\n        Dates and date times, unless otherwise specified, must be in\n        the [RFC 3339](https://tools.ietf.org/html/rfc3339) format."
servers:
- url: https://dev.to/api
  description: Production server
security:
- api-key: []
tags:
- name: surveys
paths:
  /api/surveys:
    get:
      summary: List surveys
      tags:
      - surveys
      description: 'This endpoint allows the client to retrieve a list of surveys.


        It supports pagination and optional filtering by active status.


        Internal only. Admin authorization is required to access this endpoint.'
      operationId: getSurveys
      parameters:
      - $ref: '#/components/parameters/pageParam'
      - $ref: '#/components/parameters/perPageParam30to1000'
      - name: active
        in: query
        required: false
        description: Filter by active status. Omit to return all surveys.
        schema:
          type: boolean
      responses:
        '200':
          description: A list of surveys
          content:
            application/json:
              example:
              - type_of: survey
                id: 43
                title: dolores
                slug: dolores-2875c66f
                active: true
                display_title: true
                allow_resubmission: false
                survey_type_of: community_pulse
                created_at: '2026-05-28T18:45:29Z'
                updated_at: '2026-05-28T18:45:29Z'
              - type_of: survey
                id: 44
                title: autem
                slug: autem-1c9b1a12
                active: true
                display_title: true
                allow_resubmission: false
                survey_type_of: community_pulse
                created_at: '2026-05-28T18:45:29Z'
                updated_at: '2026-05-28T18:45:29Z'
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Survey'
        '401':
          description: Unauthorized
          content:
            application/json:
              example:
                error: unauthorized
                status: 401
  /api/surveys/{id_or_slug}:
    get:
      summary: A survey with polls
      tags:
      - surveys
      description: 'This endpoint allows the client to retrieve a single survey by ID or slug,

        including its nested polls and poll options.


        Internal only. Admin authorization is required to access this endpoint.'
      operationId: getSurveyByIdOrSlug
      parameters:
      - name: id_or_slug
        in: path
        required: true
        description: The ID or slug of the survey.
        schema:
          type: string
        example: community-pulse-2026
      responses:
        '200':
          description: A survey with nested polls and options
          content:
            application/json:
              example:
                type_of: survey
                id: 45
                title: Test Survey
                slug: test-survey-1b83c27b
                active: true
                display_title: true
                allow_resubmission: false
                survey_type_of: community_pulse
                created_at: '2026-05-28T18:45:29Z'
                updated_at: '2026-05-28T18:45:29Z'
                polls:
                - type_of: poll
                  id: 51
                  prompt_markdown: What do you think?
                  prompt_html: 'What do you think?

                    '
                  position: 0
                  poll_votes_count: 0
                  poll_skips_count: 0
                  poll_options_count: 4
                  scale_min: null
                  scale_max: null
                  poll_type_of: single_choice
                  created_at: '2026-05-28T18:45:29Z'
                  updated_at: '2026-05-28T18:45:29Z'
                  poll_options:
                  - type_of: poll_option
                    id: 178
                    markdown: '2'
                    processed_html: '2

                      '
                    position: 0
                    poll_votes_count: 0
                    supplementary_text: null
                  - type_of: poll_option
                    id: 179
                    markdown: '4'
                    processed_html: '4

                      '
                    position: 1
                    poll_votes_count: 0
                    supplementary_text: null
                  - type_of: poll_option
                    id: 180
                    markdown: '2'
                    processed_html: '2

                      '
                    position: 2
                    poll_votes_count: 0
                    supplementary_text: null
                  - type_of: poll_option
                    id: 181
                    markdown: '1'
                    processed_html: '1

                      '
                    position: 3
                    poll_votes_count: 0
                    supplementary_text: null
              schema:
                $ref: '#/components/schemas/SurveyWithPolls'
        '401':
          description: Unauthorized
          content:
            application/json:
              example:
                error: unauthorized
                status: 401
        '404':
          description: Not found
          content:
            application/json:
              example:
                error: not found
                status: 404
  /api/surveys/{id_or_slug}/poll_votes:
    get:
      summary: Survey poll votes
      tags:
      - surveys
      description: 'This endpoint allows the client to retrieve poll votes for a given survey.

        Results are paginated. Use the `after` parameter with the last seen vote ID

        for cursor-based pagination.


        Internal only. Admin authorization is required to access this endpoint.'
      operationId: getSurveyPollVotes
      parameters:
      - name: id_or_slug
        in: path
        required: true
        description: The ID or slug of the survey.
        schema:
          type: string
      - $ref: '#/components/parameters/perPageParam30to1000'
      - name: after
        in: query
        required: false
        description: Return only votes with an ID greater than this value.
        schema:
          type: integer
        example: 42
      responses:
        '200':
          description: Poll votes
          content:
            application/json:
              example:
              - type_of: poll_vote
                id: 28
                poll_id: 54
                poll_option_id: 190
                user_id: 4252
                session_start: 0
                user_email: person204@example.com
                created_at: '2026-05-28T18:45:29Z'
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PollVote'
        '401':
          description: Unauthorized
          content:
            application/json:
              example:
                error: unauthorized
                status: 401
        '404':
          description: Not found
          content:
            application/json:
              example:
                error: not found
                status: 404
  /api/surveys/{id_or_slug}/poll_text_responses:
    get:
      summary: Survey poll text responses
      tags:
      - surveys
      description: 'This endpoint allows the client to retrieve text responses for a given survey.

        Results are paginated. Use the `after` parameter with the last seen response ID

        for cursor-based pagination.


        Internal only. Admin authorization is required to access this endpoint.'
      operationId: getSurveyPollTextResponses
      parameters:
      - name: id_or_slug
        in: path
        required: true
        description: The ID or slug of the survey.
        schema:
          type: string
      - $ref: '#/components/parameters/perPageParam30to1000'
      - name: after
        in: query
        required: false
        description: Return only text responses with an ID greater than this value.
        schema:
          type: integer
        example: 42
      responses:
        '200':
          description: Poll text responses
          content:
            application/json:
              example:
              - type_of: poll_text_response
                id: 12
                poll_id: 57
                user_id: 4258
                text_content: Great survey!
                session_start: 0
                user_email: person210@example.com
                created_at: '2026-05-28T18:45:30Z'
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PollTextResponse'
        '401':
          description: Unauthorized
          content:
            application/json:
              example:
                error: unauthorized
                status: 401
        '404':
          description: Not found
          content:
            application/json:
              example:
                error: not found
                status: 404
components:
  schemas:
    PollOption:
      description: A single option within a poll
      type: object
      properties:
        type_of:
          type: string
          enum:
          - poll_option
          description: Resource discriminator
        id:
          type: integer
          format: int64
        markdown:
          type: string
          nullable: true
          description: Option text in markdown
        processed_html:
          type: string
          nullable: true
          description: Option text rendered as HTML
        position:
          type: integer
          format: int32
          description: Display order within the poll
        poll_votes_count:
          type: integer
          format: int32
          description: Number of votes for this option
        supplementary_text:
          type: string
          nullable: true
          description: Additional descriptive text for the option
      required:
      - type_of
      - id
      - markdown
      - processed_html
      - position
      - poll_votes_count
    Poll:
      description: A poll (question) belonging to a survey or article
      type: object
      properties:
        type_of:
          type: string
          enum:
          - poll
          description: Resource discriminator
        id:
          type: integer
          format: int64
        prompt_markdown:
          type: string
          nullable: true
          description: Question text in markdown
        prompt_html:
          type: string
          nullable: true
          description: Question text rendered as HTML
        poll_type_of:
          type: string
          enum:
          - single_choice
          - multiple_choice
          - scale
          - text_input
          description: 'Poll question type: single_choice, multiple_choice, scale, or text_input'
        position:
          type: integer
          format: int32
          description: Display order within the survey
        poll_votes_count:
          type: integer
          format: int32
          description: Total number of votes across all options
        poll_skips_count:
          type: integer
          format: int32
          description: Number of users who skipped this poll
        poll_options_count:
          type: integer
          format: int32
          description: Number of options in this poll
        scale_min:
          type: integer
          format: int32
          nullable: true
          description: Minimum value for scale polls
        scale_max:
          type: integer
          format: int32
          nullable: true
          description: Maximum value for scale polls
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        poll_options:
          type: array
          items:
            $ref: '#/components/schemas/PollOption'
          description: The available options for this poll
      required:
      - type_of
      - id
      - prompt_markdown
      - prompt_html
      - poll_type_of
      - position
      - poll_votes_count
      - poll_skips_count
      - poll_options_count
      - created_at
      - updated_at
      - poll_options
    PollTextResponse:
      description: Representation of a free-text response to a text-input poll
      type: object
      properties:
        type_of:
          type: string
          enum:
          - poll_text_response
          description: Resource discriminator
        id:
          type: integer
          format: int64
        poll_id:
          type: integer
          format: int64
        user_id:
          type: integer
          format: int64
        user_email:
          type: string
          format: email
        text_content:
          type: string
        session_start:
          type: integer
          format: int32
        created_at:
          type: string
          format: date-time
      required:
      - type_of
      - id
      - poll_id
      - user_id
      - user_email
      - text_content
      - session_start
      - created_at
    Survey:
      description: Representation of a survey
      type: object
      properties:
        type_of:
          type: string
          enum:
          - survey
          description: Resource discriminator
        id:
          type: integer
          format: int64
        title:
          type: string
        slug:
          type: string
        survey_type_of:
          type: string
          enum:
          - community_pulse
          - industry
          - fun
          description: Survey category
        active:
          type: boolean
          nullable: true
          description: Whether the survey is currently active
        display_title:
          type: boolean
          description: Whether to show the title to respondents
        allow_resubmission:
          type: boolean
          description: Whether users can submit multiple times
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - type_of
      - id
      - title
      - slug
      - survey_type_of
      - display_title
      - allow_resubmission
      - created_at
      - updated_at
    PollVote:
      description: Representation of a single poll vote cast by a user
      type: object
      properties:
        type_of:
          type: string
          enum:
          - poll_vote
          description: Resource discriminator
        id:
          type: integer
          format: int64
        poll_id:
          type: integer
          format: int64
        poll_option_id:
          type: integer
          format: int64
        user_id:
          type: integer
          format: int64
        user_email:
          type: string
          format: email
        session_start:
          type: integer
          format: int32
        created_at:
          type: string
          format: date-time
      required:
      - type_of
      - id
      - poll_id
      - poll_option_id
      - user_id
      - user_email
      - session_start
      - created_at
    SurveyWithPolls:
      description: Representation of a survey including its polls and poll options
      allOf:
      - $ref: '#/components/schemas/Survey'
      - type: object
        properties:
          polls:
            type: array
            items:
              $ref: '#/components/schemas/Poll'
            description: All polls in the survey, ordered by position
        required:
        - polls
  parameters:
    pageParam:
      in: query
      name: page
      required: false
      description: Pagination page
      schema:
        type: integer
        format: int32
        minimum: 1
        default: 1
    perPageParam30to1000:
      in: query
      name: per_page
      required: false
      description: Page size (the number of items to return per page). The default maximum value can be overridden by "API_PER_PAGE_MAX" environment variable.
      schema:
        type: integer
        format: int32
        minimum: 1
        maximum: 1000
        default: 30
  securitySchemes:
    api-key:
      type: apiKey
      name: api-key
      in: header
      description: "API Key authentication.\n\nAuthentication for some endpoints, like write operations on the\nArticles API require a DEV API key.\n\nAll authenticated endpoints are CORS disabled, the API key is intended for non-browser scripts.\n\n### Getting an API key\n\nTo obtain one, please follow these steps:\n\n  - visit https://dev.to/settings/extensions\n  - in the \"DEV API Keys\" section create a new key by adding a\n    description and clicking on \"Generate API Key\"\n\n    ![obtain a DEV API Key](https://user-images.githubusercontent.com/37842/172718105-bd93664e-76e0-477d-99c4-265dda0b06c5.png)\n\n  - You'll see the newly generated key in the same view\n    ![generated DEV API Key](https://user-images.githubusercontent.com/37842/172718151-e7fe26a0-9937-42e8-96c6-333acdab9e49.png)"