What Is TDMRep and How Do You Implement It in 2026?

TDMRep is the W3C protocol for declaring, in machine-readable form, that text and data mining rights over your content are reserved. This page covers the well-known file, the HTTP response headers and the ODRL policy document, with code you can ship today.

CategoryCrawler access, licensing & indexing StatusW3C Community Group Report Maintained byW3C TDM Reservation CG Glippy checkMachine Readability (category 6)

TDMRep (TDM Reservation Protocol) is a W3C Community Group specification for stating, in machine-readable form, whether text and data mining rights over a web resource are reserved, and where a mining licence can be obtained. It carries exactly two properties, tdm-reservation (the integer 1 or 0) and an optional tdm-policy URL, published through a well-known JSON file, HTTP response headers, or HTML meta tags. It exists to satisfy the machine-readable reservation condition set by Article 4 of the EU Copyright in the Digital Single Market Directive.

Why TDMRep matters for AI visibility

Article 4 of EU Directive 2019/790 lets any organisation mine lawfully accessible content for any purpose, including commercial purposes, unless the rightsholder has expressly reserved that use "in an appropriate manner, such as machine-readable means". TDMRep is the W3C-backed way of making that reservation, and it is the only one of the current signals written specifically against that legal test. The pressure behind it increased with the EU AI Act: general-purpose AI providers must put a copyright policy in place, and Measure 1.3 of the GPAI Code of Practice commits signatories to honour robots.txt per RFC 9309 plus other appropriate machine-readable protocols that are adopted by standards bodies or are state of the art. The European Commission ran a consultation from 1 December 2025 to 23 January 2026, with EUIPO support, to agree a published list of which protocols those are. This page describes the protocol, not the law, and none of it is legal advice.

Treat TDMRep as a training-rights signal, not a visibility lever. Reserving TDM rights does not block a fetch, does not remove you from AI answers, and has no effect on whether an assistant retrieves or cites your page, so there is no visibility cost to publishing it. It also sits in a different place to its neighbours: RSL attaches licensing and payment terms to content, and Content Signals expresses separate preferences for search, AI input and AI training inside robots.txt. TDMRep says one narrow thing, in the vocabulary an EU court is most likely to recognise. Outside the EU there is generally no equivalent statutory opt-out, and the specification itself notes that exclusive rights remain in force there, so the absence of a reservation cannot be read as permission. Publishing TDMRep outside the EU records intent; it does not create an enforcement mechanism.

Where the spec lives

The Final Community Group Report is short and normative, and everything else here is context for how it is being read in 2026.

Three ways to implement TDMRep

Start with the well-known file: it is a static asset, it covers an entire origin, and it needs no server configuration. Add HTTP response headers when you need per-resource control or when the resources are PDFs and images that cannot carry a meta tag. Finally, publish the ODRL policy document that tdm-policy points at, which is what turns "rights reserved" into "rights reserved, and here is how to license them".

01

Site-wide reservation in /.well-known/tdmrep.json

The baseline for any site. One static file at the origin root declares rules for whole path prefixes, so a single deploy covers HTML pages, PDFs, images and API responses alike. This is the first thing a conforming TDM agent fetches, before it scrapes anything.

json/.well-known/tdmrep.json
[
  {
    "location": "/press/",
    "tdm-reservation": 0
  },
  {
    "location": "/docs/*.pdf",
    "tdm-reservation": 1,
    "tdm-policy": "https://example.com/policies/tdm-policy.json"
  },
  {
    "location": "/blog/",
    "tdm-reservation": 1,
    "tdm-policy": "https://example.com/policies/tdm-policy.json"
  },
  {
    "location": "/",
    "tdm-reservation": 1,
    "tdm-policy": "https://example.com/policies/tdm-policy.json"
  }
]

What this does: a TDM agent fetches this file once, caches it, and matches every URL it later requests against the location patterns, taking the most specific match, which the spec defines as the first one in sequence. Press releases are explicitly released for mining with 0, everything else is reserved with a licensing route attached, and the trailing "/" rule is the catch-all that must come last.

02

Per-resource reservation with HTTP response headers

