Introduction

Many of us pour thousands of hours into the work of creating marked up document collections. When we are finally ready to share them with the wider community, we then encounter a whole new set of challenges. How do we make them FAIR: findable, accessible, interoperable, and reusable? How do we go beyond just posting the text for human readers, with a PDF or HTML representation, and expose them to machine clients of all kinds, from aggregators to NLP pipelines? How do we convey to those machine clients not only the internal structure of the individual texts, but also the relationships of those documents to one another? How do we provide metadata about the collections themselves? How do we make it possible to reference and access specific parts of the text?

Shared markup schemes like TEI gave us standard tools to express the structure and semantics of the texts. They let us build an ecosystem of tools, from XML Stylesheets (XSLT) that produce static websites to more dynamic ones such as TEI Publisher. They helped us to maximize the reach and usefulness of the texts we produce by, for example, allowing texts from various projects to be readily understood and combined even in unanticipated contexts. The reality has not always lived up to the promise, and standards can be applied in incompatible ways, despite the best efforts of their framers. Still, standards like TEI have made our work far more interoperable and reusable than before.

The Distributed Text Services (DTS) API specification likewise offers a common, interoperable pattern for exposing, accessing and traversing document collections. It is aimed chiefly at those building or hosting a DTS API—service implementers and corpus maintainers—though anyone preparing TEI markup for eventual publication may also want to understand its data model, since it can inform decisions about how consistently metadata and citation structure are encoded in the source documents themselves. Beyond just helping to make text collections FAIR, an API implementing DTS can make complex document structures more readily accessible and can enrich the semantics of the texts it exposes. This paper presents DTS 1.0, the first stable release of the specification, published on February 13, 2026, the fruit of nearly a decade of iteration, implementation, and community feedback.

What Is the Distributed Text Services API Specification?

DTS[1] is a RESTful API specification for publishing and navigating collections of marked up texts. It provides effective ways for data providers to enable clients—with no prior knowledge of the corpus—to browse collections of texts with standardized metadata, read or download those texts (in whole or in part) programmatically, and to reference parts of texts without having to parse any of the documents themselves.

With access to a DTS 1.0 API, a machine client can:

  • traverse collections of related documents in a standardized catalog;

  • download whole documents;

  • discover a document’s citation structure and referencing scheme (chapters, lines, pages, etc.);

  • retrieve extracts (such as pages) from documents by citation reference;

  • retrieve linked metadata about a document, a collection of documents, or even document extracts.

Such an API facilitates everything from building a table of contents for a single work, to traversal of documents with complex internal structures, to discovery of complex semantic relationships among documents across different corpora. For corpus owners and developers, it provides a ready-made way to share open textual data in a way that is interoperable, highly adaptable to different domains and use cases, and able to add significant semantic value—all in a way that is highly accessible for everything from simple reader clients to natural language processing pipelines.

Of course, a specification is useful only if it is adopted. Open access projects that currently implement the DTS 1.0 release candidate specification include DraCor: Open Infrastructure for Drama Analysis,[2] the CoMMA[3] collection of Medieval Latin and Old French manuscripts, and École Nationale des Chartes.[4] Several other projects are in the process of implementing the full DTS 1.0 specification, including the very large set of collections of the Text Service Infrastructure.[5] (See the list of known implementations on the DTS website[1].)

One of the chief benefits of a standard is the opportunity it creates to build interoperable tools. The DTS community has also produced a growing collection of tools to help implement the specification, including a validation toolkit[6] developed by Matteo Romanello; myDapytains,[7] a generic Python implementation using a Flask web front-end; DoTS,[8] a BaseX implementation of the services; and even an XSLT-based implementation of the most complex parts of the specification involving extract and citation retrieval.[9]

While the DTS specification allows for the use of JSON-LD’s full expressive power, it also mandates a flat representation of the data to enable wider reusability by communities with no interest in linked data but otherwise interested in sharing portions of texts and browsable catalogs. Every DTS endpoint returns JSON-LD conforming to a strict, fully specified JSON schema, so clients with no interest in linked data can treat any response as plain JSON and navigate it with ordinary key lookups. The one exception is textual content itself: TEI XML (or any other markup format a Document endpoint chooses to serve) is returned only from the Document endpoint, and is never embedded inside a JSON or JSON-LD structure—so clients never have to parse one markup language out of another.

