curl --request GET \
--url https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot \
--header 'Authorization: Bearer <token>'import requests
url = "https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"png": "<string>",
"width": 0,
"height": 0,
"revision": "<string>",
"elements": [
{
"id": "<string>",
"kind": "overlay",
"index": 0,
"rect": {
"x": 0.5,
"y": 0.5,
"w": 0.51,
"h": 0.51
},
"z": 123,
"label": "<string>"
}
],
"overlaps": [
{
"a": "<string>",
"b": "<string>",
"covered": 123
}
],
"warnings": [
{
"element": "<string>",
"message": "<string>",
"with": "<string>"
}
],
"coversPageText": [
{
"element": "<string>",
"text": "<string>",
"hidden": 123
}
],
"measured": [
{
"element": "<string>",
"clipped": true,
"overflowPx": 123,
"textPx": 123
}
]
}{
"error": "<string>",
"fix": "<string>"
}{
"error": "<string>",
"fix": "<string>"
}{
"error": "<string>",
"fix": "<string>"
}{
"error": "<string>",
"fix": "<string>"
}Screenshot a step
A PNG of one step as the room will see it: the slide’s page with its cards, text, shapes and images on it, or the full-screen poll the way the audience screen draws it. Beside the picture come the numbers: every element’s rect, the pairs that overlap, warnings for a card too small to read or over another card or text box, coversPageText, the PDF page’s own words a card or text box hides, and measured, each card and text box as the drawing measured it: cut off by its box, and how high its biggest answer text is drawn. Send annotate to have every element’s box and name drawn on the picture, the clashing ones in red and the hidden words tinted; element to crop to one element, the way Paper screenshots one node; scale 2 for twice the pixels. Rendered on the server in a real browser, so the first look takes a few seconds; the same step at the same revision comes straight back. Through MCP the image arrives as an image; over HTTP, read png as a data URL or send Accept: image/png for the bytes.
Needs the decks:read scope.
curl --request GET \
--url https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot \
--header 'Authorization: Bearer <token>'import requests
url = "https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://test.polltheroom.com/api/v1/decks/{id}/steps/{index}/screenshot")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"png": "<string>",
"width": 0,
"height": 0,
"revision": "<string>",
"elements": [
{
"id": "<string>",
"kind": "overlay",
"index": 0,
"rect": {
"x": 0.5,
"y": 0.5,
"w": 0.51,
"h": 0.51
},
"z": 123,
"label": "<string>"
}
],
"overlaps": [
{
"a": "<string>",
"b": "<string>",
"covered": 123
}
],
"warnings": [
{
"element": "<string>",
"message": "<string>",
"with": "<string>"
}
],
"coversPageText": [
{
"element": "<string>",
"text": "<string>",
"hidden": 123
}
],
"measured": [
{
"element": "<string>",
"clipped": true,
"overflowPx": 123,
"textPx": 123
}
]
}{
"error": "<string>",
"fix": "<string>"
}{
"error": "<string>",
"fix": "<string>"
}{
"error": "<string>",
"fix": "<string>"
}{
"error": "<string>",
"fix": "<string>"
}Authorizations
An API key from Settings › API, sent as Authorization: Bearer ptr_…. Shown once when made; only a hash is stored.
Path Parameters
The deck's id
1The step's index; the join screen (0) has no picture
1 <= x <= 9007199254740991Query Parameters
1 (the default) for 1600 pixels wide, 2 for 3200
1 <= x <= 2Crop to this element, as get_step names it: "overlay 0", "text 1"
^(overlay|text|shape|image) \d+$Draw every element's box and name on the picture, clashes in red
Response
OK
The image, as a data URL
Pixels
-9007199254740991 <= x <= 9007199254740991Pixels
-9007199254740991 <= x <= 9007199254740991The deck's revision this picture shows
Show child attributes
Show child attributes
Pairs of elements that sit on top of each other; empty when nothing overlaps
Show child attributes
Show child attributes
What on this slide will not read well: a card too small to read, a card or text box over another
Show child attributes
Show child attributes
Cards and text boxes over the PDF page's own text. Words drawn inside a picture on the page are pixels, not text, so look at the picture for those
Show child attributes
Show child attributes
Each card and text box as the drawing measured it after paint. How small a card can go depends on its look, so this, not a fraction, says whether it fits
Show child attributes
Show child attributes