Skip to content

When GEDCOM has no tag for it

GEDCOM is an open, extensible standard: when no standard tag fits the data you have, you may invent your own. Custom tags are how the format stretches to cover DNA results, vendor identifiers, and the long tail of things the spec never named — and Linea Codex carries them through every edit, save, and conversion without losing them. These recipes show how to add a custom tag, how the app treats it, when to reach for a generic event instead, and how to keep custom data readable by other programs.

New to reading GEDCOM lines? Skim How GEDCOM works first — every recipe shows the underlying lines, but the app writes them for you as you type.

Add a custom tag for data the standard doesn’t cover

Section titled “Add a custom tag for data the standard doesn’t cover”

The structure. A custom tag is an ordinary GEDCOM line whose tag begins with an underscore. Otherwise it behaves like any other line — it has a level, it can hold a value, and it can have children:

0 @I1@ INDI
1 NAME Jane /Smith/
1 _DNA mtDNA haplogroup H1
2 SOUR @S1@

Here _DNA records a DNA result the standard has no tag for. It nests under the individual like any other fact, and carries a normal source citation beneath it. You choose the tag name (anything starting with _) and what it means.

In the app. Add a line in the editor and type a tag starting with _. Autocomplete proposes the standard tags valid at your position, but it won’t stop you from typing your own — once the tag starts with an underscore the app treats it as a custom tag and lets it stand. There’s no special “custom tag” command; a custom tag is just a line you write. Use the spec viewer on the parent line to confirm what standard tags are available first — often there’s a standard structure that fits, and a custom tag is only worth it when there genuinely isn’t one.

Across versions. The underscore convention is part of the grammar in all three versions. GEDCOM 5.5 and 5.5.1 both state in their prose that any user-defined tag — one not defined in the standard — must begin with an underscore; GEDCOM 7.0 keeps the requirement (its grammar’s extTag production requires the leading underscore) and adds a formal mechanism for documenting what your custom tags mean (see Keep custom data portable). So 1 _DNA … is well-formed in 5.5, 5.5.1, and 7.0 alike — what changes across versions is only how much you can say about the tag, not whether you may use it.

Validation notes. A custom tag is never an error — the underscore tells the checker “this is intentional, not a typo,” and it is left alone. This is the difference that matters: a non-underscore tag the version doesn’t recognize (a misspelled BIRTH instead of BIRT, say) is flagged as an unknown tag, because the checker assumes you meant a standard tag and got it wrong. Prefix it with _ and that assumption — and the diagnostic — goes away. In a 7.0 file the app may still emit a warning suggesting you declare the tag in the header schema; that’s a portability hint, not a rejection (see the next two recipes).

See also: How Linea Codex preserves and validates custom tags · The spec viewer · Notes.

How Linea Codex preserves and validates custom tags

Section titled “How Linea Codex preserves and validates custom tags”

Goal. Understand what the app does with a tag it doesn’t recognize — so you can trust that custom data survives a round-trip and a version conversion.

The structure. Nothing special: a custom tag and its whole subtree are stored exactly as written.

0 @I1@ INDI
1 _MILT
2 TYPE Army
2 DATE FROM 1916 TO 1918
2 PLAC France

The app parses _MILT and everything beneath it (TYPE, DATE, PLAC) into the same tree it uses for standard tags. When you save or export, it writes those lines back out unchanged.

In the app. Custom tags appear in both editor modes — Raw mode shows the lines verbatim; Structured mode draws the subtree like any other. The inspector lists them, and search finds them. Validation underlines genuine problems (a malformed line, a broken pointer) but leaves the custom tag itself unhighlighted. Because the app round-trips the AST faithfully, importing a file with custom tags and exporting it again gives you back the same custom tags.

