← Back to the User Guide

The WeEngage API

How the WeEngage API works: create an API key, read your sessions, responses, and AI insights from another system, and the privacy rules that carry over from the app.

Getting started

What the API is for

The WeEngage API lets another system read what happened in your sessions, the questions you asked, the responses that came in, and the AI insights you generated, and run sessions as a facilitator: create them, add and show questions, and end them. Use it to pull session data into a reporting tool or data warehouse, or to start and run WeEngage sessions from inside another application.

API access is switched on per account for enterprise customers. If API access in your Profile says it is not enabled yet, email support@weengage.app and tell us what you are building. Every call is scoped to your own account: you can read your sessions and nobody else's.

Create an API key

  1. Open your Profile from the dashboard and find API access.
  2. Give the key a short name that says where it will be used, such as “Reporting sync”, and click Create key.
  3. Copy the key right away. It is shown once and never again. If you lose it, revoke it and create a new one.

Keep the key on a server or in a secrets manager, not in a web page or a shared document. Anyone who has it can read your sessions. You can have up to five active keys, and revoking one takes effect immediately.

Make your first call

Every request goes to https://weengage.app/api/v1 and carries the key in a header. The quickest check that a key works:

curl https://weengage.app/api/v1/me \
  -H "Authorization: Bearer we_your_key_here"

You get back your account email, your plan, and the name of the key you used. The header X-API-Key: we_your_key_here works the same way if your tool prefers it.

All responses are JSON. Dates are ISO 8601 in UTC, for example 2026-09-16T14:03:00.000Z.

Endpoints

List your sessions

GET /api/v1/sessions returns your sessions, newest first, as summaries:

{
  "sessions": [
    {
      "id": "…",
      "name": "Q3 retrospective",
      "code": "K7M2PQ",
      "sessionType": "retrospective",
      "status": "closed",
      "createdAt": "…", "scheduledAt": null, "startedAt": "…", "closedAt": "…",
      "closeReason": "manual",
      "participantCount": 9,
      "questionCount": 5,
      "responseCount": 41
    }
  ],
  "total": 128,
  "limit": 50,
  "offset": 0
}

Filter with ?status=scheduled, ?status=active, or ?status=closed. Page with limit (up to 200) and offset.

One session and its questions

GET /api/v1/sessions/{id} accepts a session id or its six-character join code and returns the session with its questions in order. Each question carries its type, options, whether it has been shown to participants, whether results have been shown to participants, and two flags, hasInsight and insightSharedWithGroup, that tell you whether the insights endpoint has anything for it.

GET /api/v1/sessions/{id}/questions returns only the questions.

Responses

GET /api/v1/sessions/{id}/responses returns every response in the session. Add ?questionId=… for one question.

{
  "responses": [
    {
      "id": "…",
      "questionId": "…",
      "author": "Priya",
      "anonymous": false,
      "responseText": "We shipped on time but burned out doing it.",
      "selectedOptions": [],
      "rankedOptionIds": [],
      "selectedOptionIds": [],
      "stackedUnder": null, "stackLabel": null, "tagIds": [],
      "createdAt": "…", "updatedAt": "…"
    }
  ],
  "declinedCounts": { "…question id…": 2 }
}

The fields that don't apply to a question's type come back empty. Which field holds the answer depends on the type: responseText for open-ended, brainstorm, word cloud, start/stop/continue, and laddering questions; selectedOptions for polls and scales; rankedOptionIds for ranking; selectedOptionIds for knowledge checks and dot voting.

AI insights

GET /api/v1/sessions/{id}/insights returns the insights generated for the session: one entry for each question that has any, plus the conversation-level insight.

For each, insight is the version generated for you as the facilitator and sharedWithGroup is the participant version you chose to share, if you did. Either can be null. The insight objects are exactly what you saw in the app, including the coverage stamp that records how many responses the model had seen when it ran.

Creating and running sessions

Create a session

POST /api/v1/sessions creates a session with its questions, all queued until you show them. It returns the session and its join link.

