Custom JSON format
This is the file format behind the JSON export, for reading or writing it with your own scripts. To move a tree in or out normally, use the Import and Export panels.
Overview
Draw My Tree uses a versioned JSON wrapper for imports and exports. Files start with a schemaVersion and a meta block, followed by a data object that holds people, relationships, and optional details, events, and media. An unknown key at the top level, in meta or in data rejects the file; an unknown field on a record is reported as a warning and not saved.
The backup .zip
The JSON export downloads as a .zip backup. It holds tree.json, the wrapper described on this page, and a media folder with each uploaded file's bytes as media/<id>.<ext>. That uploaded file's media item names it by the same relative path in url, so a backup carries no signed links. Links and text items stay as they are. Account → Download all my data writes one folder per tree in this layout, with an account.json at the top listing the trees.
The Import panel takes the .zip (one tree.json, at the top or in a single folder). It imports tree.json, then uploads each file to the person the import stored, and gives each person the picture their profileMediaId names when they have none in the tree. The 25 MB limit applies to tree.json, not to the files.
Top-level shape
| Field | Type | Required | Description |
|---|---|---|---|
| schemaVersion | "1" | required | Format version. Currently only '1' is accepted. |
| meta | object | required | Export metadata. See Meta below. |
| data | object | required | Tree contents. See Data below. |
Meta
| Field | Type | Required | Description |
|---|---|---|---|
| exportedAt | string (ISO 8601) | required | When the export was produced. |
| appVersion | string | optional | Optional; Draw My Tree's own exports leave it out. |
| treeName | string | optional | Human-readable tree name. |
| homePersonId | string | optional | The id of the person in data.people the tree opens on. An import into a tree with no home person makes them its home person; an id that is not in the file is ignored with a warning. |
| places | PlaceCoordinate[] | optional | Map coordinates the tree saved for its places, each { placeKey, lat, lng, source?, label? }. The placeKey is the place as people and events write it, read the same way however it is spelled. An import keeps them for every person and event written with that place, and never over a correction already saved in the tree. |
Data
The data block contains five arrays. Every array must be present, even if empty.
| Field | Type | Required | Description |
|---|---|---|---|
| people | Person[] | required | Individuals in the tree. |
| relationships | Relationship[] | required | Parent-child and partner links. |
| personDetails | PersonDetails[] | required | Optional life-event places and dates per person. |
| events | PersonEvent[] | required | Census, marriage, immigration, and other dated records. |
| media | PersonMedia[] | required | Photos, portraits, and documents linked to a person or relationship. |
Person
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | required | Identifier within the file, referenced by relationships and details. It can't contain '+'. An import stores it under the tree's own id; see Import behavior. |
| name | string | required | Display name. |
| birthDate | string | optional | ISO date or partial date (e.g. '1815' or '1815-12-10'), or an approximate date in GEDCOM form ('ABT 1815', 'BEF 1815-12', 'BET 1810 AND 1815'; also CAL, EST, AFT and FROM … TO). Text that isn't a readable date is kept as written. |
| deathDate | string | optional | Same forms as birthDate. |
| gender | 'male' | 'female' | 'other' | optional | Used for visual styling and GEDCOM export. |
| prefix | 'mr' | 'mrs' | 'ms' | 'dr' | 'rev' | optional | Title before the name, shown as Mr., Mrs., Ms., Dr. or Rev. Any other title belongs in name. |
| suffix | 'jr' | 'sr' | 'ii' | 'iii' | 'iv' | optional | Suffix after the name, shown as Jr., Sr., II, III or IV. |
| nickname | string | optional | The name the person was known by, such as 'Bud'. Plain text without quotes. Keep to 60 characters; the app's editor holds you to it, an import doesn't. |
| surname | string | optional | The family-name part of name, stated when it can't be guessed: a double surname ('Fernández de Córdoba') or a surname-first name ('毛' in '毛 澤東'). A hint only; name stays the full name. Keep to 120 characters; the app's editor holds you to it, an import doesn't. |
| tags | string[] | optional | Free-form labels. |
| aliases | string[] | optional | Alternate or former names (maiden name, anglicized spelling). The name a person went by belongs in nickname. |
| story | string | optional | Long-form biography. Markdown is supported in the UI. |
| profileMediaId | string | optional | Id of the media item used as this person's portrait. The Import panel restores it after the import, for an uploaded file in a backup .zip or a link; the import API ignores it. |
| livingStatus | 'unknown' | 'living' | 'deceased' | optional | Whether the person is living, as set in their details. 'unknown' leaves it to the dates. |
| shareVisibility | 'auto' | 'show' | 'hide' | optional | The person's Show on public links setting. An import by someone who can't publish keeps each person's stored setting. |
Relationship
Discriminated by type.
Parent-child
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | required | Identifier within the file; see Import behavior. |
| type | "parent-child" | required | Discriminator. |
| parentId | string | required | Person id of the parent. |
| childId | string | required | Person id of the child. |
| parentType | 'biological' | 'adoptive' | 'foster' | 'step' | 'guardian' | 'other' | optional | Nature of the parental link. |
| confidence | 'certain' | 'probable' | 'possible' | optional | How certain the link is. |
| childOrder | number | optional | The child's place among the family's children, 0 for the eldest; the same on both parents' links. |
Partner
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | required | Identifier within the file; see Import behavior. |
| type | "partner" | required | Discriminator. |
| a | string | required | One partner's person id. |
| b | string | required | The other partner's person id. |
| status | 'married' | 'engaged' | 'partnered' | 'separated' | 'divorced' | optional | Current state of the partnership. |
| startYear | number | optional | Year the partnership began. |
| endYear | number | optional | Year the partnership ended. |
PersonDetails
One entry per person id. All fields except id are nullable.
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | required | Matches a Person id. |
| birthDate | string | null | optional | Used when Person.birthDate is not set. |
| deathDate | string | null | optional | Used when Person.deathDate is not set. |
| birthPlace | string | null | optional | Place of birth. |
| deathPlace | string | null | optional | Place of death. |
| burialDate | string | null | optional | Date of burial. |
| burialPlace | string | null | optional | Place of burial. |
| baptismDate | string | null | optional | Date of baptism. |
| baptismPlace | string | null | optional | Place of baptism. |
| religion | string | null | optional | Religious affiliation. |
PersonEvent
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | required | Identifier within the file; see Import behavior. |
| type | 'marriage' | 'divorce' | 'census' | 'burial' | 'immigration' | 'newspaper' | 'probate' | 'property' | 'church' | 'record' | 'occupation' | 'residence' | required | Event category. |
| date | string | null | optional | Same forms as Person birthDate. |
| place | string | null | optional | Where the event occurred. |
| summary | string | null | optional | Short note about the event. |
| url | string | null | optional | Link to a source record. |
| personId | string | null | optional | Person the event is attached to. |
| relationshipId | string | null | optional | Relationship the event is attached to (e.g. marriage). |
PersonMedia
| Field | Type | Required | Description |
|---|---|---|---|
| id | string | required | Identifier within the file; see Import behavior. |
| type | 'photo' | 'portrait' | 'video' | 'document' | 'link' | 'text' | required | Media category. |
| url | string | null | optional | Direct URL to the media file, or in a backup .zip the file's path in it (media/<id>.<ext>). Leave it out for 'text' items, which use body. |
| body | string | null | optional | Inline content for 'text' items (transcripts, poems, recollections). |
| title | string | null | optional | Short human-readable label shown as the media's display name. Recommended under ~80 characters. |
| caption | string | null | optional | Longer descriptive context, transcript snippet, or alt text. Shown beneath the title. |
| source | string | null | optional | Attribution or archive reference. |
| sourceUrl | string | null | optional | Link to the source the item was drawn from. |
| personId | string | null | optional | Person the media is attached to. |
| relationshipId | string | null | optional | Relationship the media is attached to. |
Files you uploaded through the app carry storage fields on export (storage, status, contentType, bytes, width, height). An import doesn't read them; an uploaded file comes back as an uploaded file only from a backup .zip, uploaded again from its media folder. For media you write yourself, a url (or body for text) is all you need.
Example
{
"schemaVersion": "1",
"meta": {
"exportedAt": "2026-05-19T12:00:00.000Z",
"treeName": "My Lineage",
"homePersonId": "p1"
},
"data": {
"people": [
{
"id": "p1",
"name": "Ada Lovelace",
"birthDate": "1815-12-10",
"deathDate": "1852-11-27",
"gender": "female",
"tags": ["mathematician"],
"story": "Wrote the first algorithm intended for a machine."
},
{
"id": "p2",
"name": "Byron King-Noel",
"birthDate": "1836-05-12",
"gender": "male"
},
{
"id": "p3",
"name": "William King-Noel",
"birthDate": "1805-02-21",
"gender": "male"
}
],
"relationships": [
{
"id": "r1",
"type": "parent-child",
"parentId": "p1",
"childId": "p2",
"parentType": "biological",
"confidence": "certain"
},
{
"id": "r2",
"type": "partner",
"a": "p1",
"b": "p3",
"status": "married",
"startYear": 1835
}
],
"personDetails": [
{
"id": "p1",
"birthPlace": "London, England",
"religion": "Anglican"
}
],
"events": [
{
"id": "e1",
"type": "census",
"date": "1841-06-06",
"place": "Surrey, England",
"summary": "1841 UK Census",
"personId": "p1"
}
],
"media": [
{
"id": "m1",
"type": "portrait",
"url": "https://example.com/ada.jpg",
"title": "Ada at the writing desk",
"caption": "Portrait, c. 1840, oil on canvas",
"personId": "p1"
}
]
}
}Import behavior
- Files larger than 25 MB are rejected.
- Each list holds at most 50,000 records.
- An unknown key at the top level, in
metaor indatarejects the file. An unknown field on a person, relationship, detail, event or media item (for example a typo) is reported as a warning in the import preview and is not saved. - A person id containing
+rejects the file. A second record with an id already used in the same list is dropped with a warning, and so is a relationship that links a person to themselves. - A relationship, detail, event or media item that names a person or relationship not in the file is dropped.
- A media item whose
urlis amedia/path (atree.jsonimported without its.zip) is dropped with a warning. Import the.zipto restore the file. - The import API does not restore a person's
profileMediaIdor an uploaded file's storage fields; the Import panel restores both from a backup.zip, as above. - The chosen merge strategy controls how the import is reconciled with existing data. Pick a strategy in the Import sidebar before applying.
- An import stores every record under the tree's own ids. An id the tree already holds (a re-import of this tree's own export) is kept; any other id is replaced by one derived from the tree and the file's id, so importing the same file into the same tree again finds the records the first import made. References inside the file (relationships, details, events, media and
cite:links) are translated with them. - The import response carries an
idMapwithpeople,relationships,eventsandmedia, each mapping the file's id to the id stored. A script that goes on to update or attach to what it imported should look its ids up there rather than reuse the file's.
Last updated October 30, 2026 by Prescott Bros LLC, the makers of Draw My Tree.