The election package contains all of the information that defines an election. VxAdmin is configured by inserting a USB drive and selecting an election package from the drive.
After VxAdmin is configured, the election package can then be digitally signed and exported onto a USB drive in order to configure VxScan, VxCentralScan, and VxMark. The digital signature verifies that the election package is legitimate. The other devices require that the signature is present. As a result, an election package from outside the system cannot be used to directly configure VxScan, VxCentralScan, or VxMark.
The election package is a zip archive (a .zip
file). The zip archive contains 6 files:
Election Definition (election.json
)
App Strings (appStrings.json
)
Audio IDs (audioIds.json
)
Audio Clips (audioClips.jsonl
)
System Settings (systemSettings.json
)
Metadata (metadata.json
)
The election definition file includes the information that defines the election and ballots, including but not limited to definitions for contests, ballot styles, precincts, parties, multi-lingual ballot translations, and ballot layouts. The system accepts two formats - the VxSuite Election Definition format or the Ballot Definition CDF. When using the Ballot Definition CDF, some features are not available.
The election definition file is required to be present in the election package.
The app strings file contains all voter-facing strings in the user interface and their translations. For example, at the beginning of the voter flow in VxMark there is a button labelled, by default, "Start Voting." If the voter has set VxMark to another language, however, the button will display the translation for that language specified in the app strings file. Additionally, the default English text can be overridden by specifying a different English value in the app strings file.
In the case of specifying a Spanish translation and overriding the English translation for "Start Voting", which has an internal key of buttonStartVoting
, the following values and overall structure would appear in the app strings file:
Notes:
Voter-facing strings that appear on ballots (contest names, candidate names, the name of the jurisdiction, etc.) are not included in the app strings file because they are already included in the election definition.
The language codes in the app strings file are the IETF language tags for supported VxSuite languages: English, Spanish, Simplified Chinese, and Traditional Chinese.
The keys for the various user interface app strings (e.g. buttonStartVoting
) are defined in VxSuite's app strings catalog.
The app strings file is optional. If not provided, default English strings will be used.
The audio IDs file is a JSON file structured identically to the app strings file except that instead of containing text values for each voter string, it contains audio IDs for each voter string. Each audio ID corresponds to an entry in the audio clips file.
Each row of the audio clips file contains one audio clip with relevant metadata. The audio itself appears as an MP3 file encoded in base 64. For example, a row representing an audio clip for the "Start Voting" button would appear as:
Together, the two files allow specifying audio playback for any text read to a voter in audio mode, including both non-English translations and English overrides.
The audio IDs and audio clips files are optional. If they are not provided, audio playback will be disabled.
The system settings file contains settings which are not specific to an election definition but do impact machine behavior.
Authentication Settings
arePollWorkerCardPinsEnabled
- When set to true
, poll worker cards are created with PINs which are then required when authenticating.
inactiveSessionTimeLimitMinutes
- Sets the number of minutes after which machines automatically lock due to inactivity.
numIncorrectPinAttemptsAllowedBeforeCardLockout
- Sets the number of times that a PIN can be entered incorrectly before the user has to wait extra time to retry.
overallSessionTimeLimitHours
- Sets the maximum number of hours for any session, regardless of activity.
startingCardLockoutDurationSeconds
- Sets the number of seconds that the user is locked out from retrying a PIN after the number of failed attempts specified by numIncorrectPinAttemptsAllowedBeforeCardLockout
. Each subsequent failed attempt triggers a lockout double the length of the previous lockout.
Scanning Thresholds
definite
- Specifies the percentage of a bubble that needs to be filled in for the tabulators to consider it a mark.
writeInTextArea
- Specifies the percentage of the write-in area that needs to be filled in for the tabulators to consider it a write-in. This is only relevant for jurisdictions that allow unmarked write-ins i.e write-ins without an accompanying mark.
Adjudication Reasons
precinctScanAdjudicationReasons
- Specifies the reasons that a ballot scanned at VxScan should be flagged for adjudication. Supported reasons are overvotes, undervotes, blank ballots, or unmarked write-ins.
centralScanAdjudicationReasons
- Specifies the reasons that a ballot scanned at VxCentralScan should be flagged for adjudication. Supported reasons are overvotes, undervotes, blank ballots, or unmarked write-ins.
disallowCastingOvervotes
- When set to true
, scanners will always reject overvoted ballots. When set to false
, VxScan will allow a voter to choose whether to reject or cast an overvoted ballot, and VxCentralScan will allow an election manager to choose whether to reject or tabulate an overvoted ballot.
allowOfficialBallotsInTestMode
- When set to true
, official ballots will not be rejected in test mode. The setting is for jurisdictions where testing must take place on official ballots.
Other
precinctScanEnableShoeshineMode
- When set to true
, VxScan will run in "shoeshine mode," which will scan the same ballot repeatedly. Instead of ejecting the ballot after scanning it, VxScan will move it back to the input tray and scan it again. This mode is used only for internal testing and certification testing.
castVoteRecordsIncludeOriginalSnapshots
- When set to true
, scanners will include "original" snapshots in the CVR export for each ballot. This includes extra information about the marks on the ballot before contest rules are applied as specified in the CVR CDF. This extra information increases the size of the CVR export, degrading performance.
castVoteRecordsIncludeRedundantMetadata
- When set to true
, scanners will include election and system metadata in each ballot's CVR as specified in the CVR CDF, rather than just including it once for the entire export. This extra information increases the size of the CVR export, degrading performance.
disableVerticalStreakDetection
- Disables the warning when streaks are detected when scanning ballots (which indicates that the scanner needs to be cleaned). Used as a failsafe in case of erroneous warnings.
The system settings file is optional. If not provided, the following default settings will be used:
The metadata file is a JSON file that contains a single key, version
. In the current software version, the value will only ever be "latest"
. In other words, the metadata file is a JSON file with the contents:
In future software versions, the "version"
value will be used to differentiate versions of the election package that correspond to different software versions. For example, if a user flow is updated, a new app string may be added and the "version"
value will indicate which app strings to expect.
There are two hashes for each election which are both critical to operation and security of each election.
The ballot hash is the SHA256 hash of the election definition file and represents a snapshot of all election-specific data which determines the ballot, including contest definitions and ballot layout. Ballots must include a machine-readable version of the ballot hash (e.g. a QR code or a pattern of timing marks). When a ballot is scanned, the scanner checks to make sure the ballot has the expected ballot hash. The ballot hash from the ballot must match the ballot hash from the scanner's configured election definition.
If any election content changes, the ballot hash will change, meaning the system will consider it to be a new election definition, and any ballots with a different ballot hash will not scan. The system's strict checking of the ballot hash prevents situations where a change to the election definition leads to ballots being miscounted (for example, if the order of two candidates is swapped). As a result, any changes to the election definition require reprinting all ballots.
The election package hash is the SHA256 hash of the entire election package, which includes both the election definition and all other files. The election package hash is displayed on screen to election managers and system administrators. It allows the user to ascertain which election package was used to configure a machine. The election package hash is not used during ballot scanning.
For example, imagine that an election administrator wants to change the audio clip for candidate's name. The audio clip is not a part of the election definition but it is a part of the election package, so the ballot hash remains the same while the election package hash changes. The election administrator can reconfigure VxMark with an updated election package but does not have to reprint ballots.
The election ID shown on screen and included in printed reports contains a shortened version of both the ballot hash and the election hash in the format: {ballot hash}-{election hash}
. For example, with ballot hash 083e2e0afbb19191a4d2850562ddef050ff860b0d61acee15d3bb26954932941
and election hash db5c379b71accbf991e42ab23d26202f88b2539b6c69b814a0d3c8dc9f4072dc
, the election ID would be: 083e2e0-db5c379
. This enables identification of both the specific election package and election definition that a machine is configured with.
The VxSuite Election Definition is a data format for defining an election that is specific to VxSuite. It is a JSON file which defines the essential features of an election - metadata, contests, parties, precincts, districts, ballot styles, candidates, and more. In addition to defining that basic structure of the election, the format contains translations for any text which may appear on the ballots and ballot layouts to map the bubbles on each ballot to contest options.
The Election
entity is the top-level entity that contains all other entities.
The ballot layout entity includes basic information about the physical ballots used for the election.
The paperSize
attribute accepts the following valid options:
The metadataEncoding
attribute must be "qr-code".
Each ballot style corresponds to a single- or multi-sheet ballot. The contests on a ballot style are determined by its associated districts - every contest belonging to an associated district is considered a part of the ballot style. A ballot style may be used in multiple precincts, one ballot style might correspond to multiple ballot PDFs that have identical contest layouts but different precinct labels.
There are two types of contests - candidate contests and yes-no contests. Both types share core attributes:
One and only one county is associated with each election.
Districts are used to define levels at which a contest takes place. For example, an election may have districts defined for the state, county, town, and ward levels. Different contests can be associated with each of those levels.
Parties are used in the data model either to associate candidates with a party, associate ballot styles with a party for a primary, associate contests with a party for a primary
The ballotStrings
object contains the translations for any text which may appear on the ballot. The text falls into one of two categories: instructional text or election-specific text.
Examples of instructional ballot text include:
"To vote, completely fill in the oval next to your choice."
"Vote for up to 3",
"Official Absentee Ballot"
The language-specific strings are used to accommodate multi-lingual voting on VxMark
The election-specific ballotStrings
recognized by the system are the following:
gridLayouts
is an array
which contains entities with the following attributes:
The optionBoundsFromTargetMark
field specifies an Outset
entity. The purpose is to give the distance from the bubble to edges of the entire contest option e.g. the area that includes the bubble, the corresponding candidate's name, and some padding. The system uses this area during write-in-adjudication to highlight specific contest options for review.
Grid positions are defined positions on the ballot corresponding to bubbles that can be marked by a voter. The row
and column
coordinates of each grid position denote where the bubble is printed within the abstract "grid" created by the timing marks on the outer edges of the ballot. There are two types of positions - a standard option position corresponding to a candidate or option in the election definition or a write-in position corresponding to a write-in bubble and area on the ballot.
In some jurisdictions, a write-in can only be counted if the associated bubble is filled in as for any other option. In other jurisdictions, a write-in must be counted even if the bubble is not filled. In order to detect these write-ins, a writeInArea
is defined for each write-in grid position. The Rectangle
specifies the area.
The election definition within the election package can be a JSON Ballot Definition CDF Version 1.0 file. The full specification is defined by NIST and can be .
VxSuite accepts the Ballot Definition CDF Version 1.0 as defined by NIST without any data extensions. VxSuite requirements differ from the NIST CDF schema only in the following respects:
Some fields not required in the NIST CDF are required in VxSuite
Some enumeration values are more restricted in VxSuite than in the NIST CDF
Some classes and attributes are ignored in VxSuite
The exact VxSuite schema is defined as a which is derived from the . The differences between the two are documented in the below tables.
The Ballot Definition defines all geographies as GpUnit
s, whereas the VxSuite Election Definition defines various geographies.
Contest term descriptions (e.g. “2 years”) will always show up in English because there is no field in the CDF for internationalized term descriptions
The full party name will be displayed for each candidate on VxMark (e.g. “Democratic Party” instead of “Democrat”) because the CDF only has one attribute for party name. In contrast, the VxSuite format supports two separate fields, one for the full name and one for showing on the ballot.
When adjudicating write-ins, the highlighted contest option area will be set to a default because there is no field in the CDF for this parameter.
Seal images are not supported in the CDF, so no seal will be shown in association with the election.
In a candidate contest, the voter makes a selection between pre-defined candidates or write-in options. The following attributes extend the shared attributes:
In a yes-no contest, also known as a ballot measure, the voter makes a selection between two options. The following attributes extend the shared attributes:
Although the system does not use the hand marked ballot instructional text for any purpose, it must be included in the election definition for security purposes. When included, it becomes a part of the and cannot be changed without invalidating older ballots.
The core data model already includes names and labels. For example, the entity already has a name
attribute. The names within the data model are used by default in the system in reports and administrative menus. The translations for all of these names are within the ballotStrings
and are important for two main reasons:
Including the translations in the election definition means they are included in the and cannot be changed without invalidating older ballots.
The language codes used are the for supported VxSuite languages: English, Spanish, Simplified Chinese, and Traditional Chinese.
Grid layouts describe where the bubbles and write-in areas exist on each ballot style. They must correspond exactly to the ballots used for the election in order for interpretation to succeed. For more information on the acceptable ballot format and its relationship to grid coordinates, see .
Election definition examples are located in the vxsuite
repository, such as .
When importing a Ballot Definition CDF file, attributes will be mapped to the and used across the system in the exact same way.
Most attributes in the Ballot Definition CDF that could require translation are defined with the CDF InternationalizedText
class which allows specifying variants for each language. InternationalizedText
maps directly onto VxSuite's . When an InternationalizedText
attribute is mapped to a ballot string, the English version is used as the default which will appear on reports and administrator interfaces while the translations are maintained in the election definition for multi-language experiences on voter devices.
Some geographies must exist in the Ballot Definition CDF file to be used in VxSuite. There must be one GpUnit
of type state
and one of type county
to populate the relevant metadata on the .
Any GpUnit
of type precinct
is mapped to a .
Any GpUnit
with an associated contest is mapped to a .
Because VxSuite does not utilize any data extensions to the Ballot Definition CDF, some information cannot be included when using the Ballot Definition CDF. The missing information creates some limitations when using the Ballot Definition CDF when compared to the format:
ballotLayout
Physical ballot metadata
ballotStrings
array
- Ballot Strings
ballotStyles
array
- Ballot Style
All ballot styles
contests
array
- Contest
All contests
gridLayouts
array
- Grid Layouts
county
County metadata
date
string
- YYYY-MM-DD
Date of the election
districts
array
- District
All districts
id
string
Unique identifier
parties
array
- Party
All parties
precincts
array
- Precinct
All precincts
seal
string
- SVG file format
Seal for the election
state
string
Name of the state
title
string
Title of the election
type
string
- "general" or "primary"
Type of the election
paperSize
string
Indicates physical length of the ballot
metadataEncoding
string
Indicates how the ballot metadata will be encoded on the ballot
id
string
Unique identifier
precincts
array
- IDs for Precinct
The IDs of all precincts which use the ballot style
districts
array
- IDs for District
The IDs of all districts whose contests are included in the ballot style
partyId
string
- ID for Party
Optional. The ID of the party to which the ballot belongs, if a primary
languages
array
- string
Optional. The language codes for the languages covered by the ballot style
id
string
Unique identifier
districtId
string
- ID for District
The associated district of the contest such as a state, county, or ward
title
string
Title of the contest
type
string
- "candidate" or "yesno"
Type of the contest
seats
number
The number of selections a voter can make
candidates
array
- Candidate
Candidate options for the contest
allowWriteIns
boolean
Whether the contest allows write-ins
partyId
string
- ID for Party
Optional. The ID of the party to which the contest belongs, if a primary
termDescription
string
Optional. Description of the term of the position, such as "For three years"
id
string
Unique identifier
name
string
Name as it appears on the ballot
partyIds
array
- ID for Party
Optional. The IDs of the parties associated with the candidate. The party name will appear next to the candidate
id
string
Contest description
yesOption
"Yes" option
noOption
"No" option
id
string
Unique Identifier
label
string
Label e.g. "Yes" or "No"
id
string
Unique Identifier
name
string
Name e.g. "Choctaw County"
id
string
Unique Identifier
name
string
Name e.g. "State of Mississippi"
id
string
Unique Identifier
name
string
Short name which will appear on the ballot besides candidates e.g. "Republican"
fullName
string
Full name which will appear in reports and in the titles of ballots e.g. "Democratic Party"
abbrev
string
Abbreviation for a party e.g. "R"
id
string
Unique Identifier
name
string
Name e.g. "Fire Station"
Ballot Language
ballotLanguage
string
Ballot Style IDs
ballotStyleId
key-value pairs, Ballot Style IDs mapped to names
Candidate Names
candidateName
key-value pairs, Candidate IDs mapped to names
Contest Descriptions
contestDescription
key-value pairs, Contest IDs mapped to descriptions
Contest Option Labels
contestOptionLabel
key-value pairs, Yes-No Contest Option IDs mapped to labels
Contest Terms
contestTerm
key-value pairs, Contest IDs mapped to term descriptions
Contest Titles
contestTitle
key-value pairs, Contest IDs mapped to titles
County Name
countyName
string
District Names
districtName
key-value pairs, District IDs mapped to names
Election Date
electionDate
string
Election Title
electionTitle
string
Party Full Names
partyFullName
key-value pairs, Party IDs mapped to their full names
Party Names
partyName
key-value pairs, Party IDs mapped to their short names
Precinct Names
precinctName
key-value pairs, Precinct IDs mapped to names
State Name
stateName
string
ballotStyleId
string
, ID for Ballot Style
Identifies the ballot style
optionBoundsFromTargetMark
Describes where the entire contest option area sits relative to the bubble
gridPositions
Describes bubble and write-in positions on the ballot
top
number
Distance from center of bubble to top of option bounds
right
number
Distance from center of bubble to right of option bounds
bottom
number
Distance from center of bubble to bottom of option bounds
left
number
Distance between center of bubble to left of option bounds
type
string
- "option"
Indicates this is a standard option position
sheetNumber
number
1-indexed sheet number within the ballot style
side
string
- "front" or "back"
Indicates side of the sheet
column
number
Column position of the bubble in the timing mark grid
row
number
Row position of the bubble in the timing mark grid
contestId
string
- ID of Contest
Contest identifier
optionId
string
- ID of Candidate or Yes-No Contest Option
Option identifier
type
string
- "write-in"
Indicates this is a write-in option position
sheetNumber
number
1-indexed sheet number within the ballot style
side
string
- "front" or "back"
Indicates side of the sheet
column
number
Column position of the bubble in the timing mark grid
row
number
Row position of the bubble in the timing mark grid
contestId
string
- ID of Contest
Contest identifier
writeInIndex
number
An index of the write-in position within the list of write-in positions for a contest (zero-indexed)
writeInArea
Area of the ballot to scan for a write-in
x
number
Column start of the rectangle
y
number
Row start of the rectangle
width
number
Width of the rectangle
height
number
Height of the rectangle
ElectionType
general, primary
ReportingUnitType
county, precinct, split-precinct, state, other
ActivationContest
ActivationOption
AnnotatedString
AnnotatedUri
BallotMeasureType
CandidatePreElectionStatus
Coalition
ContactInformation
DayType
ElectionAdministration
GeoSpatialFormat
Hours
LatLng
OfficeGroup
OfficeTermType
OrderedHeader
PartyContest
PartyOption
PartyPreferenceContest
PartyRegistration
Person
RetentionContest
Schedule
ShortString
SpatialDimension
SpatialExtent
StraightPartyContest
StraightPartyRuleset
TimeWithZone
VoteVariation
BallotDefinition
IsTest, Notes, OfficeGroup, Person, TestType
BallotMeasureContest
Abbreviation, BallotSubTitle, ContStatement, EffectOfAbstain, ExternalIdentifier, HasRotation, InfoUri, OtherType, OtherVoteVariation, PassageThreshold, ProStatement, SequenceOrder, SummaryText, TotalSubUnits, Type, VoteVariation
BallotMeasureOption
ExternalIdentifier, SequenceOrder
BallotStyle
ImageUri, Purpose
Candidate
CampaignSlogan, ContactInformation, ExternalIdentifier, FileDate, IsIncumbent, IsTopTicket, PartyId, PersonId, PreElectionStatus, ReadName
CandidateContest
Abbreviation, BallotSubTitle, ExternalIdentifier, HasRotation, NumberElected, NumberRunoff, OtherVoteVariation, RanksAllowed, SequenceOrder, TotalSubUnits, VoteVariation
CandidateOption
ExternalIdentifier, SequenceOrder
Election
ContactInformation, OtherType
Office
ContactInformation, Description, ElectionDistrictId, ExternalIdentifier, FilingDeadline, IsPartisan, OfficeHolderPersonIds
OrderedContest
OrderedContestOptionIds
Party
Color, ContactInformation, ExternalIdentifier, IsRecognizedParty, LeaderPersonIds, LogoUri, PartyScopeGpUnitIds, Slogan
ReportingUnit
AuthorityIds, ContactInformation, ElectionAdministration, ExternalIdentifier, IsDistricted, IsMailOnly, Number, OtherType, PartyRegistration, SpatialDimension, TotalSubUnits, VotersRegistered
Term
EndDate, StartDate, Type
Election.ExternalIdentifier
Election.id
Election.Type
Election.type
Election.Name
Election.title
Election.StartDate
Election.date
GpUnit.id
County.id, Precinct.id, District.id
GpUnit.Name
Election.state, County.name, Precinct.name, District.name
Party.id
Party.id
Party.Name
Party.name
Party.Name
Party.fullName
Party.Abbreviation
Party.abbrev
Contest.id
Contest.id
Contest.BallotTitle
Contest.title
Contest.ElectionDistrictId
Contest.districtId
CandidateContest.VotesAllowed
CandidateContest.seats
CandidateContest.ContestOption.IsWriteIn
CandidateContest.allowWriteIns
CandidateContest.PrimaryPartyIds
CandidateContest.partyId
Office.Term.Label
CandidateContest.termDescription
Candidate.id
Candidate.id
Candidate.BallotName
Candidate.name
CandidateOption.EndorsementPartyIds
Candidate.partyIds
BallotMeasureContest.FullText
YesNoContest.description
BallotMeasureContestOption.id
YesNoContestOption.id
BallotMeasureContestOption.Selection
YesNoContestOption.label
BallotStyle.ExternalIdentifier.Value
BallotStyle.id
BallotStyle.GpUnitIds
BallotStyle.districts, BallotStyle.precincts
BallotStyle.PartyIds
BallotStyle.partyId
BallotStyle.Language
BallotStyle.languages
BallotFormat.ShortEdge
BallotLayout.width
BallotFormat.LongEdge
BallotLayout.height
OrderedContest.ContestId
GridPosition.contestId
PhysicalContestOption.OptionPosition.Sheet
GridPosition.sheet
PhysicalContestOption.OptionPosition.Side
GridPosition.side
PhysicalContestOption.OptionPosition.X
GridPosition.column
PhysicalContestOption.OptionPosition.Y
GridPosition.row
PhysicalContestOption.ContestOptionId
GridPositionOption.optionId
PhysicalContestOption.ContestOptionId
GridPositionWriteIn.writeInIndex
PhysicalContestOption.WriteInPosition.X
GridPositionWriteIn.writeInArea.x
PhysicalContestOption.WriteInPosition.Y
GridPositionWriteIn.writeInArea.y
PhysicalContestOption.WriteInPosition.W
GridPositionWriteIn.writeInArea.width
PhysicalContestOption.WriteInPosition.H
GridPositionWriteIn.writeInArea.height
BallotDefinition
BallotFormat, Election, GpUnit, and Party are required
BallotFormat and Election must have a length of 1
GpUnit must have a minimum of length 1
BallotMeasureContest
BallotTitle, ContestOption, and FullText are required
ContestOption must have a length of 2
BallotStyle
ExternalIdentifier is required and must have a length of 1
Language must have a minimum length of 1
CandidateContest
BallotTitle and ContestOption are required
ContestOption must have a minimum of length 1
PrimaryPartyIds must have a length of 1 if it exists
CandidateOption
CandidateIds must have a length of 1
Election
BallotStyle, Contest, and ExternalIdentifier are required and all must have a minimum length of 1
GpUnit
At least one GpUnit must be defined with the type "state"
At least one GpUnit must be defined with the type "county"
Office
Term is required
OptionPosition
Sheet is required
OrderedContest
Physical is required and must have a minimum length of 1
Party
Abbreviation is required
PhysicalContest
PhysicalContestOption is required and must have a minimum length of 1
PhysicalContestOption
ContestOptionId is required
ReportingUnit
Name is required
Term
Label is required