Stable identifiers are an externally stable, unique identifier for a given
object. They allow data consumers to reconcile objects in a Common Data Format
(CDF) feed with other data repositories. In database parlance, external
identifiers are a form of foreign key that lets data consumers link
objects in a CDF feed to other databases.

As an example, if "Robert Brady" is a candidate, a data consumer might not
immediately link that person to "Bob Brady" in their image database. However,
the CDF data and the image database could indicate that this person is
legislator 01469 as identified by the Library of Congress THOMAS database. Then
the data consumer can link the image with the candidate.

The following conditions must hold for all stable identifiers:

- **Stability:** The stable identifier for a given unique entity, such as a `Person` or `Party`, mustn't change across different versions of the data feed. In other words, the stable ID mustn't change over time for a specific entity.
- **Uniqueness:** Never reuse a stable identifier for a different entity, even if the original entity is no longer in the feed.
- **Consistency:** You must use the same set of stable identifiers for candidates, parties, or districts for both simulations, if needed, and during the election cycle.

## Data formatting

Provide the stable identifiers in the following format:

    <ExternalIdentifier>
      <Type>other</Type>
      <OtherType>stable</OtherType>
      <Value>match the regex ^[a-zA-Z0-9_-]+$</Value>
    </ExternalIdentifier>

Some good examples of Stable IDs are Universal Unique identifiers (UUIDs) and
Global Unique identifiers (GUIDs). These would look like:

`e55b7dd4-cc98-11ec-9d64-0242ac120002`

Using [Hungarian notation](https://en.wikipedia.org/wiki/Hungarian_notation)
to further break down entities is a best practice to improve data readability,
but it is not required. The content of stable IDs is not expected to conform to
any standards beyond that of uniqueness and stability as described earlier.

Examples of prefixes:

- `e` for [`Election`](https://developers.google.com/civics-data/reference/election)
- `c` for [`Contest`](https://developers.google.com/civics-data/reference/contest)
- `can` for [`Candidate`](https://developers.google.com/civics-data/reference/candidate)
- `per` for [`Person`](https://developers.google.com/civics-data/reference/person)
- `par` for [`Party`](https://developers.google.com/civics-data/reference/party)
- `off` for [`Office`](https://developers.google.com/civics-data/reference/office)
- `oh` for [`OfficeHolderTenure`](https://developers.google.com/civics-data/reference/officeholder-tenure)
- `gb` for [`GovernmentBody`](https://developers.google.com/civics-data/reference/government-body)
- `ci` for [`ContactInformation`](https://developers.google.com/civics-data/reference/contact-information)
- `ru` for [`ReportingUnit`](https://developers.google.com/civics-data/reference/gp-unit)
- `bms` for [`BallotMeasureSelection`](https://developers.google.com/civics-data/reference/ballot-selection?feed=pre-election#ballot-measure-selection)
- `cs` for [`CandidateSelection`](https://developers.google.com/civics-data/reference/ballot-selection?feed=pre-election#candidate-selection)
- `ps` for [`PartySelection`](https://developers.google.com/civics-data/reference/ballot-selection?feed=pre-election#party-selection)
- `sbs` for [`SpecialBallotSelection`](https://developers.google.com/civics-data/reference/ballot-selection?feed=pre-election#special-ballot-selection)
- `pl` for [`PartyLeadership`](https://developers.google.com/civics-data/reference/party-leadership)
- `ds` for [`DataSource`](https://developers.google.com/civics-data/reference/data-source)
- `com` for [`Committee`](https://developers.google.com/civics-data/reference/committee)
- `ec` for [`ElectoralCommission`](https://developers.google.com/civics-data/reference/electoral-commission)

> [!IMPORTANT]
> **Important:** Avoid generating a stable ID from the data being provided. This can cause stable ID shifts which lead the data to be corrupted or become inaccurate and misused.

Recommended: per-e55b7dd4-cc98-11ec-9d64-0242ac120002

Recommended: off-7849514a-e8bc-11ec-8fea-0242ac120002

Recommended: per-123456789012345

Not recommended: per-john-doe

- Risk: Another person with the same name may have the same ID.
- Risk: Change in the data might affect the stable ID.

Not recommended: off-presidento-of-us

## Where to use stable IDs

Stable identifiers are mandatory for the following elements:

- [`BallotMeasureSelection`](https://developers.google.com/civics-data/reference/ballot-selection?feed=pre-election#ballot-measure-selection) of a **`BallotSelection`**
- [`Candidate`](https://developers.google.com/civics-data/reference/candidate)
- `Coalition` of a [`Party`](https://developers.google.com/civics-data/reference/party)
- [`Contest`](https://developers.google.com/civics-data/reference/contest)
- [`Election`](https://developers.google.com/civics-data/reference/election)
- [`Office`](https://developers.google.com/civics-data/reference/office)
- [`Party`](https://developers.google.com/civics-data/reference/party)
- [`Person`](https://developers.google.com/civics-data/reference/person)
- [`ReportingUnit`](https://developers.google.com/civics-data/reference/gp-unit#reporting-unit)