This is the whole product
Every voting platform says it is easy to use. Here is ours, in 11 screenshots of the real software, with a caption under each one that is a fact read off the source code and the file it was read from — not an adjective. And because twelve flattering screenshots would just be a brochure, the three places a competitor does this in fewer steps than we do are on the page as well.
“In our case, setup would have required only a few minutes of effort from management or the Board.”
Act 1
Building the election
From an empty account to a ballot that will publish, and the parts of each screen that are decisions rather than decoration.
Every election, and only the actions its status allows

The dashboard filters on five states — all, live, scheduled, draft and closed — and every card works out what it is allowed to do from that same status rather than from a separate permissions list.
A draft or scheduled election can be edited; a live one cannot. A live one can be closed early; nothing else can. Anything not live can be deleted. So there is no menu item anywhere on this screen that would quietly change a ballot voters are already looking at — not because someone remembered to hide it, but because the card never renders it.
Read in app/(dashboard)/dashboard/dashboard-client.tsx — FilterType, and the card capability block
68 state-written starting points, and what they actually set

The library holds 68 association templates across 22 states, plus four generic ones. Each state template is a board election, a budget approval, an amendment, and in California a special assessment.
The part worth checking is what a template writes onto the election rather than into the copy. Every one of them sets the state code, the community type (association or condominium), the vote type, the verification level, the quorum, and — where the state names it separately — the share of the vote the measure has to win, which is not the same number as the quorum and used to be stored as though it were.
The state code matters most and is the least visible: a template called "Board Election (California)" that did not set California would leave the wizard's compliance step on "No state selected", and that field is create-only, so it cannot be repaired after the election is published. Read the template description before you publish — several of them tell you to change the preset quorum, because the reduced number only applies to a meeting that has already been adjourned and re-noticed.
Read in lib/vote-templates.ts — HOA_STATE_TEMPLATES and VoteTemplateConfig.stateJurisdiction
Seven question types on one screen, none of them behind a plan

Single choice, multiple choice, cumulative, yes/no, rating, ranking and open text. All seven render from one list with no tier check in it, so what you can see is what your account can use.
Cumulative is the one worth naming: it hands each member a pool of votes to spread across candidates as they like, which is what a governing document means when it says a member may cast all of their votes for one candidate. It is a question type here, not an add-on.
Read in app/(dashboard)/create/wizard/steps/content-step.tsx — QUESTION_TYPE_CONFIG
The step that cannot stop you

The wizard's rule engine has a branch for this step and it pushes nothing. Not one rule lives here. An election with nobody on the roster publishes, and it publishes free — the flat rate is charged the first time a list exists, not at publish.
That is a reversal, and the reason is written into the source: an empty roster used to be the most common publish failure, and every person who hit it had already built the whole ballot before anything mentioned it. "The manager still owes me the spreadsheet" is a normal Tuesday, not a mistake, and it is no longer a dead end.
A roster that exists and is wrong is still a blocker. Over the self-serve ceiling, the wizard stops and asks you to call.
Read in app/(dashboard)/create/wizard/validation.ts — case 1, and roster_over_self_serve
When the person with the list is not you

This generates a tokenized link. You forward it to the property manager or the secretary, they open it, upload the list, and the names land on this draft's roster. They never make an account and they never see the ballot.
The link expires after 14 days. In the wizard the arrivals merge into the list you are already looking at, so the banner points at the roster below it rather than at another page.
Read in app/api/votes/[id]/roster-request/route.ts, components/wizard/roster-request-panel.tsx
Opens on publish, and an end date is optional

The wizard opens with "start immediately" already on and the close date empty, and that combination raises nothing — the checklist reads "Opens on publish · no end date" and the publish button stays live. A board that will close the vote at the meeting does not have to invent a date to get past this screen.
The rules that fire here are the ones where a date is wrong rather than absent: a date that does not parse, a close before the start, an online cutoff later than the close. A start time that has already gone by is deliberately not one of them — publishing treats it as "open now", because refusing only ever stranded the people whose setup outlasted the start time they picked.
One more rule is neither: auto-reminders switched on with no times chosen, which would otherwise publish an election that silently never reminds anybody.
Read in app/(dashboard)/create/wizard/types.ts (initial state), validation.ts (case 2)
5 steps, four of which carry rules

