For developers

Build with Votinova

REST API, webhooks, connectors and an MCP server. Everything the web app does is also in the API: create a session, open it and get results into your stack in under five minutes.

  1. Create a credential in your workspace — two scopes, organization-wide.
  2. Make your first call: create and open a session from curl.
  3. Subscribe to a webhook and receive results as each question closes.
curl -X POST https://api.votinova.prd.atbionapps.com/public/v1/sessions \  -H "X-API-Key: vz_live_…" \  -d '{ "presentation_id": "prs_8f3k2" }' 200 OK   · X-RateLimit-Remaining: 119{  "id": "ses_71xw9",  "join_code": "482913",  "state": "LIVE"}

Every surface, one contract

Every integration derives from the same OpenAPI document. A new endpoint shows up everywhere at once.

What people build with this

Results in your CRM

Sync answers and attendance into your CRM or data warehouse the moment each question closes — a webhook tells you, no polling.

Your own reporting

KPIs, participants and results over the API with cursor pagination: build the report exactly the way your organization wants it.

Sessions from your software

Create, open and drive sessions from your backend, your internal tools or your agent — the same API this web app uses.

Built for agents

Your agent already knows Votinova

A remote MCP server with tools derived from the OpenAPI document, filtered by your credential's scopes. Plus an llms.txt so any model can find the docs.

Set up the MCP server
{  "mcpServers": {    "votinova": {      "url": "https://mcp.votinova.com/mcp",      "headers": { "Authorization": "Bearer vz_live_…" }    }  }}

Latest API changes

Changelog
  • ADDITIVE

    The participant roster now says how each person was let in: identity_seal is VERIFIED when an identity provider vouched for them, GUEST when they came through the invited-guest link, and UNVERIFIED when neither happened. Without it an integrator reading a roster of names could not tell which of them anyone had actually checked. Additive: no existing field changed. The same release finishes naming two closed domains the document was already enforcing but never said out loud: the export format (csv, xlsx) and the webhook connector (ZAPIER, POWER_AUTOMATE) — until now the only way to learn either was to send a wrong value and read the 400.

  • ADDITIVE

    Per-question results now carry the spinner wheel's spin log (spin_outcomes) and, for ordering questions, how many people put each item in each position (placement_accuracy[].counts_by_position). Both were produced internally and never published; a spinner wheel's results envelope used to arrive empty. Additive: no existing field changed.

  • ADDITIVE

    Discovery without a credential: the enforced rate limits, the webhook retry schedule and the published event catalogue, plus this changelog itself.

Quota per plan

  • PRO120 requests every 60s
  • TEAM600 requests every 60s
  • ENTERPRISE3000 requests every 60s

Your quota travels in every response (X-RateLimit-* headers).