Use headers when the reservation varies by resource rather than by path prefix, when you want the signal to travel with a file that has been hotlinked or proxied, or when your content is served from object storage where you cannot write to /.well-known. Header values supersede whatever the well-known file said for the same URL.

nginx/etc/nginx/conf.d/tdmrep.conf
server {
  server_name example.com;

  # Site-wide default: TDM rights reserved, terms at the policy URL.
  add_header tdm-reservation 1 always;
  add_header tdm-policy https://example.com/policies/tdm-policy.json always;

  # nginx does not merge add_header across levels. Any location that sets
  # a header of its own must repeat every header it still needs.
  location /press/ {
    add_header tdm-reservation 0 always;
  }

  location /docs/ {
    add_header tdm-reservation 1 always;
    add_header tdm-policy https://example.com/policies/tdm-policy.json always;
  }

  location = /.well-known/tdmrep.json {
    default_type application/json;
    add_header Cache-Control "public, max-age=3600" always;
    add_header tdm-reservation 1 always;
  }
}

# Verify:  curl -sI https://example.com/docs/report.pdf | grep -i '^tdm-'

What this does: every response now carries the reservation on the wire, so an agent that fetched a PDF directly still sees it without parsing the document or re-reading the well-known file. Apache is the same idea with mod_headers and a Header set tdm-reservation "1" directive; on a CDN, add the headers as an edge response rule so they are not stripped by the cache.

03

A machine-readable TDM policy in ODRL JSON-LD

Only needed if you set tdm-policy, and required if you do. The policy is an ODRL 2.2 Offer that tells a mining actor who to contact and on what terms a licence is available. A tdm-policy URL that 404s or returns an unmarked HTML page teaches an agent nothing.

json/policies/tdm-policy.json
{
  "@context": [
    "http://www.w3.org/ns/odrl.jsonld",
    "http://www.w3.org/ns/tdmrep.jsonld"
  ],
  "@type": "Offer",
  "profile": "http://www.w3.org/ns/tdmrep",
  "uid": "https://example.com/policies/1",
  "assigner": {
    "uid": "https://example.com",
    "vcard:fn": "Example Publishing Ltd",
    "vcard:nickname": "Example",
    "vcard:hasEmail": "mailto:[email protected]",
    "vcard:hasURL": "https://example.com/legal/tdm-licensing"
  },
  "permission": [
    {
      "target": "https://example.com#all-content",
      "action": "tdm:mine",
      "duty": [
        { "action": "obtainConsent" }
      ]
    },
    {
      "target": "https://example.com#all-content",
      "action": "tdm:mine",
      "duty": [
        { "action": "compensate" }
      ],
      "constraint": [
        {
          "leftOperand": "purpose",
          "operator": "eq",
          "rightOperand": "tdm:non-research"
        }
      ]
    }
  ]
}

What this does: the first permission says an actor may mine the content after obtaining consent, the second says a non-research actor may mine it against payment. Serve it with a content type of application/json or application/ld+json, because the report treats text/html policies as human-readable only. The report flags tdm:research and tdm:non-research as experimental, so keep a human-readable licensing page at vcard:hasURL as the fallback.

Implementation guidelines

These are the details that decide whether a TDM agent reads your reservation correctly or silently treats it as unset.

  1. Know the processing order. Agents check the well-known file, then HTTP headers, then HTML meta tags, then EPUB and PDF metadata, and each later layer supersedes the one before it. Crucially, the absence of a property at a later layer never resets a value already found, so a page with no meta tag keeps whatever the file or header said.
  2. The document root is an array. Even a single rule must be wrapped in [ ... ]. Each object needs location and tdm-reservation; tdm-policy is optional. An object wrapper is the most common reason a file parses as JSON but is ignored as TDMRep.
  3. Order rules narrowest first. The spec resolves ties by taking the most specific match, and defines the most specific match as the first in sequence, so a leading "/" catch-all will swallow everything below it. Matching should be case sensitive and supports * and $ using the same rules as robots.txt.
  4. Use the integers 1 and 0, nothing else. Any other value is a protocol error and the agent must treat tdm-reservation as unset, which is worse than not publishing at all. Do not send true, "yes", or a quoted "1" in the JSON file.
  5. Check your CDN and cache layer. Edge caches routinely strip unknown response headers, and a header set on the HTML origin will not reach PDFs or images served from a separate bucket. Verify with curl -sI against a production URL of each content type, not against localhost.
  6. Give per-page overrides a reason to exist. The HTML technique is <meta name="tdm-reservation" content="1"> and <meta name="tdm-policy" content="https://example.com/policies/tdm-policy.json">. The report says rightsholders should pick one technique, so use meta tags for genuine per-page exceptions rather than duplicating a site-wide rule on every template.
  7. Keep it separate from crawler control. TDMRep reserves rights over content that has already been lawfully accessed; it does not deny the request. If you also want to stop the fetch, that is robots.txt and crawler-level enforcement, and the two are routinely shipped together.

