Introduction

In February 2026, the v1.0 of the Distributed Text Services (DTS) specification was officially released — a standard API for accessing text collections.

This article documents the changes required to migrate the Kouigenji Monogatari Text Database DTS API from 1-alpha to 1.0.

https://github.com/distributed-text-services/specifications/releases/tag/v1.0

What is DTS?

DTS defines a standard API for accessing text collections such as TEI/XML. It consists of four endpoints:

EndpointPurpose
Entry PointReturns URLs for each API endpoint
CollectionInter-text navigation (listing collections and resources)
NavigationIntra-text navigation (exploring citation structures)
DocumentRetrieving text content (full or partial TEI/XML)

Target Project

A TypeScript/Express.js implementation of DTS for the Kouigenji Monogatari Text Database.

Key Changes from 1-alpha to 1.0

1. JSON-LD Context URL Change

The most fundamental change is the JSON-LD context file URL.

- "@context": "https://distributed-text-services.github.io/specifications/context/1-alpha1.json"
+ "@context": "https://dtsapi.org/context/v1.0.json"

The domain changed from distributed-text-services.github.io to dtsapi.org, reflecting the assignment of a persistent URL with the official release.

2. dtsVersion Update

- "dtsVersion": "1-alpha"
+ "dtsVersion": "1.0"

The dtsVersion field in all endpoint responses must be updated.

3. Full Parameter Listing in URI Templates

In 1-alpha, only some parameters were listed, but 1.0 requires all accepted parameters in URI templates.

Entry Point response example:

{
-   "collection": "/api/v2/dts/collection{?id}",
-   "navigation": "/api/v2/dts/navigation{?resource,ref,down}",
-   "document": "/api/v2/dts/document{?resource,ref}"
+   "collection": "/api/v2/dts/collection{?id,page,nav}",
+   "navigation": "/api/v2/dts/navigation{?resource,ref,start,end,down,tree,page}",
+   "document": "/api/v2/dts/document{?resource,ref,start,end,tree,mediaType}"
}

Added parameters:

ParameterEndpointPurpose
pageCollection, NavigationPagination
navCollectionchildren (default) or parents
start / endNavigation, DocumentRange specification (mutually exclusive with ref)
treeNavigation, DocumentCitation Tree selection
mediaTypeDocumentResponse media type specification

4. Stricter Content-Type

JSON responses that used application/json in 1-alpha must now use application/ld+json in 1.0.

// JSON-LD responses (Entry Point, Collection, Navigation)
res.set("Content-Type", "application/ld+json");

// Document responses
res.set("Content-Type", "application/tei+xml");
EndpointOld Content-TypeNew Content-Type
Entry Point / Collection / Navigationapplication/jsonapplication/ld+json
Documentapplication/xmlapplication/tei+xml

Document endpoint responses now require a Link header pointing to the Collection endpoint.

res.set("Link", `</api/v2/dts/collection?id=${resource}>; rel="collection"`);

Example response headers:

Content-Type: application/tei+xml; charset=utf-8
Link: </api/v2/dts/collection?id=urn:kouigenjimonogatari.1>; rel="collection"

6. Changed Behavior of Navigation down Parameter

In 1-alpha, down had a default value, but in 1.0 its presence or absence significantly changes behavior.

downrefBehavior
absentabsent400 Bad Request
absentpresentReturn ref info only (no member array)
1+absentReturn member array from root to specified depth
1+presentReturn member array from ref to specified depth
-1eitherReturn all levels to deepest
0presentReturn siblings sharing same parent as ref
// 1-alpha: default down=1
if (down === undefined) {
  down = "1";
}

// 1.0: 400 if down, ref, and start/end are all absent
if (down === undefined && !ref && !start && !end) {
  res.status(400).json({ error: "down, ref, or start/end is required" });
  return;
}

7. CitableUnit identifier Field

Navigation response ref objects now use identifier instead of @id.

  navigationData["ref"] = {
-   "@id": refString,
+   "identifier": refString,
    "@type": "CitableUnit",
    "level": 1,
    "parent": null,
    "citeType": "page"
  }

8. Parameter Validation

DTS 1.0 requires clear 400/404 responses for invalid parameter combinations.

// ref and start/end are mutually exclusive
if (ref && (start || end)) {
  res.status(400).json({ error: "ref cannot be used with start/end" });
  return;
}