Across versions.

  • 5.5 / 5.5.1 — custom tags pass through import, edit, save, and export untouched. They carry no formal documentation; their meaning lives only in the sending system, exactly as the spec says.
  • 7.0 — custom tags still pass through, and 7.0 adds the option to document them in a header schema. An undeclared custom tag in a 7.0 file is valid but draws a warning; declaring it (see the next recipe) clears the warning and tells other programs where to look up its meaning.
  • Converting between versions preserves custom tags as-is — the converter doesn’t drop a tag just because it doesn’t recognize it. (By contrast, dropping a standard 7.0-only tag when converting down to 5.5 is unavoidable and best-effort; custom tags don’t face that problem because no version “owns” them.) When the target is 7.0, the converter can additionally declare every in-use custom tag in the header schema for you, under Linea Codex’s own URI namespace, so the result is fully documented.

Validation notes. The app is permissive: it never blocks a save or conversion because of a custom tag, and it never silently rewrites one. The strongest thing the checker does is, in a 7.0 file, warn that a custom tag is undeclared. Everything else about the tag — its value, its children, its placement — is your call. If you want a bulk remedy (renaming a custom tag across the whole file, declaring several at once), reach for the transform panel rather than expecting an automatic fix; in-editor quick-fixes are narrow convenience spot-fixes, not a broad auto-correct.

See also: Keep custom data portable · Converting GEDCOM versions · Bulk transforms.

Custom tag vs. generic event/fact — which to choose

Section titled “Custom tag vs. generic event/fact — which to choose”

Goal. Decide whether to invent a custom tag or use a standard generic carrier. Often the standard already has a home for your data, and using it keeps the file portable with no schema work.

The structure. Before inventing _LANDLEASE, check whether a generic event (EVEN) or fact (FACT) fits. Both are standard tags that take a TYPE to say what they classify:

1 EVEN
2 TYPE Land lease
2 DATE 2 OCT 1837
2 PLAC Boston, Massachusetts, USA
1 FACT Woodworking
2 TYPE Hobby

EVEN carries something that happened on a date; FACT carries a standing characteristic. Compared with a custom tag, both are understood by every GEDCOM program, sort and display correctly, and need no declaration — so they’re the better choice whenever your data is “an event” or “a fact.”

In the app. Add an EVEN (or, in a 5.5.1/7.0 file, FACT) line and let autocomplete offer TYPE beneath it. The generic-event and generic-fact recipe in Events & facts walks through this in full, including the version differences.

When a custom tag is the right call. Reach for a custom tag when the data isn’t an event or a fact at all — a machine identifier, a display preference, a cross-system key — or when you must match a tag a specific other program reads (see Recognizing common third-party extensions). Rule of thumb: prefer a standard structure; use EVEN/FACT for typed events and characteristics; fall back to a custom tag only for things the standard genuinely cannot express.

Across versions. EVEN exists in all three versions; FACT was added in 5.5.1 and kept in 7.0 (5.5 has no FACT, so use EVEN there). A custom tag works in all three. This is the trade-off: the generic carriers are version-sensitive but universally understood, while a custom tag is uniform across versions but understood only by programs that know your convention.

Validation notes. A FACT without a TYPE is flagged in 5.5.1 and 7.0, and a generic EVEN without one is flagged in 7.0 (in 5.5.1 the TYPE under EVEN is recommended but optional) — the TYPE is what gives the generic tag meaning. A custom tag, by contrast, is never flagged for lacking a TYPE; the checker makes no demands of it. That asymmetry is a hint in itself: if the checker can usefully validate the typed form, the typed form is usually the more portable choice.

See also: Record a custom event or fact (EVEN with TYPE) · Add a custom tag for data the standard doesn’t cover.

Goal. Make sure another program — or future you — can tell what a custom tag means, instead of guessing from its name.

The structure (7.0). GEDCOM 7.0 formalizes extensions with a header schema: a SCHMA structure in HEAD whose TAG children map each custom tag to a URI that documents its meaning. A tag mapped this way is a documented extension tag; one used without a mapping is an undocumented extension tag:

0 HEAD
1 SCHMA
2 TAG _DNA https://example.com/gedcom/ext/DNA
2 TAG _MILT https://example.com/gedcom/ext/MILT
0 @I1@ INDI
1 _DNA mtDNA haplogroup H1

The SCHMA block declares that, throughout this file, _DNA is shorthand for the concept at that URI. The spec recommends the URI be a URL that actually serves documentation, and that SCHMA appear early in the header, before any extension tag is used. It’s the URI — not the tag spelling — that carries the meaning, so two files can use different tag letters for the same documented concept and still agree.

