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)"