Skip to content

Identifier export review guide

Preserve leading zeros in identifiers during export

Treat an identifier as a label with a declared lexical contract, not as a number that happens to contain digits. Preserve width, prefixes, and leading zeros from source through serialization, validation, sorting, and joins.

If leading zeros distinguish identifiers, serialize the field as a JSON string and validate its pattern and width. A JSON number is the wrong wire type for a value such as 0017 because JSON number syntax does not permit a leading zero and numeric parsing has no place to retain the original width. Keep the original text, reject malformed values, and test round trips across every export and import boundary. This is a lexical integrity method, not proof that an identifier belongs to a person or organization.

Updated

On this page

Decide whether the field is an identifier

A value is an identifier when its characters select or name something, rather than measure an amount. A fixed-width account key, postal code, warehouse bin, catalog code, and composite record key can all contain digits while remaining text. The first review question is not “can a parser convert this?” It is “would changing the character sequence change the key?” If yes, keep the lexical form.

The source dates shown in this guide identify documentation checks on 22 October 2026, not original publication dates. Use the producer contract to decide whether a prefix, case choice, separator, or width is significant. Do not infer that a field is numeric just because a spreadsheet displays it right-aligned.

Decide whether the field is an identifier (table)
Field behaviorLikely wire typeRisk when cast to number
Fixed-width key such as 0017StringLeading zeros disappear
Code with letters and digitsStringPrefix or case can change
Measured quantityNumber or documented decimal stringArithmetic may be blocked if text is used
Sequence used only for orderingInteger with rangeStill needs a separate identifier policy if reused as a key
Unknown digit-only fieldKeep source text until classifiedA guess can make joins irreproducible

Write a width and pattern contract

Make the lexical rule executable. State whether the identifier has an exact width, a minimum and maximum width, an allowed alphabet, a prefix, separators, and case behavior. If a value may be blank, model that state separately from a valid identifier. If the source uses several formats, version the contract instead of silently padding or trimming rows during export.

Write a width and pattern contract (table)
Contract fieldSynthetic choiceQuestion for the owner
wire_typestringDoes every serializer emit quotes?
pattern^[0-9]{4}$Are separators or prefixes ever valid?
width4Is width fixed across versions?
normalizationnoneWould padding create a new identifier?
case_policynot_applicableIf letters occur, is case significant?
invalid_actionreject_and_reportCan an invalid key enter a join?

JSON Schema can express a string type, a regular-expression pattern, and length boundaries. The schema does not know that a value is a business key, so add a description or external data dictionary that names its role. Keep the schema validation result separate from ownership, uniqueness, and authorization findings.

Round-trip text through every serializer

Test the smallest path that can lose width: source reader, in-memory representation, JSON serializer, destination reader, and any spreadsheet or warehouse adapter. A parser that turns 0017 into an integer has already discarded evidence. Re-padding the integer later can make the output look tidy while hiding whether the source was 17, 0017, or an invalid longer value.

Round-trip text through every serializer code example, Python
import json
import re

KEY = re.compile(r"^[0-9]{4}$")
source = {"record_key": "0017"}
wire = json.dumps(source, separators=(",", ":"))
loaded = json.loads(wire)

value = loaded["record_key"]
assert isinstance(value, str)
assert KEY.fullmatch(value)
assert value == "0017"

Minimum fixture set

  • A valid all-zero value if the contract allows it.
  • A valid value with one leading zero, such as 0017.
  • A valid value with no leading zero, such as 1700.
  • A short value, a long value, and a value with whitespace.
  • A quoted JSON string and a deliberately rejected JSON number.

RFC 8259 also recommends unique object member names for interoperability. That matters here because a duplicate key can make a test appear to preserve one identifier while a receiver chooses another. Reject duplicate members or use a parser mode that exposes them before judging identifier behavior Internet Engineering Task Force, (opens in a new tab).

Join and sort without changing identity

A join review should compare the exact key text first. Do not repair a failed join by converting both sides to numbers unless the owner has confirmed that lexical width is irrelevant. If two source systems use different widths, retain each original value, map through a documented crosswalk, and record whether the mapping is one-to-one, many-to-one, or unresolved.

Join and sort without changing identity (table)
OperationSafe defaultFinding to record
EqualityCompare strings under the stated case policyUnresolved normalization or width mismatch
SortingUse lexical or numeric order only when declaredConsumer sorted a key as a measure
JoinMatch exact contract values before crosswalksRows need a mapping or remain unmatched
DeduplicationPreserve source keys and collision evidenceValues collapse after coercion
ExportQuote identifiers and validate after serializationWire type changed at the boundary

RFC 8785 provides a useful caution for canonicalization: strings and numbers are different JSON values, and number serialization follows a precision model. Canonical output cannot restore characters that an earlier numeric conversion discarded. Treat canonicalization as a final check, not a repair step Internet Engineering Task Force, (opens in a new tab).

Take a qualified next step

If the owner can describe the collection and its handling authority, the next step may be the appraisal route. That route is a request for review, not automatic acceptance, a quote, a buyer match, a legal opinion, or a license. A small synthetic fixture is enough to test leading-zero behavior; do not send private records merely to demonstrate a serializer bug.

Takeaways

  • Classify digit-only fields as identifiers or measures before parsing.
  • Use a string wire type when width or characters are meaningful.
  • Validate width and pattern after every serialization boundary.
  • Compare exact text before applying a documented crosswalk.
  • Report lexical integrity separately from uniqueness and ownership.

Sources

  1. Internet Engineering Task Force: The JavaScript Object Notation (JSON) Data Interchange Format (opens in a new tab)
  2. JSON Schema: JSON Schema Validation: Draft 2020-12 (opens in a new tab)
  3. Internet Engineering Task Force: JSON Canonicalization Scheme (JCS) (opens in a new tab)

Use the appraisal route only after identifier semantics are documented.

Preparation does not promise acceptance, a buyer, a quote, or an offer.