Feed endpoints for Open Terms Archive collections
Context
Open Terms Archive collections currently rely on GitHub-generated Atom feeds to expose version changes to subscribers.
Problem statement
GitHub-generated feeds are outside OTA's control: their format, content, and filtering capabilities are dictated by GitHub. Collections cannot expose custom metadata, filter entries by service or terms type, or guarantee continuity if GitHub changes or discontinues this feature.
Proposed solution
The collection API exposes dedicated feed endpoints that generate and serve Atom feeds directly from the versions repository, without relying on any external platform.
Endpoints:
- GET
/feed Global feed (all services, all terms types), newest-first, limited to last N items (configurable, default 100)
- GET
/feed/:serviceId Filtered to a specific service
- GET
/feed/:serviceId/:termsType Filtered to a specific service and a specific terms type
Feed-level metadata:
<title> Collection name
<subtitle> Collection tagline
<id> urn:{namespace}:{collectionId}:{languages}:{jurisdictions}
<updated> Fetch date of most recent version
<link rel="self" href={feedBasePath} />
<author><name>OTA-Bot</name></author>
<logo> Collection logo URL
Entry-level metadata:
<id> {storageType}:{identifier} Storage type (Git or MongoDB) and unique identifier (SHA or ObjectId)
<link rel="alternate" type="text/html"> {apiBasePath}/version/{serviceId}/{termsType}/{fetchDate} Link to collection API route
<title> Mirrors Git commit message
<updated> Fetch date
<category term="{serviceId}" scheme="urn:ota:service" />
<category term="{termsType}" scheme="urn:ota:terms-type" />
<category term="{recordType}" scheme="urn:ota:record-type" />
Notes
- The three endpoints allow subscribers to choose their level of granularity: the global feed covers all activity across the collection, while the service and terms type filters let subscribers focus on what matters to them. For subscribers using the global feed, the elements on each entry expose the same filtering dimensions directly in the feed, allowing feed readers to apply client-side rules without requiring a separate subscription.
- If no versions match the request, an empty feed is returned, allowing subscribers to keep their subscription active and receive future entries.
- The Atom format is proposed because it benefits from clear, mandatory fields and unambiguous semantics as defined by the IETF standard, but also because it is flexible and extensible, supports custom elements and attributes, and is widely supported by feed readers.
Example: global feed response
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Demo</title>
<subtitle>Services used by Open Terms Archive</subtitle>
<id>urn:ota:demo:en:eu</id>
<updated>2024-03-15T10:30:00Z</updated>
<link rel="self" href="http://162.19.74.224/collection-api/v1/feed"/>
<author>
<name>OTA-Bot</name>
</author>
<logo>https://opentermsarchive.org/images/collections/demo.png</logo>
<entry>
<id>git:2bfa15dd66f89e8612f33875a5be799a45f4b50a</id>
<link rel="alternate" type="text/html">http://162.19.74.224/collection-api/v1/version/npm%20Public%20Registry/Copyright%20Claims%20Policy/2026-02-12T00%3A30%3A15Z</link>
<title>Record new changes of npm Public Registry Copyright Claims Policy</title>
<updated>2026-02-12T00:30:15Z</updated>
<category term="npm Public Registry" scheme="urn:ota:service"/>
<category term="Copyright Claims Policy" scheme="urn:ota:terms-type"/>
<category term="Change" scheme="urn:ota:record-type"/>
</entry>
<entry>
<id>git:b7c967be56caa71d700282880bca901565ec544d</id>
<link rel="alternate" type="text/html">http://162.19.74.224/collection-api/v1/version/Buffer/Terms%20of%20Service/2026-02-04T00%3A30%3A03Z</link>
<title>Record new changes of Buffer Terms of Service</title>
<updated>2026-02-04T00:30:03Z</updated>
<category term="Buffer" scheme="urn:ota:service"/>
<category term="Terms of Service" scheme="urn:ota:terms-type"/>
<category term="Change" scheme="urn:ota:record-type"/>
</entry>
<entry>
<id>git:3af22e88474e02fe99a69b92e8fdd0fa43f6756f</id>
<link rel="alternate" type="text/html">http://162.19.74.224/collection-api/v1/version/UptimeRobot/Terms%20of%20Service/2025-09-22T15%3A54%3A35Z</link>
<title>Apply technical or declaration upgrade on UptimeRobot Terms of Service</title>
<updated>2025-09-22T15:54:35Z</updated>
<category term="UptimeRobot" scheme="urn:ota:service"/>
<category term="Terms of Service" scheme="urn:ota:terms-type"/>
<category term="Technical upgrade" scheme="urn:ota:record-type"/>
</entry>
<entry>
<id>git:4990c3bed01498668c93a7cabdacbe60478dccae</id>
<link rel="alternate" type="text/html">http://162.19.74.224/collection-api/v1/version/Brevo/Privacy%20Policy/2023-09-26T12%3A30%3A00.000Z</link>
<title>First record of Brevo Privacy Policy</title>
<updated>2023-09-26T12:30:00.000Z</updated>
<category term="Brevo" scheme="urn:ota:service"/>
<category term="Privacy Policy" scheme="urn:ota:terms-type"/>
<category term="First record" scheme="urn:ota:record-type"/>
</entry>
<!-- ... -->
</feed>
Feedback expectations
We invite you to provide feedback to:
- Point out any limitations or edge cases you see in the proposed implementation.
- Suggest improvements or refinements to the current proposal.
- Share any alternative approaches you believe could address the problem more effectively.
If you support the proposal as it stands, please react with a 👍 or leave a positive comment.
Please provide your feedback by April 14th.
Feed endpoints for Open Terms Archive collections
Context
Open Terms Archive collections currently rely on GitHub-generated Atom feeds to expose version changes to subscribers.
Problem statement
GitHub-generated feeds are outside OTA's control: their format, content, and filtering capabilities are dictated by GitHub. Collections cannot expose custom metadata, filter entries by service or terms type, or guarantee continuity if GitHub changes or discontinues this feature.
Proposed solution
The collection API exposes dedicated feed endpoints that generate and serve Atom feeds directly from the versions repository, without relying on any external platform.
Endpoints:
/feedGlobal feed (all services, all terms types), newest-first, limited to last N items (configurable, default 100)/feed/:serviceIdFiltered to a specific service/feed/:serviceId/:termsTypeFiltered to a specific service and a specific terms typeFeed-level metadata:
<title>Collection name<subtitle>Collection tagline<id>urn:{namespace}:{collectionId}:{languages}:{jurisdictions}<updated>Fetch date of most recent version<link rel="self" href={feedBasePath} /><author><name>OTA-Bot</name></author><logo>Collection logo URLEntry-level metadata:
<id>{storageType}:{identifier}Storage type (Git or MongoDB) and unique identifier (SHA or ObjectId)<link rel="alternate" type="text/html">{apiBasePath}/version/{serviceId}/{termsType}/{fetchDate}Link to collection API route<title>Mirrors Git commit message<updated>Fetch date<category term="{serviceId}" scheme="urn:ota:service" /><category term="{termsType}" scheme="urn:ota:terms-type" /><category term="{recordType}" scheme="urn:ota:record-type" />Notes
Example: global feed response
Feedback expectations
We invite you to provide feedback to:
If you support the proposal as it stands, please react with a 👍 or leave a positive comment.
Please provide your feedback by April 14th.