The DTS 1.0 Data Model

Before examining the API’s four endpoints in detail, it is useful to define the core objects that the DTS 1.0 specification employs. All DTS responses are expressed in JSON-LD, and every object carries a @type property that identifies it as one of the types described below.

Collections and Resources

A Collection is the organizing unit of a DTS API. Rather than a simple container, a Collection is a node in a directed graph of records whose purpose is to curate access to information and texts: a Collection may have more than one parent, since the same Resource or sub-Collection is often meaningfully grouped in more than one way at once (see below), and simple trees cannot express that. It does not itself hold readable content; instead, it organizes records into meaningful groupings and carries metadata that describes the principle behind each grouping.

A Resource is best understood as a readable Collection: like a Collection, it is a cataloging node that groups records and carries metadata, but it also corresponds to an actual document that can be retrieved and read. A Resource can be navigated via the Navigation endpoint and retrieved via the Document endpoint. It is the point in the catalog graph where the organizational structure meets textual content—and it is within a Resource that CitableUnits (defined below) come into play.

Because a Resource may appear as a member of any number of Collections simultaneously, the graph of collections is a flexible cataloging structure rather than a strict document tree. The same texts can be organized by chronological period in one branch, by subject in another, and by genetic origin in a third—all without duplicating any record. Each path through the graph represents a curatorial choice: a deliberate statement about how a set of texts relate, expressed in shared metadata that machine clients can read and reason over.

CitableUnits and CitationTrees

One of the distinctive contributions of DTS is the ability to expose and retrieve chunks of a text directly through the API. A DTS API does not merely point to a document and leave the client to parse it, rather it serves any portion of that document on demand, identified by a structured reference. This builds on a long-standing practice in classical and humanistic scholarship, where canonical reference systems—Aeneid 1.1, Nicomachean Ethics 1106a14—allow scholars to cite and locate passages precisely without transmitting entire works. DTS formalizes and extends this practice into the digital API layer.

A CitationTree is the formal model of one such citation scheme for a Resource. It defines the set of named division types (CiteTypes) and the ways they may be nested, expressed as a recursive citeStructure array. A single Resource may carry multiple CitationTrees, one for each distinct scheme it supports. This is where DTS goes beyond traditional reference practice: it can represent simultaneously a material organization of the text (gatherings, pages, columns) and one or more narrative or intellectual structures (books and chapters, acts and scenes, entries in a journal). Each CitationTree is an independent, self-consistent model of the text’s structure, and clients are free to choose whichever scheme suits their purpose.

A CitableUnit is the addressable node within one of these trees: a single portion of a Resource identified by a reference string, placed at a given level in the hierarchy, and typed according to its CitationTree (e.g., "chapter", "page", "line"). A CitableUnit may also carry dublinCore and extensions metadata, making it possible to expose section-level information—titles, dates, authors of individual chapters—without requiring clients to parse the document itself. This combination of addressability, typed structure, and inline metadata is what allows a DTS API to serve as a first-class interface for scholarly citation, not merely a file delivery system.

A Shared Metadata Model

A deliberate design principle of DTS 1.0 is that every object in the model— Collection, Resource, and CitableUnit alike—shares the same metadata system. Each node may carry a dublinCore object containing any property expressible in Dublin Core Terms (title, creator, date, language, subject, and so on), and an extensions object for terms drawn from any other ontology or custom vocabulary. The extensions object carries its own nested @context, which extends the DTS JSON-LD context to define the additional terms in use.

This uniformity has practical consequences. A client that knows how to read metadata from a Collection already knows how to read it from a Resource or a CitableUnit; no special-casing is needed. For implementors, a single metadata-handling layer covers the entire object graph, reducing the complexity of both server and client codebases. More importantly, it means that metadata can be exposed, normalized, and enriched at any level of the hierarchy—on an entire corpus, on a collected subset of documents, on an individual document, or on a single chapter—without ever requiring a client to parse the underlying XML or have any prior knowledge of the document’s internal structure.

This last point is significant. In practice, document collections are often heterogeneous: contributors encode metadata inconsistently, licenses may prohibit modification of source files, and harmonizing markup across a large corpus can be prohibitively expensive. The DTS metadata layer provides an independent surface for description that accompanies the documents without depending on them. Shared attributes can be expressed once at the appropriate Collection level rather than repeated in every document header; individual Resource or CitableUnit objects can carry metadata that simply does not exist in the source markup, or is too complex for a client to parse from that markup.