// start and end must be used together
if ((start && !end) || (end && !start)) {
  res.status(400).json({ error: "start and end must be used together" });
  return;
}

Level 0 and Level 1

DTS 1.0 defines conformance levels:

  • Level 0: start/end parameter implementation not required (intended for static file implementations)
  • Level 1: Full parameter support

This implementation targets Level 0 conformance. All parameters are listed in URI templates, but start/end return validation errors when used. This is correct behavior per the specification.

A Level 0 DTS Server need not support the start and end parameters for the Navigation endpoint. It SHOULD raise an error if either of these parameters are used in a request.

Waka Navigation with Multiple Citation Trees

DTS 1.0 allows defining multiple Citation Trees per resource. The Kouigenji Monogatari TEI/XML contains waka (tanka poems) embedded as <lg type="waka"> elements.

<lg xml:id="waka-001" type="waka" rhyme="tanka">
  <l n="1">かきりとて</l>
  <l n="2">わかるゝ道の</l>
  <l n="3">かなしきに</l>
  <l n="4">いかまほしきは</l>
  <l n="5">いのちなりけり</l>
</lg>

A dedicated waka Citation Tree was added alongside the default page/line navigation.

citationTrees Definition

{
  "citationTrees": [
    {
      "@type": "CitationTree",
      "citeStructure": [
        { "citeType": "page", "citeStructure": [{ "citeType": "line" }] }
      ]
    },
    {
      "@type": "CitationTree",
      "identifier": "waka",
      "description": "Citation structure by waka (tanka) poems",
      "citeStructure": [
        { "citeType": "waka", "citeStructure": [{ "citeType": "ku" }] }
      ]
    }
  ]
}

Per DTS 1.0:

  • The default Citation Tree (first) has no identifier
  • Subsequent Citation Trees have an identifier
  • description is optional for human-readable explanation

Using the tree Parameter

Clients switch between Citation Trees using the tree parameter.

# Default (page/line) navigation
/navigation?resource=urn:kouigenjimonogatari.1&down=1

# Waka tree listing
/navigation?resource=urn:kouigenjimonogatari.1&tree=waka&down=1

# Waka tree all levels (poems + verses)
/navigation?resource=urn:kouigenjimonogatari.1&tree=waka&down=-1

# Get a specific waka's XML
/document?resource=urn:kouigenjimonogatari.1&tree=waka&ref=waka-001

# Get only the 3rd verse
/document?resource=urn:kouigenjimonogatari.1&tree=waka&ref=waka-001.3

Implementation Notes

Citation Trees are defined in src/utils/citationTrees.ts and shared across Collection, Navigation, and Document endpoints.

The Navigation endpoint dispatches to different member map building functions based on the tree parameter:

if (treeString === "waka") {
  buildWakaMembersMap(xmlDoc, membersMap);  // Traverse <lg type="waka">
} else {
  buildDefaultMembersMap(xmlDoc, membersMap);  // Traverse <seg corresp="...">
}

The Document endpoint extracts <lg xml:id="waka-001"> when tree=waka and ref=waka-001 are specified. For verse-level references (ref=waka-001.3), only the matching <l n="3"> is returned.

Test Suite

Tests were added using vitest with 29 test cases verifying DTS 1.0 compliance.

npm test

Tests cover:

  • Response format for each endpoint (Context URL, dtsVersion, @type)
  • Content-Type headers (application/ld+json, application/tei+xml)
  • Full parameter listing in URI templates
  • Document Link header
  • Validation (400/404 errors)
  • Navigation down parameter behavior
  • Waka navigation (tree=waka) poem and verse retrieval
  • Waka document retrieval (full poem, single verse)

Changed Files

FileChanges
src/api/v2/dts.tsContext URL, dtsVersion, URI templates, Content-Type
src/api/v2/collection.tsSame + page/nav params, shared citationTrees
src/api/v2/navigation.tsSame + down behavior, validation, identifier, tree=waka
src/api/v2/document.tsContent-Type application/tei+xml, Link header, validation, tree=waka
src/utils/citationTrees.tsShared Citation Trees module (new)
src/__tests__/dts-v2.test.ts29 vitest test cases

Conclusion

DTS 1.0 is a specification refined through years of development and interoperability testing. While changes from 1-alpha are relatively small, they include production-oriented improvements such as stricter Content-Type handling and parameter validation.

By implementing a DTS-compliant API when publishing TEI/XML texts in Digital Humanities, interoperability with existing DTS clients is achieved.

References