The wizard is 5 steps and the rule engine runs on four of them. Design is the fifth and is hardcoded as done, because a color scheme has never been a reason to refuse to hold an election.
Continue does not validate. Since the always-visible checklist shipped, moving around the wizard is free and only Publish enforces anything — and it enforces every step at once, from one rule list, so the tracker, the step ticks, the button label and the gate cannot disagree with each other.
Read in app/(dashboard)/create/wizard/constants.ts (wizardSteps), publish-readiness.ts (VALIDATED_STEPS)
The row that says "Any time"

With an empty roster, the Voters row is labeled "Any time" and reads: "Add them now or after publishing — nothing is charged until you do." The Design row is labeled Optional and reads: "Fine to skip, or add your branding."
Both are quoted exactly, because the checklist is the one surface that has to be literally true: only rows that are not optional are counted toward the publish gate, so a row marked "Any time" cannot be silently blocking. The row still sits there unticked. It is not pretending the job is done — it is refusing to pretend the job is required.
Read in app/(dashboard)/create/wizard/publish-readiness.ts, components/wizard/publish-checklist.tsx
Act 2
Proving it before anyone sees it
The step between "I think this is right" and 148 packets in the mail.
Send yourself the real thing, 5 times, free

5 free email or text tests per election. A mailed test packet is also available and is charged like a real one, because it really is one.
A test is not a preview. It is a hidden copy of the election with you as its only voter, sent down the production path — the same subject line, the same link, the same verification code, the same ballot on your phone, the same confirmation code at the end. Every screen is identical because every screen is the same code.
It is isolated by being a separate election rather than by being filtered out of yours, so the real roster, eligible count, results, turnout, certificate and invoice never see it, and no charge can escape from it. The copy leaves behind the things that would make it a different test: your roster, your schedule, and government-ID verification, which would otherwise ask you to photograph your driver's license to proofread a ballot.
Read in lib/test-ballot.ts — TEST_BALLOT_FREE_SENDS and the copy rules
Act 3
What the member sees, and what you get back
The two screens the whole product is judged on: the one a homeowner opens on a phone in a parking lot, and the one a board looks at afterwards.
The 44-pixel decision

The verification fields — the ones every single voter types into — are 44 pixels tall with 16-pixel text. They used to be 40 and 14.
The comment in the source explains why that was worth changing: 40 pixels is under the touch-target minimum, and 14-pixel text is small enough that iOS Safari zooms the page when the field takes focus and then never zooms back. A voter on a phone would have been left pinching their way around a ballot for the rest of the session.
That is the whole argument this page is making, in one measurement. Nobody notices a ballot that does not zoom.
Read in app/(public)/v/[slug]/verify/page.tsx — VERIFY_FIELD_CLASS
Counts, participation, and both exports off one computation