In the app. When you convert a file to GEDCOM 7.0, Linea Codex can declare every custom tag in use for you, writing a HEAD.SCHMA with a TAG mapping per tag under its own URI namespace (https://linea.sh/gedcom/ext/…). You can also write or edit the SCHMA block by hand in the editor — autocomplete offers SCHMA under HEAD and TAG under SCHMA in a 7.0 file. Use the spec viewer on SCHMA/TAG to see the exact shape.

Across versions.

  • 5.5 / 5.5.1 have no SCHMA — there is no in-file way to document a custom tag, so its meaning travels only by convention. Keep tag names self-explanatory and, where it helps, attach a note explaining the data.
  • 7.0 is the only version with SCHMA. Writing a 1 SCHMA block in a 5.5 or 5.5.1 file is not valid there and gains you nothing — reserve it for 7.0 files.
  • Converting up to 7.0 is therefore the moment custom data becomes self-documenting: the app can generate the schema declarations as part of the conversion. Converting down from 7.0 drops the SCHMA block (5.x has nowhere to put it) but keeps the custom tags themselves — best-effort, and a lossy step only for the documentation, not the data.

Validation notes. In a 7.0 file, a custom tag that isn’t listed in HEAD.SCHMA produces a warning (undeclared extension tag), not an error — your data is intact, but a reader has no URI to resolve. A TAG line must follow the _TAG <URI> shape (an underscore tag, a space, then a non-empty URI with no whitespace); a malformed mapping is flagged. Declaring the tag clears the warning. There’s no equivalent check in 5.5 / 5.5.1, because those versions have no schema to check against.

See also: How Linea Codex preserves and validates custom tags · Converting GEDCOM versions · Give a record a stable identifier.

Goal. Read custom tags written by other programs. Many genealogy applications ship their own underscore tags, and a handful are common enough that you’ll meet them in imported files.

The structure. These all look like ordinary custom tags — an underscore tag with a value and sometimes children:

0 @I1@ INDI
1 NAME Jane /Smith/
1 _UID 26D3EB01-5C4F-4D8A-9A1F-2B9C0F3A77E1
1 OBJE @O1@
2 _PRIM Y
0 @O1@ OBJE
1 _PHOTO Y

Tags you may run into in the wild include:

  • _UID — a stable unique identifier on a record, common in 5.5 / 5.5.1 files that predate 7.0’s standard UID. (See Give a record a stable identifier for the 7.0 standard equivalent.)
  • _PRIM — marks a multimedia object as the primary (preferred) one for a record.
  • _PHOTO — flags an object as a photograph, or points to a person’s primary photo.
  • _MILT — a military-service event many programs use where the standard offers no dedicated tag.

In the app. Linea Codex imports, displays, edits, and re-exports all of these like any other custom tag — they survive the round-trip unchanged. They show up in the editor, the inspector, and search, and they’re never flagged as errors. If you want to normalize such tags on import — say, rename a vendor tag, or in a 7.0 file declare it in HEAD.SCHMA — the transform panel is the tool for a file-wide change.

Across versions. These are conventions, not standard tags, so no version defines them and the underscore rule covers them everywhere. Where a standard tag now exists — 7.0’s UID versus the older _UID — prefer the standard form in new 7.0 data and keep the custom form only for compatibility with the program that wrote it.

Validation notes. Because these are custom tags, the checker leaves them alone in every version; the only treatment they get is 7.0’s undeclared-extension-tag warning if you haven’t documented them in SCHMA. Linea Codex does not attach special meaning to any third-party tag — it preserves them exactly, but it reads them as opaque custom data, not as the originating program’s feature. What a _PRIM or _PHOTO means is defined by whoever wrote it, so treat the descriptions above as “recognized in the wild,” not as guarantees the app interprets them.

See also: Add a custom tag for data the standard doesn’t cover · Multimedia · Bulk transforms.


That’s the cookbook — from reading a GEDCOM line to extending the standard itself. Head back to the Cookbook overview to revisit any chapter, or dig into the per-version detail in Reference & Concepts →.