How to Publish a Standards-Compliant Atom 1.0 Feed
A task guide to publishing a valid Atom 1.0 feed: stable IRIs, RFC 3339 timestamps, typed text constructs, correct MIME delivery, and validation checks.
14 Aug 2026, 09:43 UTC

Desired Outcome
Publish an Atom 1.0 feed (RFC 4287) that passes schema validation and is ingested reliably by aggregators. A compliant feed requires three mandatory elements at both the feed and entry level, RFC 3339 timestamps with timezone offsets, text constructs that declare their type, and delivery with the application/atom+xml MIME type. Getting these details right prevents duplicate entries in readers and avoids silent parse failures.
Prerequisites
- A server, static site generator, or application that can emit XML and control HTTP response headers.
- A permanent IRI scheme for the feed ID and every entry ID. Tag URIs or stable HTTPS URLs under your control work well.
- A validation path: the official Atom 1.0 RELAX NG schema (an XML schema language), a mature parser such as Python
feedparser, or a public feed validator. - Familiarity with XML namespaces; Atom elements live in
http://www.w3.org/2005/Atom.
Focused Procedure
Assign permanent identifiers
The id element must be an IRI (Internationalized Resource Identifier, the internationalized form of a URI) that remains permanently unique and unchanged, even if the feed moves or its content is revised. Do not use the current feed URL as the entry ID unless that entry page is guaranteed to exist forever. A common pattern is a tag URI, a scheme designed for stable unique identifiers without requiring a resolvable URL:
<id>tag:example.com,2026:entry:42</id>
Once published, never alter this value. Readers use it to detect duplicates and updates.
Build required elements and text constructs
Every feed and every entry requires id, title, and updated. Date elements such as updated and published must use RFC 3339 timestamps that include a timezone offset, for example 2026-10-16T01:49:25Z or 2026-10-16T01:49:25+00:00. Omitting the offset is a common validation failure.
Text constructs—title, subtitle, summary, content, and rights—require a type attribute of text, html, or xhtml. Use type="text" for plain strings, type="html" for entity-escaped HTML, and type="xhtml" for inline XHTML wrapped in a single div element in the XHTML namespace. Do not mix RSS elements such as <channel> or <item> into an Atom document; each format has its own root element and namespace.
A minimal valid feed looks like this:
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<id>tag:example.com,2026:feed:main</id>
<title type="text">Example Engineering Notes</title>
<updated>2026-10-16T01:49:25Z</updated>
<link rel="self" href="https://example.com/atom.xml"/>
<link rel="alternate" href="https://example.com/"/>
<author>
<name>Engineering Team</name>
</author>
<entry>
<id>tag:example.com,2026:entry:42</id>
<title type="text">Stable IDs Matter</title>
<updated>2026-10-15T09:00:00Z</updated>
<published>2026-10-15T09:00:00Z</published>
<link rel="alternate" href="https://example.com/notes/stable-ids"/>
<summary type="text">Why Atom identifiers must not change.</summary>
<content type="html"><p>Content here.</p></content>
</entry>
</feed>
Declare links and authors
Include a feed-level link with rel="self" pointing to the feed URL and rel="alternate" pointing to the human-readable HTML page. Entry-level link elements with rel="alternate" should point to the individual content page.
Author handling follows a simple rule: if the feed has a top-level author that applies to every entry, entries may omit their own author. Otherwise, each entry must carry an author person construct containing at least a name. Optional email and uri elements are permitted.
Serve with the correct MIME type
Browsers and feed readers rely on the Content-Type header rather than sniffing the body. Serve the document as:
Content-Type: application/atom+xml; charset=utf-8
Expected Checks
Before deployment, verify the feed in three layers.
First, validate the XML against the official Atom 1.0 RELAX NG schema. If you have xmllint installed locally, run:
xmllint --noout --relaxng /path/to/atom.rng feed.xml
Replace /path/to/atom.rng with the location of the official schema and feed.xml with your generated file. The expected result is no output and exit code 0. Risk: an incorrect or outdated schema will produce false errors.
Second, parse the feed with a mature library. In a Python environment with feedparser installed (pip install feedparser), run:
python3 -c "import feedparser; d=feedparser.parse('feed.xml'); print(d.version, len(d.entries))"
The parser should report an Atom version (commonly atom10) and the expected number of entries. If it reports rss20 or zero entries, the root element or namespace is wrong.
Third, fetch the live URL and inspect the headers. From any networked shell:
curl -sI https://example.com/atom.xml | grep -i content-type
Confirm the response includes application/atom+xml. This command is read-only and requires no special permissions.
Finally, submit the public URL to a public feed validator and resolve any reported warnings.
Recovery Options
Incorrect Content-Type
If the header is wrong, adjust the server configuration. For nginx, you can map a specific location to the Atom type:
location = /atom.xml {
default_type application/atom+xml;
}
For Apache, use AddType application/atom+xml .xml in an .htaccess file or virtual host. Risk: mapping all .xml files globally may affect other XML endpoints; prefer a specific location or a dedicated file extension.
Invalid timestamps
If validation flags date elements, regenerate them with an explicit timezone offset. Note that changing an entry's updated value may cause readers to re-fetch content, so correct timestamps before first publication whenever possible.
Unstable or missing IDs
There is no safe recovery after publication. If an entry ID changes, readers treat the item as new content. If IDs were omitted, the feed is invalid; republish with stable IDs and accept that existing subscribers may see duplicate entries until their clients reconcile the new identifiers.
Text construct errors
If html content contains unescaped angle brackets, parsers may truncate the content or reject the entry. Re-escape the markup or switch to type="xhtml" with a properly namespaced div wrapper.
Limitations and Practical Verification
Atom permits foreign markup from other namespaces, but processors may ignore unknown elements. Keep critical data inside standard Atom constructs. RFC 4287 has published errata; check them if strict conformance is required. Relative IRIs resolve against xml:base or the feed's base IRI (the document URL unless xml:base overrides it), so set them deliberately rather than relying on the document location.
To check the final result, re-run the RELAX NG validation and parser inspection after any change, and confirm the HTTP header again if server configuration was modified.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.