Basics

  • All files are under https://eu5db.com/data/.
  • Each game version has its own folder, named by a version ID such as 1.3.11-0d6cd6f7e3dd. Read versions.json to find them. default is the latest version.
  • The format can change when the site is updated. The types at the bottom of this page are always current.
  • A path that doesn't exist returns the site's HTML page instead of a 404. Check that the Content-Type is application/json.
  • Please be kind to the server: if you need everything, download it once instead of fetching on every request.

Files

PathContents
versions.jsonEvery published game version, newest first, and which one is the default.
<version>/manifest.jsonConcept types with their counts, plus node and edge totals.
<version>/index.json[id, name, icon] for every node. Use it to search or to list all IDs.
<version>/lists/<concept>.jsonOne summary row per node of a concept type, as shown in the tables.
<version>/nodes/<shard>.jsonFull details for every node in one shard, keyed by node ID.
<version>/hashes.jsonNode ID → content hash. The hash changes when the node's content changes.
<version>/changes.jsonNodes added, removed and changed since the previous version.
assets/<file>Icons and illustrations. The icon fields hold these file names.

Node IDs

A node ID is concept:key, for example law:administration_of_italian_lands_law. It's the same as the node's page address on this site, /concept/key. Edges and modifiers refer to other nodes by ID.

Finding a node's shard

Nodes are split across 256 files so that a page only downloads a small part of the data. To find which file holds a node, hash its ID with 32-bit FNV-1a, take the result modulo 256, and write it as two lowercase hex digits:

  1. Start with hash = 0x811c9dc5.
  2. For each byte of the ID in UTF-8: hash = (hash XOR byte) × 0x01000193, keeping the low 32 bits.
  3. The shard is hash mod 256, zero-padded to two hex digits: 00 to ff.
function shardOf(id) {
  let hash = 0x811c9dc5;
  for (const byte of new TextEncoder().encode(id)) {
    hash ^= byte;
    hash = Math.imul(hash, 0x01000193) >>> 0;
  }
  return (hash % 256).toString(16).padStart(2, "0");
}

Shard d2 → https://eu5db.com/data/1.3.11-0d6cd6f7e3dd/nodes/d2.json

Example

const base = "https://eu5db.com/data";
const { default: version } = await fetch(`${base}/versions.json`).then((r) => r.json());

const id = "estate_privilege:noble_serfdom_rights";
const shard = await fetch(`${base}/${version}/nodes/${shardOf(id)}.json`).then((r) => r.json());
const node = shard[id];

console.log(node.name, node.modifiers, node.out, node.in);

With curl: curl https://eu5db.com/data/1.3.11-0d6cd6f7e3dd/lists/law.json

Types

Optional fields are left out of the JSON when they're empty. body is the parsed game script; see a node file for its shape.

export type Manifest = { version: VersionInfo, concepts: Array<ConceptInfo>, nodeCount: number, edgeCount: number, shardCount: number, diagnostics: Array<DiagnosticCount>, };

export type Index = { nodes: Array<[string, string | null, string | null]>, };

export type ListRow = { id: string, key: string, name?: string, icon?: string, dlc?: string, parent?: string, props?: { [key in string]: JsonValue }, modifiers?: Array<ModifierEntry>, 
/**
 * Structural outgoing edges (membership, prerequisites, unlocks, event chains).
 */
out?: Array<EdgeRef>, availability?: Array<AvailabilitySource>, };

export type NodeDetail = { out: Array<EdgeRef>, in: Array<EdgeRef>, availability?: Array<AvailabilitySource>, id: string, concept: string, key: string, name?: string, desc?: string, 
/**
 * Game-relative asset path; replaced by a published file name when assets are exported.
 */
icon?: string, 
/**
 * Large picture for the top of the page; an asset path like `icon`.
 */
illustration?: string, file: string, line: number, dlc?: string, parent?: string, props?: { [key in string]: JsonValue }, modifiers?: Array<ModifierEntry>, body: Block, 
/**
 * Localized text for localization keys appearing in the body.
 */
locs?: { [key in string]: string }, 
/**
 * Token → node id for every resolved reference in the body (drives links in the UI).
 */
links?: { [key in string]: string }, 
/**
 * Token → number for references to constant script values, shown next to the name.
 */
values?: { [key in string]: JsonValue }, };

export type EdgeRef = { node: string, kind: EdgeKind, via: string, value?: JsonValue, };

export type EdgeKind = "contains" | "belongs_to" | "requires" | "unlocks" | "triggers" | "grants" | "removes" | "calls" | "modifies" | "references" | "mentions";

export type ModifierEntry = { 
/**
 * `modifier_type:<key>` node id.
 */
modifier: string, value: JsonValue, scope: Scope, 
/**
 * Path of the block the entry was found in.
 */
via: string, };

export type AvailabilitySource = { 
/**
 * Definition declaring these conditions (may be a parent law).
 */
source: string, body: Block, links: { [key in string]: string }, locs: { [key in string]: string }, values: { [key in string]: JsonValue }, };
© 2026 Soft Santa Cruz, S.L.U.. Tous droits réservés. Projet de fan non officiel, non affilié à Paradox Interactive. Contenu du jeu © Paradox Interactive. À propos · Confidentialité · Mentions légales