Webmention
Webmention is a simple way to notify any URL when you link to it on your site. From the receiver's perspective, it's a way to request notifications when other sites link to it. Webmention is a modern update to Pingback, using only HTTP and x-www-urlencoded content rather than XMLRPC requests. Webmention supersedes Pingback.
- Status
- This is an Editor's Draft yet mature enough to encourage implementations and feedback.
- Participate
- Wiki (Feedback, Open issues)
- IRC: #indiewebcamp on Freenode
- Concept and v0.1
- Sandeep Shetty
- Contributors
- See revision history for contributors
- License
- Per CC0, to the extent possible under law, the editor(s) and contributors have waived all copyright and related or neighboring rights to this work. In addition, as of 2024-12-16, the editor(s) and contributors (2015-04-07 onward) have made this specification available under the Open Web Foundation Agreement Version 1.0.
Protocol Summary
If Aaron's blog supports receiving webmentions, and Barnaby's blog supports sending webmentions, then this is how they interact:
- User Aaron posts a blog post on his blog
- User Barnaby writes post on his blog that links to Aaron's post.
- After publishing the post (i.e. it has a URL), Barnaby's server notices this link as part of the publishing process
- Barnaby's server does webmention discovery on Aaron's post to find its webmention endpoint (if not found, process stops)
- Barnaby's server sends a webmention to Aaron's post's webmention endpoint with
source
set to Barnaby's post's permalinktarget
set to Aaron's post's permalink.
- Aaron's server receives the webmention
- Aaron's server verifies that
target
(after following redirects) in the webmention is a valid permalink on Aaron's blog (if not, processing stops) - Aaron's server verifies that the
source
(when retrieved, after following redirects) in the webmention contains a hyperlink to thetarget
(if not, processing stops)
Unmentioned but implied (and vaguely mentioned in the pingback spec):
- Aaron's server displays the information about Barnaby's post somewhere on Aaron's post.
See comment: how to accept a comment for more details on accepting comments in general and displaying them.
Protocol
How to send webmentions
Sender discovers receiver endpoint
The webmention endpoint is advertised in the HTTP Link header or a <link>
or <a>
element with rel="webmention"
. If more than one of these is present, the HTTP Link header takes precedence, followed by the <link>
element, and finally the <a>
element. Clients MUST support all three options and fall back in this order.
GET /post-by-aaron HTTP/1.1 Host: aaronpk.com
HTTP/1.1 200 OK Link: <http://aaronpk.com/webmention-endpoint>; rel="webmention" <html> <head> ... <link href="http://aaronpk.com/webmention-endpoint" rel="webmention" /> ... </head> <body> .... <a href="http://aaronpk.com/webmention-endpoint" rel="webmention" /> ... </body> </html>
Sender notifies receiver
The sender posts form-encoded source
and target
, where source
is the URL of the page containing a link, and the target
is the URL of the page being linked to.
202 Accepted
is the recommended status code to return indicating that the request SHOULD be queued and processed asynchronously to prevent DoS attacks. The response body SHOULD include a URL that can be used to monitor the status of the request.
See Error Responses for what to do when the webmention is not successful.
POST /webmention-endpoint HTTP/1.1 Host: aaronpk.com Content-Type: application/x-www-url-form-encoded source=https://waterpigs.co.uk/post-by-barnaby& target=https://aaronpk.com/post-by-aaron
HTTP/1.1 202 Accepted https://aaronpk.com/webmentions/222
How to receive a webmention
Upon receipt of a POST request containing source
and target
, 202 Accepted
is the recommended status code to return indicating that the request SHOULD be queued and processed asynchronously to prevent DoS attacks. The response body SHOULD include a URL that can be used to monitor the status of the request.
If you choose to process the request and perform the verification step synchronously, you can respond with a 200 OK status on success.
Verification
1. The receiver SHOULD check that target is a valid resource belonging to it and that it accepts webmentions.
2. The receiver SHOULD perform a HTTP GET
request on source to confirm that it actually links to target
(note that the receiver will need to check the Content-type
of the entity returned by source to make sure it is a textual response).
3. At this point the receiver can choose to publish information about this webmention along with any other data it picks up from source.
Error Responses
If the webmention was not successful because of something the sender did, you SHOULD return a 400 Bad Request status code and MAY include a description of the error in the response body.
Possible sender related errors (from the Pingback specification):
Source
URL not found.- Specified target URL not found.
- Source URL does not contain a link to the
target
URL. - Specified
target
URL does not accept webmentions. - Receiver Error
If the webmention was not successful because of an error on the receivers server, it SHOULD return a 500 Internal Server Error status code and MAY include a description of the error in the response body.
Updating existing webmentions
If receiver had received a webmention in the past with the same source
and target
then,
- If both the verification steps are successful, it SHOULD update any existing data it picked from
source
for the existing webmention. - If it received a 410 on step 2 (performing a
GET
request on source) or does not find a link totarget
onsource
, it SHOULD delete the existing webmention.
Security and Privacy
Preventing Abuse
- The verification process SHOULD be queued and processed asynchronously to prevent DDoS attacks.
- Receivers SHOULD moderate Webmentions, and if a link is displayed back to the
source
, SHOULD link tosource
withrel="nofollow"
to prevent spam. - Receivers MAY periodically re-verify webmentions and update them.
- If a receiver chooses to publish data it picks up from
source
, it should ensure that the data is encoded and/or filtered to prevent XSS and CSRF attacks.
Why
Why webmentions (e.g. instead of Pingback) and why you should implement them.
Webmentions are:
- Simpler. By dropping XML-RPC, webmention is simpler than Pingback. This means:
- Less work to implement
- Easier to test
- Both of which combine to enable more reliable, interoperable implementations, sooner.
- Re-using only HTTP enables easier testing and UI. By using only HTTP, it's possible to construct simple HTML forms that exercise the protocol, which is a good design principle for web protocols in general[1]. This enables simpler/easier testing (with just a static HTML file), and the ability to provide simple (no JS needed) webmention submit forms on blog posts for others to paste URLs to their replies (some IndieWeb participants are already doing this, e.g. http://adactio.com/ and http://aaronparecki.com/ posts).
How to test webmentions
Sending Webmentions
The beauty of simple protocols is that you can do most of this manually very easily.
- Given a target to which you want to send a webmention, you need to first discover it's webmention endpoint:
curl -i -s $target | grep 'rel="webmention"'
- Note: this is only an approximation, your implementation MUST accept a "webmention" value among the space separated set of terms in the 'rel' attribute. Older implementations may use
rel="http://webmention.org/"
and some may use both:rel="webmention http://webmention.org/"
neither of which are discovered by the grep above. Some may use single quotes (or no quotes at all) to surround thewebmention
rel value. Still others may only support discovery with an HTTP Link header (e.g. Taproot). Compliant implementations must check the HTTP Link headers for the rel value first, and if not found then parse for the rel value on a<link>
or<a>
element in the<head>
per the HTML specification on parsing rel values.
- Note: this is only an approximation, your implementation MUST accept a "webmention" value among the space separated set of terms in the 'rel' attribute. Older implementations may use
- Now to send the webmention:
curl -i -d "source=$your_url&target=$target_url" $targets_webmention_endpoint
One-liner webmentions
This will send the webmention in a single command:
curl -i -d "source=$your_url&target=$target_url" `curl -i -s $target_url | grep 'rel="http://webmention.org/"' | sed 's/rel="webmention"//' | grep -o -E 'https?://[^ ">]+' | sort | uniq`
See also this gist for sending pingbacks manually: https://gist.github.com/aaronpk/5744879
Accepting Webmentions
Currently the easiest way to test consuming webmentions is to implement sending them, then send yourself mentions.
Once youβre ready to test integration with another site, you can either ask someone in IRC to send you a comment, or mention your page in IRC and send a webmention from IRC log URL for that line to your URL.
For example this IRC line links to http://caseorganic.com/notes/2014/02/18/1/. Pasting the URL for the IRC line into the indiewebify.me webmention sender will send webmentions for all the links on the page. Then you can check your page or your server logs to see if the webmention was successful β in this case the comment successfully showed up on the target page.
Implementation Details
There are some interesting implementation details regarding receiving webmentions. E.g. when to follow redirects and when not to.
endpoint discovery
In step 4 in the protocol summary above, when performing webmention endpoint discovery, implementations MUST check for the webmention
and SHOULD check for http://webmention.org/
(for backward compatiblity) as rel values which may be present among a space separated set of rel values inside a rel attribute.
Also note that endpoints may be advertised in both <link>
and <a>
elements. Supporting <a>
is important for sites like WordPress.com that don't allow link elements at all.
must follow redirects
In steps 7 and 8 above, implementations MUST follow redirects of the target and source URLs.
checking target validity
In step 7 above, when the webmention receiver checks the target
URL for validity, follow any HTTP redirects and use the resulting URL when checking for validity.
For example, if your posts visibly show permashortlinks for others to copy/cite/link to and someone sends a webmention to a shortlink, be sure to resolve any redirects before checking if itβs on your site, or matching it up to a post on your site.
The webmention receiver should then check if the target
is valid and supported. A valid target is one that is recognized by the receiver.
In simple cases, this is just a check that the target URL exists on the receiver's domain. The meaning of "valid" can be extended to also include:
- mentions of pages that don't exist on your site (in case you want to track possible lost URLs)
- mentions of POSSE URLs
use cases
- Webmention proxy servers such as webmention.io and webmention.herokuapp.com are able to accept webmentions for other people's sites
- Enables indieweb-friendly silos to send backfeed webmentions for comments and responses to the original post of a POSSE copy on that silo.
- i.e. if you POSSE to a silo, you should accept webmentions where the target is your POSSE copy
- This requires indieweb-friendly silos send webmentions to the original site's webmention endpoint, so the silo will need to know that one of its posts is a POSSE copy
You should also support receiving webmentions where the target
is one of your POSSE copies.
verifying source links to target
In step 8 above, as the webmention receiver, to verify the source
URL:
- retrieve it following redirects,
- when checking the resultant HTML, look for the
target
URL as literally provided in the webmention request (i.e. NOT redirects fromtarget
)
For example, if you get a webmention with source=http://short.me/t100 target=http://example.com/notes/5
:
- Fetch
source=http://short.me/t100
following any redirects until you get an HTML document - Search the resulting HTML for
a
elements with a href value of exactlyhttp://example.com/notes/5
, as given in thetarget
parameter
sync or async response status code
Webmention receivers can choose to verify the webmention synchronously (process immediately) or asynchronously (add it to a queue for processing later). High level difference:
Synchronously:
- upon successful verification the receiver MUST return a HTTP 200 Success response
Asynchronously:
- receiver MUST return HTTP 202 Accepted.
See the Brainstorming section for some additional thinking on this.
types of mentions
In addition to just a link (mention) there are several special types of mentions, each which have markup for detection and specific implementation recommendations:
- reply (via in-reply-to)
- RSVP a special kind of reply to an event, indicating where or not attending (or maybe/interested)
- like
- repost
accessing endpoints in the browser
Some implementations now display a page that briefly explains webmentions when the webmention endpoint is accessed in a browser.
- Aaron Parecki at https://aaronparecki.com/webmention.php
- Kyle Mahan at https://kylewm.com/webmention
- Barnaby Walters at waterpigs.co.uk/mentions/webmention, containing a link to the wiki (more friendly than the spec), along with a short description and a form for easy webmention sending.
- Pelle Wessman at https://webmention.herokuapp.com/api/webmention
- add yours...
Implementations
IndieWeb Examples
The following users/sites have implemented sending and or receiving webmentions, in rough chronological order:
- Aaron Parecki using p3k on aaronparecki.com as of 2013-05-26. Details:
- All posts send webmentions (as of 2013-05-26 first (semi-)automatic webmention sent on 2013-03-31) upon posting (asynchronously with posting UI, no results reported).
- Events, notes (including RSVPs), replies accept webmentions (as of 2013-05-26)
- Discovery with both:
rel="webmention"
andrel="http://webmention.org/"
links in head, and HTTPLink: rel="http://webmention.org/
header - Notes (including RSVPs), replies have an input form for pasting in your comment URL to conveniently send a manual webmention (as of 2013-10-12)
- Ben Werdmuller using idno on werd.io as of 2013-05-31. Details:
- All(?) posts send webmentions as of 2013-05-31 and accept as of 2013-06-??
- Discovery with both:
rel="http://webmention.org/"
andrel="webmention"
links in head, and with HTTPLink: <http://werd.io/webmention/>; rel="webmention"
- Barnaby using Taproot on waterpigs.co.uk as of 2013-06-11 (per git). Details:
- All notes and articles accept (as of 2013-06-20) and send webmentions (as of 2013-06-11) upon posting (posting UI returns response content to the browser, then synchronously sends webmentions)
- Incoming webmentions for notes and articles are parsed and stored, displayed for notes (comment updating as of 2013-06-23) but not yet articles
- Discovery only with HTTP
Link: <http://waterpigs.co.uk/mentions/webmention/>; rel="http://webmention.org/"
- Jeremy Keith on adactio.com as of 2013-09-15. Details:
- All blog posts accept webmentions
- Discovery only with:
rel="webmention"
link in head - Blog posts have an input form for pasting in your comment URL to conveniently send a manual webmention
- Barry Frost on barryfrost.com as of 2013-09-15[2][3]. Details:
- All(?) posts send and accept webmentions
- Discovery with:
rel="webmention"
link in head, and HTTPLink: <http://barryfrost.com/webmention>; rel="webmention"
in header - Posts have a hyperlink in footer "How to comment on this post" to instructions detailing posting an h-entry with h-card and how to send a webmention.
- Christian Weiske receiving webmentions on cweiske.de as of 2013-10-22. Details:
- All posts accept webmentions using stapibas
- Discovery only with HTTP
Link: <http://cweiske.de/stapibas/xmlrpc.php>; rel="webmention"
- Approach for sending webmentions (with fallback sending of pingbacks)
- https://github.com/pear2/Services_Linkback/blob/master/src/PEAR2/Services/Linkback/Client.php#L236
- check self Atom feed, if there are updates then proceed with discovery/sending for each update, for each link in the update: do a HEAD request first, do discovery for webmention endpoint, if none found, do discovery for pingback endpoint, if none found and the resource is
'application/xhtml+xml'
or'text/html'
, do a GET request, do discovery for webmention endpoint, if none found, do discovery for pingback endpoint. send webmention if an endpoint was found, otherwise send pingback if an endpoint was found.
- Bear on bear.im as of 2013-12-01.
- All posts send and accept webmentions
- Discovery with both:
rel="webmention"
andrel="http://webmention.org/"
links in head, and HTTPLink: rel="http://webmention.org/
header - Incoming webmentions are validated and stored, but not yet added to the appropriate articles
- Kartik Prabhu on kartikprabhu.com as of 2013-12-03.
- All articles & notes accept webmentions
- Articles have an input form for sending a manual webmention inspired by adactio.com. The form prompt links to the webmention endpoint.
- Webmentions are saved as responses and appear below the article classified according to response type.
- Webmentions are sent manually for all posts.
- Pelle Wessman using webmention.herokuapp.com on voxpelli.com as of 2013-12-18. Details:
- All blog posts accept webmentions
- Discovery only with:
rel="webmention"
link in head - Blog posts have an input form for pasting in your comment URL to conveniently send a manual webmention
- Jeena Paradies using a home grown Rails app on https://jeena.net as of 2013-12-06. Details:
- All homepage, blog posts and notes, photos, comments and events accept webmentions
- Discovery with:
rel="webmention"
Link: in HTTP header - Sends webmentions on create, update and delete, no salmentions yet
- Has a manual form
- Andy Sylvester using the Webmention plugin for WordPress on http://andysylvester.com as of 2014-01-24. Details:
- All blog posts accept webmentions
- gRegor Morrill sending and receiving webmentions on gRegorLove.com as of 2014-02-04.
- Using a custom plugin I developed for Nucleus CMS
- All articles can receive webmentions
- Webmention endpoint is broadcast via Link: HTTP header and <link> element
- Incoming webmentions validate the target is a valid URL on gregorlove.com and the post ID in the URL is valid.
- Webmentions are parsed and further validated asynchronously. Replies/mentions are displayed interleaved with "local" blog comments..
- More implementation notes
- Glenn Jones using node.js module github.com/glennjones/webmentions on glennjones.net as of 2014-02-19.. Details:
- All notes accept webmentions
- Discovery only with:
rel="webmention"
link in head - The notes editor has an input for the
in-reply-to
URL - The webmentions module allows pinging of webmention between any sites
- Yet to implement: full authorship parsing, updates, deletes.
- Ben Roberts sending and receiving webmentions on ben.thatmustbe.me as of 2014-04-24
- Parsing replies, mentions, and likes. Rsvps are handled as just mentions currently.
- Discovery with both:
rel="webmention"
andrel="http://webmention.org/"
links in head, and HTTPLink: rel="http://webmention.org/
header - Currently uses vouch and a whitelist while all others are sent to moderation.
- Processing happens asynchronously by cron job.
- Submissions return a link for queue record that returns a status as a
Webmention-Status
header as well as a minor note in the body. - Attempting to keep implementation notes as a modified spec at webmetion0.2-b1
- Sending is done automatically when post is made.
- Will Norris using webmention.herokuapp.com on willnorris.com as of 2014-07-31. Details:
- All posts accept webmentions, but none are displayed (yet)
- Webmentions sent on-demand via command line application that handles the discovery bits
- Discovery only with
rel="webmention"
link in head - Advertised webmention endpoint is on-site, but POSTs are proxied to webmention.herokuapp.com. (documented here)
- Previously used webmention plugin for WordPress as of 2013-06-23
- Joel Dueck receiving webmentions on thelocalyarn.com as of 2014-09-23.
- All posts accept webmentions as well as traditional comments.
- Webmentions (if valid) are logged to a text file and sent to Joel via email. Those that pass moderation are manually added to the target post as a comment (which on this site means it is included in the blog and sent to email and RSS subscribers as well as being appended to the target post).
- Endpoint is a modified version of Jeremy Keith's webmention.php.
- Webmentions sent manully. More to implement. To-do list is long. Site is running Textpattern CMS, so a complete webmentions plugin is both feasible and ideal.
- Dan Lyke receiving webmentions on Flutterby.com blog entries as of 2014-10-10.
- Webmention endpoint is broadcast via <link> element and <indie-action> element.
- Currently only displays links on title text back to source URLs
- Johnny Oskarsson receiving webmentions on joskar.se as of 2014-10-23.
- Webmention endpoint is broadcast via Link: HTTP header only.
- Pages marked up with h-entry in-reply-to show up as comments, others won't show up at all. (but they will be logged)
- Webmentions are sent manually for now.
- Stuart Langridge sending and receiving webmentions on kryogenix.org as of 2014-11-29.
- Write up linking to various bits of code for Pelican, the Python static site generator, at "Enabling Webmentions".
- Webmention endpoint is declared in the HTML with a <link> element, because HTTP headers are a pain in the behind to set up by comparison.
- Uses Pelle Wessman's webmention Heroku endpoint as endpoint, and then some Python to fetch and bake in webmentions on site regeneration, and some JS to pull them in live.
- Giovanni T. Parra receiving webmentions on fiatjaf.alhur.es as of 2015-02-28.
- Wrote Jekmentions, a small service that works as a webmention endpoint for Jekyll sites hosted on GitHub that sends the webmentions received as files in commits to the GitHub repository.
- Webmentions are sent manually for now. Some are being sent, but only through brid.gy to twitter.
- Amy Guy sending webmentions automatically for all links on all posts on rhiaro.co.uk as of 2015-05-?.
- David Shanske supports sending and receiving webmentions for all posts using WordPress on david.shanske.com as of 2014-03-?.
Libraries
Sending
- indieweb/mention-client-php PHP library for sending webmention and pingpack notifications
- indieweb/mention-client-ruby Ruby library for sending webmention notifications
- phpish/webmention - Simple webmention client (non-OO) in PHP packaged as a composer package.
- vrypan/webmention-tools - Python client library and command line webmention sender
- pear2/Services_Linkback - PHP pingback+webmention client + server library
- bear/ronkyuu - Python client library and command-line tools
- glennjones/webmentions - Node.js a helper library for endpoint discovery, pulling validating webmentions and sending webmention requests
- willnorris.com/go/webmention - Go client library and command-line tool for discovering and sending webmentions.
- β¦
For webmention endpoint discovery:
- link_rel_parser :
http_rels($h)
&head_http_rels($url)
- HTTP header string parser in PHP for RFC5988 Link: rels (includingX-Pingback
) & function to curl a HEAD request and parse it all in one. - phpish/link_header - Link header (RFC 5988) parser in PHP
- PEAR: HTTP2 (documentation) - Link header (RFC 5988) parser in PHP
- ronkyuu - Python client library and command-line tools
Handling
Handling receiving webmentions:
- PHP Minimum Viable Webmention handler: https://gist.github.com/adactio/6484118
- pear2/Services_Linkback - PHP pingback+webmention client + server library
- β¦
For parsing the mentions, the following may come in handy:
- microformats2 implementations and parsers
- php-mf-cleaner - "Takes microformats2 array structure and makes it more sane. Counterpart to indieweb/php-mf2"
- went - Webmention Endpoint Tools, a Python library that takes source and target URLs and does the rest of the job for you.
Notifications
The following tools show how a notification could be sent upon receiving a webmention
- PHP to email
- Javascript
- bear is working on this...
- XMPP
- - bear is working on this...
Publishing Software
Some open source publishing software supports webmentions.
- Known sends webmentions and accepts webmention comments
- p3k sends webmentions for all posts and accepts webmention comments on events, notes, replies, RSVPs
- phorkie sends and accepts webmentions to notify remote instances about forks
- Taproot
Plugins exist for some open source publishing software:
Services
Some services one can use to receive or send webmentions.
webmention.herokuapp.com
webmention.herokuapp.com receives webmentions for any registered page and allows them to be embedded through javascript.
Bridgy
brid.gy is a service that sends webmentions for comments/replies, likes, and reposts on Facebook, Twitter, Google+, and Instagram posts. It uses original post discovery to find target links for the webmentions. GitHub repo here.
Bridgy Publish also supports webmention as a mechanism to trigger POSSEing to Facebook, Twitter, and Instagram.
stapibas
stapibas is a self-hosted service to send and receive webmentions for websites and blogs.
It can be used to send out webmentions and pingbacks for new posts on static sites.
webmention.io
webmention.io is an open-source project and hosted service for receiving webmentions and pingbacks on behalf of your indieweb site.
jekmentions
jekmentions is a service that works as webmention endpoint and saves the received webmentions in a GitHub repository, so that they can be used and shown in a Jekyll blog.
checkmention
https://checkmention.appspot.com/ lets you test your webmention implementation on your indieweb site, and whether it robustly detects certain types of XSS attacks. It also allows you to test for authorship spoofing.
node-webmention-testpinger
node-webmention-testpinger is a tool to ping your site with a variety of webmentions markup. Contains copies of a couple of real world examples of mentions that it enables you to ping locally to a development copy of your site.
node-webmention-testendpoint
node-webmention-testendpoint is tool to test your webmentions client. Generates a demo-post and a demo-endpoint to test if your client parses the webmention-endpoint correctly and to check if the ping body is transmitted correctly.
Tools
Tools you can install to send webmentions
Firefox Addon
- https://addons.mozilla.org/fr/firefox/addon/webmention/
- source: https://github.com/eliemichel/firefox-webmention-addon
Wish List
- A tiny, no-dependencies js file which can fetch indiecomment data from webmention.io and dump it into an element, enabling 2-step indiecomment support:
- Add a <link> to webmention.io
- include this script and add some
<div data-indiecomments data-url="blah">
element where you want them to appear
FAQ
See Webmention FAQ. Please read this before filing an issue or adding to brainstorming.
Issues
See Webmention Issues.
Brainstorming
Articles
Blog posts and articles about webmention:
- 2014-11-29 Stuart Langridge Enabling Webmentions - inventor of Pingback enables webmentions on his blog!
- 2014-12-21 David Shanske "One of the building blocks of Indiewebcamp is the webmention"
See Also
- http://webmention.org/
- notification
- webmention.io, a service to convert Pingbacks to WebMentions
- comments - a key use case for webmention, and post interactions in general
- indieweb messaging - another user case for webmention
- Wikipedia - Webmention - Help me expand the article --Bret.io 15:31, 30 June 2013 (PDT)
- Pingback
- Trackback
- RESTful Pingback
- Semantic Pingback
- TalkBack
- style-guide