Do this, not that

Do

  • Serve /.well-known/tdmrep.json as a JSON array with a 200 status and a Content-Type of application/json.
  • Put the narrowest location patterns at the top of the array and the "/" catch-all at the bottom.
  • Set tdm-reservation headers on PDFs, images and downloads, which have no place to carry a meta tag.
  • Point tdm-policy at a policy that includes a real contact route, at minimum vcard:hasEmail or vcard:hasURL.

Do not

  • Do not rely on a copyright line in your terms of use as the reservation. The Hamburg appeal court (5 U 104/24, 10 December 2025) held that a human-readable notice of that kind was not enough.
  • Do not write "tdm-reservation": "1" or "tdm-reservation": true. The spec defines the integers 1 and 0.
  • Do not wrap the rules in an object such as {"tdmrep": [...]}. The report defines the file as a bare array.
  • Do not copy the header examples from the older technique notes in the repo, which still use a header name that the final report replaced with tdm-reservation.

How Glippy checks this

Glippy fetches /.well-known/tdmrep.json on every scan and parses it as an array of reservation entries, requiring each one to carry both location and tdm-reservation. A valid file passes and reports how many rules it found, a file that is reachable but does not parse into usable entries raises a warning, and a page-level meta name="tdm-reservation" tag counts as a pass when no site-wide file is present. It scores under Machine Readability, category 6, alongside the other agent-facing files at the origin: see the machine readability checker for the full category.

Check your TDMRep setup

Glippy runs 240+ checks across 16 categories on any page, including Machine Readability (category 6). No sign-up required.

Frequently asked questions

No. TDMRep is a declaration of rights, not an access control, and nothing in the protocol denies a request. A crawler that ignores tdm-reservation: 1 still receives the content; the consequence is legal rather than technical, and only in jurisdictions where a reservation has effect. If you want to stop the fetch itself, use robots.txt, a WAF rule or bot management alongside TDMRep.

They do different jobs. A robots.txt Disallow asks a named crawler not to fetch a path, which says nothing about content already gathered lawfully by other means, such as a licensed feed or a third-party dataset. TDMRep asserts a reservation of text and data mining rights over the content itself, which is the condition Article 4 of the EU DSM Directive turns on. Most publishers who have adopted TDMRep ship both.

The W3C report says rightsholders should use only one, and defines a processing order for when they do not: the well-known file first, then HTTP headers, then HTML meta tags, then EPUB and PDF metadata, with each later layer superseding the one before. The file at /.well-known/tdmrep.json is the least work and covers a whole origin including binaries, so it is the sensible default. Headers are the better choice when the reservation varies per resource or when you cannot write to the origin root.

The specification is written against Article 4 of EU Directive 2019/790, and the machine-readable opt-out it implements is an EU construct. Outside the EU there is generally no equivalent statutory opt-out, and the W3C report itself notes that the exclusive rights of rightsholders remain, so a missing reservation cannot be read as implied permission there either. Publishing TDMRep outside the EU is a clear, dated record of intent rather than a mechanism with statutory teeth. This is a technical glossary entry, not legal advice: take advice on your own jurisdiction.

Reviewed against the primary sources on . These standards move quickly, so check the linked specs before you ship.

Check your site for AI search readiness

Start free with the Glippy Chrome extension for instant page checks. Scaling up? Automate audits across many URLs and your whole sitemap with the Glippy MCP server.

Add Glippy to Chrome – free Automate with the MCP server →