Participation is votes divided by eligible voters, rounded, and capped at 100 — so a roster edited mid-election cannot produce a turnout figure above 100%, which is the kind of number that ends a board meeting early.
The spreadsheet and the report come from the same authenticated route, which computes the result once and then renders it as CSV or as PDF. They cannot disagree with each other, because there is only one count. The route is rate limited to 20 exports an hour.
Read in app/(dashboard)/dashboard/[id]/vote-detail-client.tsx, app/api/votes/[id]/export/route.ts
The other side
Where this is not the easiest one
Three things a competitor could fairly say about the screens above. We would rather you read them here than find them on a demo call.
Two clicks to the ballot. OpaVote takes one.
OpaVote emails an access code and the voter is on the ballot. vote.direct takes a second step: the link in the email consumes a single-use code, and only then does the ballot render. If you are counting taps, they win, and this page is not going to pretend otherwise.
What the second step buys is an event. Consuming that link writes a row before the ballot appears — a voter_verified entry naming the voter and the method, or voter_assisted_verified when the link was issued on their behalf by an administrator. So when someone asks afterwards how a particular ballot was reached, the answer is a record rather than a recollection, and assisted ballots can be separated from self-verified ones without anyone having to remember which was which.
If your election will never be questioned, that click bought you nothing. Buy the cheaper one.
Read in app/api/verify/link/route.ts, app/api/verify/check/route.ts
ElectionBuddy markets three steps. This is five.
Counting screens against each other is a contest we would lose and you would learn nothing from, because a wizard can always be made shorter by asking for the same things on fewer pages.
The number that decides whether you get stuck is how many rules can refuse to publish. There are 18 across the whole wizard, and on a ballot somebody has just started, three of them fire: give it a title, give each question its text, and give each choice question two real options. Everything else is a rule about a value that is wrong rather than missing.
A voter list is not one of them. The Design step has none at all. An election with no end date passes.
Read in app/(dashboard)/create/wizard/validation.ts
We are not going to tell you how many minutes it takes.
The obvious sentence to put at the top of a page like this is a signup-to-publish time. Nobody here has timed a real run with a real board and a real roster, so there is no number to publish, and inventing a plausible one would undo every fact underneath it.
The nearest thing to evidence is the sentence at the top of this page, which somebody else wrote about their own case, on a review site, with nothing to gain from it. It is worth more than any figure we could put next to a stopwatch, and it is still one association.
Not our words
What people who are not us have said
Screenshots are still our screenshots. This is the part of the page we do not control, including the size of it.
How much outside evidence there is, exactly
vote.direct has 3 public third-party reviews: one on Capterra and 2 on Trustpilot, all of them 5 out of 5. Trustpilot's profile displays a TrustScore of 3.8 rather than 5.0, even though its own histogram reads 100% five-star, because a TrustScore is a weighted average that starts a new profile near 3.7 and only moves to the real mean as reviews accumulate. Both numbers are honest; that one is theirs and we do not get to change it. 3 reviews is not a track record either, and no board should choose a voting platform on the strength of it. ElectionBuddy, Simply Voting, and OpaVote have all been running elections far longer and have the independent reviews to show for it. If review volume is your deciding factor, they win it outright and this page will not talk you out of that. What we can do is show you every review we have in full, including the parts that are critical of us, and link them so you can confirm we did not edit them.
Secure, Transparent, and Easy-to-Implement HOA Voting Solution
Anonymous reviewer, Non-Profit Organization Management. 5 out of 5 on Capterra, May 2026.
vote.direct provided a secure and genuinely anonymous voting solution at a time when our HOA urgently needed an alternative election platform. [sensitive content hidden] personally worked over a weekend to help prepare a complete proposal for our Board and answered every question clearly and patiently in non-technical language. I especially appreciated the platform’s focus on voter verification, auditability, ballot secrecy, and compliance while still keeping the process simple and affordable for the Association to implement. In our case, setup would have required only a few minutes of effort from management or the Board.
What they marked as cons: I honestly did not identify any major negatives during my experience. Because the platform offers strong security and compliance features, there is a lot of information available, so organizations unfamiliar with election terminology may initially need some guidance. Fortunately, [sensitive content hidden] was extremely helpful in walking through everything step by step.
Quoted in full and unedited. The bracketed redactions are Capterra's own: it strips personal names out of review text. Both refer to the founder.
That review is worth reading in full because of what the customer chose to lead with. They were not asked about support, and they wrote that someone at vote.direct worked over a weekend to prepare a proposal for their board and answered every question in non-technical language. It is the same claim this page makes about founder-led support, made by someone with no stake in repeating it.
A reviewer describing a mixed email-and-paper election
A Trustpilot reviewer put the mixed-ballot case plainly: "Great platform with many options for voting and a competitive price. Our election needed a mix of email and physical ballots and it served our needs well. Customer service is easy to access as a direct number is available, we got a call back an hour after leaving a voicemail which was fast" (August 2026, https://www.trustpilot.com/review/vote.direct). They were not asked about ballot channels or about the phone line; both are things they chose to lead with.
The fastest way to check any of this
Build a ballot and send yourself a test of it. The test is a real election with you as its only voter, so the screens above are the screens you get — and if something on this page is wrong, the number below reaches the person who wrote both the page and the code.