Docs/Codex/Entities

Entities

Every entity returned by the codex has the same envelope. The shape is what the SDKs and HTTP clients code against.

Anatomy

The HTTP response for a Longsword:

jsonc
{
   "id":     "id.item.longsword_5001",
   "type":   "item",
   "game":   "dark-and-darker",
   "branch": "main",
   "name":   "Longsword",
   "patch":  { "id": 4, "version": "0.16.135.8645-2663" },
   "tags":   [ "primary", "two_handed", "epic", "sword", "weapon" ],

   "icon": {
      "hash": "22cd8c50c8829958106150b86dc5a436567a01df7015404f213669c5675b5b39",
      "url":  "/v1/codex/assets/22cd8c50c8829958106150b86dc5a436567a01df7015404f213669c5675b5b39"
   },

   "data": {
      "_source":         { "key": "Id_Item_Longsword_5001", "path": "Data/Generated/V2/Item/.../Id_Item_Longsword_5001.json" },
      "id_tag":          "Id.Item.Longsword",
      "origin_id":       "Id_Item_Longsword_1001",
      "item_type":       "EItemType::Weapon",
      "slot_type":       "Type.Item.Slot.Primary",
      "hand_type":       "Type.Item.Hand.TwoHanded",
      "weapon_types":    [ "Type.Item.Weapon.Sword" ],
      "rarity_type":     "Type.Item.Rarity.Epic",
      "gear_score":      50,
      "tradable":        true,
      "primary_property":     "Id_ItemProperty_Primary_Longsword_5001",
      "secondary_properties": [ "Id_ItemProperty_Secondary_Twohand_PhysicalWeapon" ],
      "abilities":            [ "Id_ItemAbility_LongswordAttack01", "..." ]
   },

   "links": [
      { "rel": "primary_property", "target": "id.item_property.primary_longsword_5001" },
      { "rel": "origin",           "target": "id.item.longsword_1001" },
      { "rel": "requires",         "target": "id.item_requirement.longsword_5001" },
      { "rel": "has_ability",      "target": "id.item_ability.longsword_attack01" }
   ]
}

Two layers compose every response:

  • Envelopeid, type, game, branch, name, tags, icon, links, patch. Same shape across every game and every type. The SDK and HTTP clients code against this layer.
  • data — the per-game, per-type projection of the upstream record. Keys are snake_cased, engine noise (Flags, Outer, Class, wrapper structs) is stripped, and upstream cross-reference names stay verbatim. No derived fields, no presentation logic, no rolled stats — presentation is an SDK concern.

Cross-references

Cross-references appear twice on purpose:

  • in data as the raw upstream key ("primary_property": "Id_ItemProperty_Primary_Longsword_5001") — verbatim from the game files.
  • in top-level links as { rel, target } pairs with codex-resolved ids — the adapter's projection.

The relationships are inherent to the game data; the codex adds the typed rel slug, the resolved canonical id, and a queryable entity_links graph table. Fields the adapter doesn't recognize stay in data only.

Hydrate

?hydrate=primary_property,origin follows links inline and returns the resolved entities under a hydrated key:

jsonc
{
   "id": "id.item.longsword_5001",
   ...,
   "hydrated": {
      "primary_property": null,
      "origin":           { "id": "id.item.longsword_1001", "name": "Longsword", ... }
   }
}

Every requested rel appears, with null for misses (target entity not yet imported as a Type) and the full entity row for hits. See the HTTP reference for query syntax.

Listing

Filter, search, paginate over a single type:

The full filter grammar (filter[data.gear_score:gte]=100, filter[tags]=weapon, etc.) is documented in the HTTP reference.

Tombstones

Removals are tombstones — a row written with data: null. 404 from the HTTP API indicates either "entity does not exist" or "exists but tombstoned at this patch". The history endpoint distinguishes them via is_tombstone: