Q&A API
Read, post, moderate, and answer audience questions.
Manage the audience questions asked during a session. All endpoints require the standard authentication headers. Write endpoints require the qa:write scope; the read endpoint requires qa:read.
Questions are stored per session, so sessionId is required on every call. The session must have hasLiveQA set to true before attendees can reach the Q&A - set that with /upsertSession.
What this API cannot do
It cannot upvote. Attendees upvote questions in the app, and nothing you send here can change a question’s vote count. You can post, edit, approve, reject, answer and delete questions.
A question has one status
Every question is in exactly one of four states, and you set it with a single status value:
status |
Meaning |
|---|---|
pending |
Asked, not yet moderated. The default for a new question. |
approved |
Visible to the audience. |
rejected |
Hidden by a moderator. |
answered |
Answered on stage. Implies approved, and requires answer text. |
Behind the scenes a question stores these as separate on/off flags, and it is possible for a careless integration to mark one both approved and rejected. This API will not let that happen: it only accepts status, and sets the flags for you. Sending approved, rejected or answered directly returns an error pointing you at status.
Reads give you status directly, so you never have to work it out.
GET /getQuestions
Returns a session’s questions, highest-voted first. Requires qa:read.
| Query parameter | Required | Description |
|---|---|---|
sessionId |
Yes | The session whose questions you want. |
[
{
"questionId": "q7",
"documentId": "q7",
"sessionId": "s42",
"question": "How does this scale past 10k attendees?",
"answer": "We shard by event, so it scales linearly.",
"status": "answered",
"score": 31,
"voterCount": 31,
"approved": true,
"rejected": false,
"answered": true
}
]
Questions come back most-upvoted first.
POST /upsertQuestion
Creates a question when questionId is omitted, edits one when it is supplied. Requires qa:write.
| Field | Type | Required on create | Notes |
|---|---|---|---|
sessionId |
string | Yes | Must reference an existing session. Required on edit too. |
questionId |
string | - | Omit to create. |
question |
string | Yes | Max 500 characters. |
answer |
string | No | Max 500 characters. Required when status is answered. |
status |
enum | No | pending, approved, rejected or answered. New questions default to pending. |
Marking a question answered with no answer text - neither in this request nor already saved - is rejected, because attendees would see it flagged as answered with nothing there.
Questions you post through the API start with no upvotes and no attendee attached to them, since they did not come from someone in the audience.
Example: approve and answer in one call
curl -X POST "https://api.event-vault.com/upsertQuestion" \
-H "x-api-key: $EV_API_KEY" \
-H "x-client-id: $EV_CLIENT_ID" \
-H "x-event-id: $EV_EVENT_ID" \
-H "x-timestamp: $(python3 -c 'import time;print(int(time.time()*1000))')" \
-H "Content-Type: application/json" \
-d '{
"sessionId": "s42",
"questionId": "q7",
"status": "answered",
"answer": "We shard by event, so it scales linearly."
}'
POST /deleteQuestion
Requires qa:write.
{ "sessionId": "s42", "questionId": "q7" }
Deletion is permanent - the same as deleting a question in the console. There is no recycle bin for questions, so reject it instead if you might want it back.