June 18, 2026 · 10 min read

Wie wir unsere wöchentliche Retro mit der PollsLive-API auf Autopilot gestellt haben

Eine Schritt-für-Schritt-Anleitung für Entwickler: eine Retro-Umfrage erstellen, eine Live-Session öffnen und dann Ergebnisse samt CSV abrufen - alles aus einem kleinen Node-Skript per Cron. Echte /api/v1-Endpunkte, echte Payloads.

By Maya Okafor · Platform engineer·DevelopersHow-toTeams & meetings

Ich bin Platform Engineer, und jeden Freitag habe ich früher zehn Minuten damit verbracht, dasselbe Retro-Deck von Hand zu bauen. Dieselben fünf Fragen, andere Woche. Genau die Art Aufgabe, die ein Skript erledigen sollte. Also habe ich das Ganze auf die PollsLive-API und einen Cron-Job umgestellt - die Umfrage erstellt sich jetzt selbst, eine Live-Session öffnet sich automatisch, und nach dem Standup landet eine CSV in unserem Slack. Hier ist genau, wie das geht, mit den echten Endpunkten und Payloads.

Tip

Du musst kein Technik-Profi sein, um dieser Anleitung zu folgen. Jeder Schritt nutzt normale Buttons in PollsLive - kein Code, keine App-Installation für dein Publikum.

Auth: ein einziger Bearer-Token

Ich habe in Studio → Developers einen Workspace-API-Key erzeugt (sie sehen aus wie `plv_live_…`) und ihn in die Umgebung des Skripts gelegt. Jede Anfrage ist einfach ein Bearer-Token - kein OAuth-Tanz für Server-zu-Server-Nutzung.

auth
# Base URL for all calls
export POLLSLIVE_API=https://pollslive.com/api/v1
export POLLSLIVE_KEY=plv_live_xxxxxxxxxxxxxxxxxxxx

# Every request carries the key as a Bearer token:
#   Authorization: Bearer $POLLSLIVE_KEY
# Rate limit: 120 requests/min per key (HTTP 429 if you exceed it).

Schritt 1 - Die Retro-Umfrage erstellen

Eine Umfrage ist ein typisiertes Deck: `content.questions` ist ein Array von Slides, jedes mit einem `kind`-Diskriminator. Für die Retro nutze ich eine scale, ein als Cloud gerendertes open_ended und ein multiple_choice, um über den Fix abzustimmen. `POST /polls` mit `renderingMode: "LIVE"` gibt mir einen Entwurf zurück.

POST /polls
curl -sS -X POST "$POLLSLIVE_API/polls" \
  -H "Authorization: Bearer $POLLSLIVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Weekly retro - week of Jun 16",
    "renderingMode": "LIVE",
    "content": {
      "questions": [
        {
          "id": "health",
          "kind": "scale",
          "text": "How healthy did this sprint feel?",
          "min": 1, "max": 5,
          "minLabel": "Rough", "maxLabel": "Great"
        },
        {
          "id": "blockers",
          "kind": "open_ended",
          "text": "What slowed us down this sprint?",
          "render": "cloud",
          "maxLength": 120
        },
        {
          "id": "fix",
          "kind": "multiple_choice",
          "type": "single",
          "text": "What should we fix first next sprint?",
          "options": [
            { "id": "ci",       "label": "Stabilise the CI pipeline" },
            { "id": "tickets",  "label": "Tighter ticket acceptance criteria" },
            { "id": "wip",      "label": "Cap WIP and reviews SLA" },
            { "id": "meetings", "label": "Trim the meeting load" }
          ]
        }
      ]
    }
  }'

Die `201`-Antwort verpackt die Umfrage in einer `data`-Hülle - ich behalte `data.id` für den Rest des Ablaufs und `data.accessPin` / `data.shareUrl` für die Beitrittsdetails:

201 Created
{
  "data": {
    "id": "poll_9aZ2kP",
    "slug": "weekly-retro-jun-16",
    "title": "Weekly retro - week of Jun 16",
    "renderingMode": "LIVE",
    "isPublished": false,
    "accessPin": "6098",
    "shareUrl": "https://pollslive.com/p/weekly-retro-jun-16",
    "createdAt": "2026-06-16T08:00:11.204Z"
  }
}

Schritt 2 - Veröffentlichen, dann eine Live-Session öffnen

Das Veröffentlichen erstellt einen Snapshot des Inhalts, damit er sicher präsentiert werden kann. Ein `PATCH /polls/{id}` mit `publish: true` erledigt das; dann startet `POST /sessions` die Presenter-Session und gibt die Beitritts-PIN sowie einen einmaligen `hostToken` zurück (das Host-Authority-Secret - es wird nur beim Erstellen zurückgegeben, also speichere ich es sofort).

PATCH /polls/{id} → POST /sessions
# Publish the draft
curl -sS -X PATCH "$POLLSLIVE_API/polls/poll_9aZ2kP" \
  -H "Authorization: Bearer $POLLSLIVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "publish": true }'

# Open a presenter-paced live session
curl -sS -X POST "$POLLSLIVE_API/sessions" \
  -H "Authorization: Bearer $POLLSLIVE_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "pollId": "poll_9aZ2kP", "pace": "PRESENTER" }'
