Reference
Graph model
Fourteen node kinds and twenty-three edge kinds, both fixed vocabularies enforced by the database rather than by convention. Adding to either takes a migration and a recorded decision, which is why something you build against this year still resolves next year.
Node kinds
| Kind | Represents |
|---|---|
region | A jurisdiction with a boundary, such as a state, county, district or place |
authority | A governing or election-administering body |
office | An elected position that exists over time |
contest | One office decided at one election |
candidacy | One person seeking one office at one election |
person | A human, deduplicated across cycles and offices |
party | A political party and its chapters |
result | A vote tally for one candidacy |
position | A stated stance on an issue |
issue | A policy topic positions attach to |
event | An election date |
artifact | A source document a claim was drawn from |
organization | A campaign, committee or firm |
engagement | A person's role at an organization |
The relationships that carry the weight
| Edge | From and to |
|---|---|
SCOPED_TO | Office to Region |
HOLDS | Authority to Office |
CONTAINS | Region to Region |
IS_CANDIDACY_OF | Candidacy to Person |
GOVERNS | Authority to Region |
RUNS_IN | Candidacy to Contest |
ALIAS_OF | Alias to any node |
NOMINATED_BY | Candidacy to Party |
FILLS | Contest to Office |
DECIDES | Event to Contest |
PRIORITIZES | Candidacy to Issue |
RESULT_OF | Result to Candidacy |
WON_BY | Contest to Candidacy |
Slugs
Every node carries a stable, readable slug shaped {kind}:{identifier}, and slugs are the key you should build against because they survive re-ingestion whereas our internal ids are not part of the contract.
region:az-maricopa-county
office:az-maricopa-county-recorder
contest:az-maricopa-county-recorder-2026-general
candidacy:az-maricopa-recorder-2026-general-jane-doe
person:az-jane-doe
artifact:az-sos-candidate-list-2026-08-20The metadata envelope
Every node and edge carries the same seven fields whatever its kind, separating when something was true in the world from when we recorded it. That is what lets you filter the entire graph by trust and by time in a single condition, and what makes a historic query an ordinary filter rather than a separate snapshot table.
| Field | Meaning |
|---|---|
confidence | Zero to one. How much we trust this assertion |
status | unverified, verified or disputed |
source_status | How authoritative the source was: authoritative, migrated or synthetic |
valid_from and valid_to | The real-world window this assertion holds for |
created_at and updated_at | When we recorded and last changed it |