Finally, because all metadata objects are expressed in JSON-LD with full context definitions, the same descriptions that serve a lightweight JSON consumer can, for those who choose to exploit it, participate in the broader linked data ecosystem. Implementations may remain entirely agnostic about linked data while still producing responses that are interpretable as RDF—a spectrum of reuse that the shared metadata model makes possible without imposing any additional burden on either implementers or clients.[10]

Implementing a DTS 1.0 API

A DTS 1.0 API exposes a set of four endpoints that together serve both metadata and documents:

  • the Entry endpoint, which provides discovery information;

  • the Collection endpoint, for traversing text collections;

  • the Navigation endpoint, for exploring a text’s internal structure;

  • the Document endpoint, for retrieving portions of a text.

All four endpoints return JSON-LD, and the DTS context is always available via the @context property. However, DTS 1.0 also mandates a strict, predictable JSON structure for every response: property names, object shapes, and nesting are fully specified, so a client can treat any DTS response as plain JSON and navigate it with ordinary key lookups—no JSON-LD processor, no RDF library, no knowledge of linked data is required. This dual nature is deliberate: it keeps the door open to the full expressiveness of linked data for implementers who want it, while ensuring that the broadest possible audience of developers can build clients with the tools they already know.

The Entry Endpoint

The Entry endpoint is the root of a DTS API. It provides the information a client needs to use the API: the URI templates for constructing requests to the other three endpoints, the standard DTS JSON-LD context that interprets those responses, and the version of the DTS standard the current API adheres to.

                     
{
  "@context": "https://dtsapi.org/context/v1.0.json",
  "dtsVersion": "1.0",
  "@id": "/api/dts/",
  "@type": "EntryPoint",
  "collection": "/api/dts/collection/{?id,page,nav}",
  "navigation": "/api/dts/navigation/{?resource,ref,start,end,down,tree,page}",
  "document": "/api/dts/document/{?resource,ref,start,end,tree,mediaType}"
}

The URI templates follow RFC 6570 syntax. An implementation is free to define its own URL structure—the templates in the Entry response are the single authoritative source of how to construct requests, so clients never need to guess or hard-code paths.

The Collection Endpoint: Exploring Collections

The Collection endpoint allows clients to traverse Collections and sub-collections and to learn about their contents. A request to a URL such as /api/dts/collection/?id=articles returns a Collection object that includes a list of the collection’s members (which may be Resources, sub-Collections, or a mix), the total number of parents and children, and pagination for large collections.

                     
{
  "@context": "https://dtsapi.org/context/v1.0.json",
  "dtsVersion": "1.0",
  "@id": "lasciva_roma",
  "@type": "Collection",
  "collection": "/api/dts/collection/{?id,page,nav}",
  "totalParents": 1,
  "totalChildren": 3,
  "title": "Lasciva Roma",
  "description": "Collection of primary sources for the study of Ancient World sexuality",
  "dublinCore": {
    "creator": ["Thibault Clerice", "http://orcid.org/0000-0003-1852-9204"],
    "title": [{ "lang": "la", "value": "Lasciva Roma" }]
  },
  "member": [
    {
      "@id": "urn:cts:latinLit:phi1103.phi001",
      "title": "Priapeia",
      "@type": "Collection",
      "collection": "/api/dts/collection/?id=urn:cts:latinLit:phi1103.phi001{&page,nav}",
      "totalParents": 1,
      "totalChildren": 1
    }
  ]
}

This sample response illustrates the shared metadata model described above: the dublinCore object is immediately readable as plain JSON, requiring no linked data tooling, while remaining fully interpretable as RDF for clients that wish to exploit it. Note that the @id values in these examples—including the CTS URN urn:cts:latinLit:phi1103.phi001—are implementation-defined; DTS does not require CTS URNs or any other particular identifier scheme, and implementers are free to use plain URLs, UUIDs, or other conventions suited to their corpus.

The Document Endpoint: Retrieving Sections of Marked-Up Text

The Document endpoint provides access to the actual textual content of a Resource. The download links in Navigation endpoint responses point here, and the CitableUnit identifiers from Navigation responses can be used to request specific sections.