{
  "name": "Q3 retrospective",
  "sessionType": "Team Building",
  "context": "Looking back at the quarter before we plan the next one.",
  "scheduledAt": "2026-10-02T14:00:00Z",
  "plannedDurationMinutes": 45,
  "questions": [
    { "text": "What went well?", "type": "open" },
    { "text": "Where should we focus next?", "type": "poll", "options": ["Hiring", "Tooling", "Process"], "allowMultiple": true },
    { "text": "Rank these by urgency", "type": "ranking", "options": ["Hiring", "Tooling", "Process"] }
  ]
}
  • sessionType is required and must be one of the types the app offers; the error message lists them.
  • Leave out scheduledAt to create a session that is live right away. With it, the session waits under Upcoming Sessions until its time, or until you call start.
  • Each question takes the same fields as the app's question form: text, type, options (for poll, ranking, knowledge, dot voting), allowMultiple (poll), correctOptionIds (knowledge, as option positions starting at 0), allowAnonymous, hideResponses, voteBudget (dot voting), ladderConfig, and a private note.
  • Types: open, poll, brainstorm, ranking, knowledge, wordcloud, scale, dotvote, startstopcontinue, ladder, whiteboard.

The response is the session object with a joinUrl field added. GET /api/v1/sessions/{id}/join-link returns the code and link again later.

Run a session

Call What it does
POST /sessions/{id}/start Starts a scheduled session now, or one waiting for you at its start time
POST /sessions/{id}/questions Adds a question. Send "show": true to show it immediately in a running session
PATCH /sessions/{id}/questions/{qid} Edits a question that has not been shown yet (send the full question), or only its note at any time
DELETE /sessions/{id}/questions/{qid} Removes a question that has not been shown yet
POST /sessions/{id}/questions/order Sets the full order with {"questionIds": [...]}. Questions already shown keep their place
POST /sessions/{id}/questions/{qid}/show Shows the question to participants
POST /sessions/{id}/questions/{qid}/show-responses Shows the responses to participants
POST /sessions/{id}/questions/{qid}/close Stops accepting responses
POST /sessions/{id}/pause and /resume Pauses or resumes responding
POST /sessions/{id}/end Ends the session and keeps its record. Send {"keepWhiteboard": false} to drop unsaved drawings
PATCH /sessions/{id} Edits a scheduled session's name, context, type, time, or length. The session note can change at any time
DELETE /sessions/{id} Deletes a scheduled session, or an ended one that is still within its retention window

Show, show-responses, and close are one-way, exactly as in the app. A running session cannot be deleted; end it first. Question and session objects come back in the same shape the read endpoints use.

Plan rules apply through the key just as they do in the app: a Free account has a monthly session limit, cannot schedule ahead, and cannot use Pro question types. Those come back as 402 with a code you can show to the user.

Rules and limits

What the API never returns

The same privacy rules that apply in the app apply here.

  • Anonymous responses have no author. A response submitted anonymously comes back with author: null and anonymous: true. So does every response to a ranking, knowledge check, word cloud, scale, or dot voting question, because those types never attribute responses to anyone, anywhere in WeEngage.
  • Declines are counted, not listed. A participant who chose “decline to respond” is left out of the responses list and shows up only in declinedCounts, so your totals match what you see in the app.
  • Deleted sessions are gone. A session you delete disappears from the API at the same moment it leaves your dashboard.
  • Join links are returned only where you ask for them. The create response and the join-link endpoint carry the link; no other response does, and the underlying join token is never returned.

Rate limits and errors

Each key may make 120 requests per minute and 10,000 per day. Past either limit you get a 429 with a Retry-After header saying how many seconds to wait.

Status Meaning
401 No key, or a key that is revoked or unknown.
403 API access has been switched off for the key's account.
402 The account's plan does not allow this (session limit, scheduling, or a Pro question type).
404 No such session or question for this account, or no such endpoint.
429 Rate limit reached. Wait for Retry-After seconds.

Every error body is JSON with an error message written for a person to read.

Coming later

Participant-side endpoints (join and respond from another app), live updates, insights on demand, and an MCP server so AI assistants can work with WeEngage directly, are planned next. If you are building against the API and need one of these, email support@weengage.app and say what you are building.