Census
A census is the who-can-vote list and how they prove who they are. It is declared inline when you create a process - no separate create-and-publish step - and its type is inferred from the fields you pick.
A census is the eligible-voter list plus the rules for how a voter authenticates. You no longer
build and publish it separately: you declare it inline in the census object of
POST /processes, and the server materializes and publishes it
for you at publish time. Its internal id is
never sent or returned.
The census object
{
"weighted": false, // when true, each member's weight counts as vote weight
"authFields": ["memberNumber"],
"twoFaFields": [], // e.g. ["email"] for an email OTP second factor
"groupId": "", // populate from a group's members...
"memberIds": [] // ...or list member ids explicitly
}
| Field | Type | Description |
|---|---|---|
authFields |
string[] | Optional. Identity fields a voter must present (e.g. memberNumber). |
twoFaFields |
string[] | Optional. Channels for a one-time-code second factor: email or phone. |
weighted |
boolean | Count each member's weight as their vote weight. |
groupId |
string | Populate the census from a group's members. |
memberIds |
string[] | Populate the census from an explicit list of member ids. |
Populate the census from a groupId or an explicit memberIds list - both reference the
organization's members and groups. Use the auto "All members"
group to include everyone.
The fields above are what you send. A process read adds response-only size and totalWeight to
the census object - see Reading a process.
Authentication
authFields and twoFaFields are two independent settings, each optional. Set either, or both:
authFieldsonly - an auth-only census: the voter authenticates purely by presenting these identity fields, no second factor.twoFaFieldsonly - a 2FA census with noauthFieldsrequired: the voter identifies by the contact channel (email or phone), receives a one-time code, and enters it. Turning on 2FA does not require any auth fields.- both - identity fields and a one-time code.
The census type is inferred from twoFaFields (you never set it directly); authFields can be
combined with any of them:
| Type | twoFaFields |
Second factor |
|---|---|---|
auth |
none | none (auth-only) |
mail |
["email"] |
email OTP |
sms |
["phone"] |
SMS OTP |
sms_or_mail |
["email","phone"] |
voter's choice |
authFieldsoptions:name,surname,memberNumber,nationalId,birthDate.twoFaFieldsoptions:email,phone.
The identifying field must be unique
Whatever field identifies a voter - an authFields value like memberNumber on an auth-only census,
or the email/phone used for the code - must be unique across the members you include;
duplicates fail the publish readiness check.
Weighted voting
Set "weighted": true to make each member's weight count as their vote weight - use it for
shareholder meetings or any vote where members do not count equally.
Per-question eligibility
The process census is the full electorate. A single question can narrow it to a subset with its
own optional census object (a groupId or memberIds, always within the process census); omit it and
every census member may vote on that question. Reads expose the resolved subset as eligibleMemberIds,
but only to a manager/admin (or a voting:write key) - it is stripped from the public process
reads. A voter checks their own per-question eligibility with
POST /processes/{processId}/check.
"questions": [{
"title": { "default": "Board seat (full members only)" },
"choices": [ /* ... */ ],
"census": { "groupId": "<full-members-group>" } // subset of the process census
}]
Identity and weight always come from the process census; the subset only decides which members may vote on which question. This is how one process runs questions with different electorates without building multiple censuses.
Validating a census
Dry-run a census spec before you create the process. It flags the common problems - duplicate or missing auth-field data across the members it resolves - without creating anything.
curl "${auth[@]}" -X POST "$B/processes/census/validation" -d @- <<JSON
{
"orgAddress": "$ORG",
"census": { "authFields": ["memberNumber"], "groupId": "$GROUP" }
}
JSON
{ "valid": true, "errors": [] } // errors may carry the offending member ids
Growing the census after publishing
The census is fixed at publish, but you can add more members later without re-creating the process - see Growing a published census. Questions with an eligibility subset keep their fixed size.