DocumentationJSON formats

JSON formats

This is not a public API. Eutepio exposes no endpoint that can be reached from outside. The structures below are internal formats — they are documented so you can read the contents of your own backup, not so you can build an integration against them. They may change between versions.

What this page is for

There are two places where you meet JSON in Eutepio:

  1. Sync — what devices send each other when a song or setlist is requested
  2. The .eutbackup backup — the songs.json and setlists.json files inside the archive

They differ deliberately: only what is worth sharing goes over the network, while everything goes into a backup.

Song over sync

json
{
  "leaderSongId": 42,
  "syncId": "e3b0c442-98fc-1c14-9afb-f4c8996fb924",
  "title": "Example Song",
  "artist": "The Band",
  "variantName": "acoustic",
  "key": "G",
  "bpm": 120,
  "timeSignature": "4/4",
  "capo": 2,
  "tags": ["rock", "live"],
  "chordProContent": "{c: Verse}\n[G]Woke up this [D]morning…",
  "durationSeconds": 225,
  "autoScrollMode": "continuous",
  "autoScrollDelaySeconds": 3,
  "version": 4
}
Note what is not there: private notes, transposition, font size, auto-scroll speeds, attachment paths and the MIDI command. Those fields never travel over the network at all — which is why nobody can overwrite them.

Setlist over sync

json
{
  "name": "Saturday at the club",
  "eventDateIso": "2026-09-12",
  "songs": [
    {
      "leaderSongId": 42,
      "title": "Example Song",
      "artist": "The Band",
      "variantName": "acoustic",
      "syncId": "e3b0c442-98fc-1c14-9afb-f4c8996fb924"
    }
  ]
}

A setlist carries only references to songs, not their content. A song the member does not have is fetched separately.

Song in a backup

A backup splits shared and personal data into two blocks:

json
{
  "syncId": "e3b0c442-98fc-1c14-9afb-f4c8996fb924",
  "matchKey": "example-song|the-band|acoustic",
  "contentHash": "9f86d081884c7d65…",
  "version": 4,
  "createdAt": "2026-05-14T18:22:04.000Z",
  "updatedAt": "2026-07-02T09:41:11.000Z",
  "deletedAt": null,
  "shared": {
    "title": "Example Song",
    "artist": "The Band",
    "variantName": "acoustic",
    "key": "G",
    "bpm": 120,
    "timeSignature": "4/4",
    "capo": 2,
    "tags": ["rock", "live"],
    "chordProContent": "{c: Verse}\n[G]Woke up this [D]morning…",
    "durationSeconds": 225,
    "autoScrollMode": "continuous",
    "autoScrollDelaySeconds": 3
  },
  "perDevice": {
    "privateNotes": "second verse a semitone down",
    "localTranspose": -2,
    "fontSizeScale": 1.2
  }
}
FieldMeaning
syncIdDurable identifier for the song across devices
matchKeyKey derived from title, artist and variant — used for matching
contentHashSHA-256 of the shared fields; tells you the content has not changed
versionIncrements on every edit of the shared fields
deletedAtSet = the song is soft-deleted

Setlist in a backup

json
{
  "matchKey": "saturday-at-the-club|2026-09-12",
  "name": "Saturday at the club",
  "eventDate": "2026-09-12T00:00:00.000Z",
  "venue": "The Club",
  "startTime": "20:30",
  "estimatedDurationMin": 90,
  "version": 2,
  "createdAt": "2026-08-01T12:00:00.000Z",
  "deletedAt": null,
  "customFieldsJson": "{}",
  "songRefs": ["e3b0c442-98fc-1c14-9afb-f4c8996fb924"],
  "breaks": [
    { "afterSongIndex": 7, "durationMinutes": 15, "label": "Break" }
  ],
  "songNotes": [
    { "songId": 42, "note": "Peter starts alone" }
  ],
  "perDevice": { "sortOrder": 3 }
}

Compatibility notes

  • The current backup format version is 2. The app can also read version 1 from earlier builds.
  • A backup with a higher schema version than the running build understands is refused — better nothing than a half-finished import.
  • Decimal values read from older records may be missing; on restore they fall back to a default.
  • Attachments are not in the JSON. They are separate files in the archive and the JSON refers to them by name.
  • A song's MIDI command is not in the backup. It stays only on the device where you set it.