Skip to main content

Prerequisites

Before integrating, take a minute to understand the security model. Getting this wrong leaks credentials; getting it right takes a single architectural decision up front.

What you need

Client ID & Client Secret

Issued by the VOTR team.

A backend you control

Node, Python, Go — anything that can hold a secret and call the VOTR API.

React / React Native client

Optional — only if you use the VoteNowButton SDK for in-app voting.

Node.js

Optional — for the SDK install steps (npm or yarn).

Environments

EnvironmentBase URL
Developmenthttps://api-dev.govotr.com
Productionhttps://api.govotr.com
note

Use the same client credentials only against the environment they were issued for. Development and Production credentials are not interchangeable.

Security model

VOTR uses OAuth 2.0 client-credentials authentication. The credentials grant unrestricted API access — they must stay on your backend.

Never put client credentials in your frontend

Anything bundled into a web or mobile client is readable by anyone who runs the app. A leaked client_secret allows arbitrary calls against the VOTR API on behalf of your organization. Rotate immediately if exposure is suspected.

Anti-patternCredentials in the client
frontend.ts (insecure — do not ship)
const CLIENT_ID = "184hc5luf27g";
const CLIENT_SECRET = "c1kf58bh43dnlq676j";
// Both values are bundled into the app and visible to every user.
Correct patternCredentials on the server

The client calls your backend, which holds the secrets and proxies to VOTR.

frontend.ts (safe)
async function getVotingUrl(userEmail: string, eventId: string) {
const response = await fetch("/api/voting/generate-url", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${userAuthToken}`, // your app's session token
},
body: JSON.stringify({ email: userEmail, eventId }),
});
return response.json();
}
backend.ts (safe)
// Reads CLIENT_ID / CLIENT_SECRET from env / secret manager only.
// Calls VOTR, gets a voting URL, returns *only* the URL to the client.

The core of the integration is the VOTR API: your backend calls it to look up events, submit shareholder and trade data, and generate voting URLs. The VoteNowButton SDK is an optional frontend convenience — only needed if you want to open the voting URL inside a React Native app — so the diagram below shows it as an optional client.

React / React Native

  • VoteNowButton SDK (optional)
  • User session token
  • No VOTR credentials

Your Backend

  • Holds client creds
  • Authenticates users
  • Calls the VOTR API

VOTR API

  • OAuth tokens & events
  • Voting URLs
  • Shareholder & trade intake

Your backend's responsibilities:

  1. Store credentials securely. Keep CLIENT_ID / CLIENT_SECRET in environment variables or a secret manager — never in source control.

  2. Authenticate your own users. Use your app's session, not VOTR's.

  3. Exchange & cache the OAuth token. Reuse it until roughly one minute before it expires.

  4. Call the VOTR API server-side. Look up events and submit shareholder & trade records from your backend, not the client.

  5. Authorize per event. Verify the user is allowed to access the requested event before generating a voting URL.

  6. Return only what the client needs. e.g. a voting URL — never expose tokens or credentials to the client.

A complete reference implementation is available at our github repo.