# → { "data": { "id": "ses_4dF1", "pin": "6098",
#       "joinUrl": "https://pollslive.com/join/6098",
#       "hostUrl": "https://pollslive.com/host/ses_4dF1",
#       "hostToken": "hst_…", "status": "LOBBY" } }

Mein Cron postet die `joinUrl` und PIN eine Minute vor dem Standup in den Team-Channel. Das Team scannt, und die Slides, die ich im Code gebaut habe, sind genau das, was sie sehen - hier ist das Live-Ergebnis der `health`-Slide, sobald alle geantwortet haben:

Live scale
Join at the PIN 6098

Wie gesund hat sich dieser Sprint angefühlt? (1 = mühsam, 5 = großartig)

5 - Großartig11% · 1
4 - Gut22% · 2
3 - Okay22% · 2
2 - Mühsam33% · 3
1 - Schlecht11% · 1
Die Slide, die ich in JSON definiert habe, live gerendert - kein manuelles Deck-Bauen.

Schritt 3 - Nach dem Standup Ergebnisse und eine CSV abrufen

Wenn die Session endet, gibt `GET /polls/{id}/results` die Auswertungen zurück - `totalVotes`, eine `voteCounts`-Map für Choice-Slides und ein `slides[]`-Array mit Aggregaten pro Typ (Skalen-Durchschnitte, gruppierter Freitext usw.).

GET /polls/{id}/results
curl -sS "$POLLSLIVE_API/polls/poll_9aZ2kP/results" \
  -H "Authorization: Bearer $POLLSLIVE_KEY"

{
  "data": {
    "pollId": "poll_9aZ2kP",
    "title": "Weekly retro - week of Jun 16",
    "closed": true,
    "totalVotes": 9,
    "voteCounts": { "ci": 4, "tickets": 3, "wip": 2, "meetings": 0 },
    "slides": [
      { "slideId": "health", "kind": "scale", "average": 2.9 },
      { "slideId": "blockers", "kind": "open_ended", "responseCount": 14 },
      { "slideId": "fix", "kind": "multiple_choice",
        "optionCounts": { "ci": 4, "tickets": 3, "wip": 2, "meetings": 0 } }
    ]
  }
}

Fürs Archiv streamt `GET /polls/{id}/export` eine RFC-4180-CSV (Slide-Nummer, Frage, Typ, Antwort-Label, Anzahl/Wert). Ich speichere sie und hänge sie an die Slack-Nachricht. Der ganze Schritt nach dem Standup ist eine kleine Funktion:

summarise.mjs (Node 18+)
const API = process.env.POLLSLIVE_API;
const KEY = process.env.POLLSLIVE_KEY;
const auth = { Authorization: `Bearer ${KEY}` };

export async function summariseRetro(pollId) {
  const res = await fetch(`${API}/polls/${pollId}/results`, { headers: auth });
  if (res.status === 429) throw new Error("rate_limited"); // back off + retry
  if (!res.ok) throw new Error(`results ${res.status}`);
  const { data } = await res.json();

  const winner = Object.entries(data.voteCounts)
    .sort((a, b) => b[1] - a[1])[0];

  // Grab the CSV for the archive
  const csv = await fetch(`${API}/polls/${pollId}/export`, { headers: auth })
    .then((r) => r.text());

  return {
    health: data.slides.find((s) => s.slideId === "health")?.average,
    topFix: winner?.[0],
    voters: data.totalVotes,
    csv,
  };
}

Das war's. Das Retro-Deck baut sich selbst, die Session öffnet sich pünktlich, und die Zusammenfassung plus CSV werden automatisch gepostet. Ich habe meine zehn Freitagsminuten zurück, und das Format ist jede Woche identisch - genau das, was man von einer Retro will.

Das Schönste daran: Die Slides, die ich in JSON beschreibe, sind dieselben Slides, die das Team sieht und über die es abstimmt. Kein Auseinanderdriften zwischen 'was das Skript gebaut hat' und 'was wir durchgeführt haben'.

Die vollständige Endpunkt-Referenz und die Schemas stehen in der interaktiven API-Referenz, und der erzählerische Schnellstart steht im Entwicklerleitfaden. Als Nächstes auf meiner Liste: Webhooks, damit die Slack-Zusammenfassung in dem Moment ausgelöst wird, in dem die Session endet, statt nach einem Timer - und genau das deckt der Webhook-Bericht ab.

Tip

Nutze einen Cron-Job, um das Retro-Deck der letzten Woche zu klonen und automatisch einen frischen Link zu veröffentlichen.

PollsLive Studio dashboard with poll list, left nav, and Create buttons.
Studio is your home for every poll you have created.
Results panel with stat tiles, breakdown by question, and export buttons.
The Results tab shows every answer and export options.

No-Code-Alternative: wiederkehrende Umfragen ohne Neuaufbau.

Entwickle auf PollsLive - erstelle Umfragen, führe Live-Sessions durch, rufe Ergebnisse ab und empfange Webhooks aus deinem eigenen Code.

Lies die Entwicklerdokumentation