Concept · JSON travel itinerary

A travel itinerary in JSON

Roadbook is an open JSON interchange format for complete travel itineraries. Here is why JSON is a good fit, what the smallest valid file looks like, and how validation and portability follow from it.

Why JSON works well for an itinerary#

The minimal valid Roadbook#

Six required root fields — id, name, start, end, members, days — plus formatVersion to say which version you wrote. Each day needs an id, an index, a date, a title and items; each item an id, a title, a type and a status.

{
  "formatVersion": "1.2",
  "id": "minimal-example",
  "name": "A day in Lille",
  "start": "2026-09-05",
  "end": "2026-09-05",
  "members": [
    { "id": "m1", "name": "Alex", "role": "owner", "kind": "adult" }
  ],
  "days": [
    {
      "id": "d1", "index": 1, "date": "2026-09-05", "title": "Old Lille",
      "items": [
        { "id": "i1", "time": "10:00", "title": "Stroll through Old Lille",
          "type": "heritage", "status": "planned",
          "place": "Place du Général-de-Gaulle, Lille" },
        { "id": "i2", "time": "12:30", "title": "Lunch",
          "type": "meal", "status": "planned" }
      ]
    }
  ]
}

This is examples/minimal.roadbook.jsonvalidate it. From there, add bookings, tickets, alternatives, options, people, vehicles, checklists as the trip requires; the examples show each feature in context.

Conventions that keep the JSON unambiguous#

ConceptRule
datesISO YYYY-MM-DD.
times24-hour HH:MM, always the local wall-clock time where the item happens; optional IANA timezone fields carry the zone.
enumsEnglish tokens ("meal", "confirmed", "to_book"…), used verbatim in the file and translated by the player at display time.
idsNon-empty strings, unique within their collection; references (bookingId, memberIds, personIds, vehicleId, chosenOptionId) must resolve.
currencyISO 4217; a trip-level default (absent = EUR), overridable per price.
mediaURLs (or relative paths next to the file) — never inline binaries.

Schema validation#

Two layers. The JSON Schema checks structure and types with any generic validator. The reference validator (zero-dependency ESM, browser/Node/CLI) additionally checks what a schema cannot express: id uniqueness, day dates inside the trip range, consistent day indexes, resolving references. Errors are path + message pairs — designed to be pasted back to the tool or model that produced the file.

import { validateRoadbook } from 'https://roadbookformat.org/roadbook-validate.mjs'
const { ok, version, errors, warnings } = validateRoadbook(json)
// errors: [{ path: "$.days[1].date", message: "Day 2026-09-07 falls outside the trip period …" }]

With AJV (JSON Schema 2020-12):

import Ajv2020 from 'ajv/dist/2020.js'
const schema = await (await fetch('https://roadbookformat.org/roadbook.schema.json')).json()
const validate = new Ajv2020({ strict: false }).compile(schema)
validate(json) || console.log(validate.errors)

Portability#

A Roadbook is a file you own: my-trip.roadbook.json, UTF-8, media type application/json. It can be e-mailed, stored in a drive, versioned in git, imported into a player, exported back out, and diffed. Because every file declares its formatVersion and readers must preserve unknown fields, a file written today stays readable by tomorrow's tools and vice-versa within the same major version. See itinerary interchange.

AI generation#

The same properties make Roadbook easy for an assistant to produce: regular structure, public spec at a stable URL, explicit rules, a schema usable for structured output, and a validator whose messages close the loop. The AI page has a prompt builder and the full workflow; AI travel itinerary explains when the format is the right answer.