It is strongly recommended that a DTS Document endpoint serve textual data at least as TEI XML, since this provides clients with a predictable response format. This is not a hard requirement (SHOULD, not MUST) and an implementation can be fully DTS-compliant without serving TEI. The optional mediaType query parameter may be used to serve multiple response formats (e.g., TEI XML, EPub, HTML).

A request for a single CitableUnit uses the ref parameter:

/api/dts/document/?resource=dracula&ref=C1

A range of units uses start and end:

/api/dts/document/?resource=dracula&start=C1&end=C3

If none of these parameters is included, the entire Resource is returned. Chunks of a TEI XML document are returned wrapped in a special dts:wrapper element, signaling to the recipient that the response is only part of a larger text:

                     
<?xml version="1.0" encoding="UTF-8"?>
<TEI xmlns="http://www.tei-c.org/ns/1.0">
  <dts:wrapper xmlns:dts="https://w3id.org/api/dts#">
    <!-- XML or string of the passage requested here -->
  </dts:wrapper>
</TEI>

Conformance Levels: Supporting Static APIs

All DTS 1.0 servers must implement all four endpoints and support all valid calls as documented. The flexibility of the standard means that nearly all of this can be implemented using a static site generator and pre-composed responses: an implementation is free to define its own URL template and rely entirely on URL path segments rather than query parameters.

The one feature that is difficult for most static sites is the start and end range parameters on the Navigation and Document endpoint. The number of possible reference ranges at every possible depth in a Resource’s citation tree is usually too large to pre-generate as static pages.

DTS 1.0 therefore defines two conformance levels, specifically to make the standard accessible to static site implementations:

Level 1 (full conformance)

The server supports all valid calls as documented in the specification, including start/end range queries on the Navigation and Document endpoint.

Level 0 (static-site conformance)

The server fulfills all MUST requirements of the specification except support for start and end parameters on the Navigation and Document endpoint. A Level 0 server SHOULD raise an error if those parameters are used. This level is specifically designed to allow fully DTS-compliant implementations based on static file generation, reducing the pre-generated citation tree segments to a manageable number.

Level 0 conformance is thus not a lesser standard but a deliberate design decision: it opens the DTS ecosystem to projects that cannot or do not wish to run a dynamic server, while still enabling the full collection browsing, document retrieval, and citation-tree navigation capabilities that make DTS valuable.

Conclusion

DTS 1.0 is the result of nearly a decade of collaborative work spanning continents, institutions, and disciplines. Reaching a stable 1.0 release was a long road—one that required sustained effort from a community willing to iterate, argue, implement, and iterate again. What drove that effort was a shared conviction that something was missing from the XML infrastructure for sharing texts: a common, machine-readable interface that would let corpora speak to one another and to the tools we build around them, without requiring every project to reinvent the wheel. We believe DTS fills that gap.

The work is not finished. The specification points toward future extensions, chief among them a standardized system for search—both faceted metadata search over collections and full-text search within documents—that would bring discoverability to the same level of interoperability that DTS already provides for browsing, citation, and retrieval. That work is ongoing.

What matters most now is adoption. A standard only becomes infrastructure when it is put to use in ways its authors did not anticipate. The implementations already in production—from drama corpora to medieval manuscripts to classical texts—are proof that DTS can travel across domains. We look forward to seeing implementers make it their own: extending it, stressing it, and building on it the kinds of tools and corpora that none of us could build alone.



[1] https://dtsapi.org/specifications/

[2] https://dracor.org/api/v1/dts

[3] https://comma.inria.fr/api

[4] https://dots.chartes.psl.eu/demo/api/dts/

[5] https://urncts.eu/

[6] https://github.com/distributed-text-services/validator

[7] https://github.com/distributed-text-services/MyDapytains

[8] https://github.com/chartes/dots

[9] https://github.com/SCDH/dts-transformations

[10] A natural alternative would be an XPath-addressable document or a flat catalog of ID-to-ID ranges. These presuppose a client that already knows the corpus’s schema or identifier conventions; DTS instead lets a client discover citation structure and metadata at request time, without prior knowledge of a given corpus’s markup or database layout.

Author's keywords for this paper:
Distributed Text Services; DTS 1.0; API specification; TEI; document collections; FAIR data; JSON-LD