--- title: "DevPlace REST: Votes, Reactions, Bookmarks and Polls" description: "Toggle-style engagement endpoints for posts, comments, gists, projects and quizzes: vote casting and removal, emoji reactions, bookmarks and poll answers, including the X-Requested-With header rule that returns JSON instead of a redirect." language: null framework: null category: api_design tags: - devplace - api - http-api - voting - reactions - bookmarks - polls - rest - idempotency - json-api keywords: - devplace POST /votes/{target_type}/{target_uid} - devplace emoji reaction endpoint toggle - devplace bookmark endpoint - devplace poll vote api - X-Requested-With fetch json response devplace last_updated: 2026-08-12 difficulty: beginner version: "DevPlace (devplace.net), documented 2026-08" related: - conventions_and_errors.md - authentication.md - rest_posts_and_comments.md - README.md search_priority: normal status: published --- # DevPlace REST: Votes, Reactions, Bookmarks and Polls Lightweight engagement actions. The POST endpoints here are **toggles** - sending the same action again removes it. They return JSON when called with `X-Requested-With: fetch` (sent automatically by the panels below); the [Conventions & Errors](conventions_and_errors.md) page explains that header rule and the response envelope. Every endpoint follows the shared [Conventions & Errors](conventions_and_errors.md) (auth, content negotiation, pagination, status codes); see [Authentication](authentication.md) for the four ways to sign requests. ## `POST /votes/{target_type}/{target_uid}` - Cast or toggle a vote Upvote or downvote a target. Re-sending the same value removes the vote. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `target_type` | path | enum | yes | Type of content being voted on. Allowed: post, comment, gist, project, quiz. | | `target_uid` | path | string | yes | UID of the target. | | `value` | form | enum | yes | 1 to upvote, -1 to downvote. Allowed: 1, -1. | **Sample response** ```json { "net": 3, "up": 4, "down": 1, "value": 1 } ``` ## `POST /reactions/{target_type}/{target_uid}` - Toggle an emoji reaction Add or remove an emoji reaction on a target. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `target_type` | path | enum | yes | Type of content being reacted to. Allowed: post, comment, gist, project, quiz. | | `target_uid` | path | string | yes | UID of the target. | | `emoji` | form | string | yes | Any single emoji character. Re-sending the same one removes it. | **Sample response** ```json { "counts": { "\ud83d\udc4d": 2 }, "mine": [ "\ud83d\udc4d" ] } ``` ## `POST /bookmarks/{target_type}/{target_uid}` - Toggle a bookmark Save or unsave a target to your bookmarks. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `target_type` | path | enum | yes | Type of content to bookmark. Allowed: post, gist, project, news, quiz. | | `target_uid` | path | string | yes | UID of the target. | **Sample response** ```json { "saved": true } ``` ## `GET /bookmarks/saved` - View saved bookmarks Render your saved content. Returns an HTML page. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `before` | query | string | no | Pagination cursor (created_at of the last item). | > Bookmarks target posts, projects, gists, and news; see [Posts, Comments, Projects, Gists & News](rest_posts_and_comments.md). **Sample response** ```json { "items": [ { "target_type": "string", "target_uid": "UID", "type_label": "string", "title": "Title", "url": "/path", "time_ago": "2 hours ago" } ], "next_cursor": "2026-01-01T00:00:00+00:00" } ``` ## `POST /polls/{poll_uid}/vote` - Vote in a poll Cast, change, or clear your vote on a poll option. *Minimal role:* Member **Parameters** | Name | In | Type | Required | Description | |------|----|------|----------|-------------| | `poll_uid` | path | string | yes | UID of the poll. | | `option_uid` | form | string | yes | UID of the chosen option. | > You hold at most one vote per poll, and only your latest vote counts. Voting a different option replaces your previous choice; voting your current option again removes the vote. **Sample response** ```json { "question": "Best editor?", "options": [ { "uid": "OPTION_UID", "label": "Vim", "votes": 5 } ], "total": 5, "voted": "OPTION_UID" } ```