Please check theerrata for any errors or issues reported since publication.
The English version of this specification is the only normative version. Non-normativetranslations may also be available.
Copyright © 2017W3C® (MIT,ERCIM,Keio,Beihang).W3Cliability,trademark andpermissive document license rules apply.
The Micropub protocol is used to create, update and delete posts on one's own domain using third-party clients. Web apps and native apps (e.g., iPhone, Android) can use Micropub to post and edit articles, short notes, comments, likes, photos, events or other kinds of posts on your own website.
This section is non-normative.
This specification was contributed to theW3C from theIndieWeb community. More history and evolution of Micropub can be found on theIndieWeb wiki.
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of currentW3C publications and the latest revision of this technical report can be found in theW3C technical reports index at https://www.w3.org/TR/.
This document was published by theSocial Web Working Group as a Recommendation. Comments regarding this document are welcome. Please send them topublic-socialweb@w3.org (subscribe,archives).
Please see the Working Group'simplementation report.
This document has been reviewed byW3C Members, by software developers, and by otherW3C groups and interested parties, and is endorsed by the Director as aW3C Recommendation. It is a stable document and may be used as reference material or cited from another document.W3C's role in making the Recommendation is to draw attention to the specification and to promote its widespread deployment. This enhances the functionality and interoperability of the Web.
This document was produced by a group operating under the5 February 2004W3C Patent Policy.W3C maintains apublic list of any patent disclosures made in connection with the deliverables of the group; that page also includes instructions for disclosing a patent. An individual who has actual knowledge of a patent which the individual believes containsEssential Claim(s) must disclose the information in accordance withsection 6 of theW3C Patent Policy.
This document is governed by the1 March 2017W3C Process Document.
This section is non-normative.
Micropub is a spec to create, update and delete posts on a server using web or native app clients. Micropub is primarily focused around creating "posts" (individual pieces of content such as blog posts, photos, short notes, comments, and more) on a website, although it can be used for other kinds of content as well. The Micropub spec defines a simple mechanism to create content, as well as a more thorough mechanism to update and delete content.
Micropub is one of several related specifications being produced by the Social Web Working Group. Implementers interested in alternative approaches and complementary protocols should reviewActivityPub as well as the overview document [social-web-protocols].
The Micropub specification began as a simplified version of the AtomPub and MetaWeblog APIs. Where AtomPub is an API to create items in an Atom feed, Micropub is an API to create items in a [Microformats2] feed.
In addition to being used with a different vocabulary from AtomPub and MetaWeblog, Micropub simplifies and improves upon both APIs in a number of ways. Micropub uses OAuth 2.0 Bearer Tokens for authentication, rather than the previous insecure username/password authentication method. Micropub also uses traditional form posts as well as JSON posts, which is both simpler and more secure than an XMLRPC approach.
The Micropub vocabulary is derived directly from the [Microformats2] vocabulary. Micropub is meant to be a serialization of Microformats that can be submitted as an HTTP POST. The method for developing new Micropub vocabularies is to look at the Microformats representation and work backwards.
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in [RFC2119].
This section describes the conformance criteria for Micropub clients and servers. All implementationsMUST support UTF-8 encoding.
A conforming Micropub client that creates posts:
x-www-form-urlencoded
requestsA conforming Micropub client that edits posts:
A conforming Micropub server:
x-www-form-urlencoded
syntaxmultipart/form-data
requests forcreating postsThis specification exited CR by there being least two independent, interoperable implementations of each feature. Each feature may be implemented by a different set of products. There is no requirement that all features be implemented by a single product. For the purposes of this criterion, we define the following terms:
A Micropub Client is an implementation that sends Micropub requests to create or otherwise manipulate posts. The conformance criteria are described inConformance Classes above.
A Micropub Server is an implementation that can create and optionally edit and delete posts given a Micropub request. The Micropub serverMAY also support a Media Endpoint for handling file uploads outside of the primary Micropub endpoint. The conformance criteria are described inConformance Classes above.
Each implementation must be developed by a different party and cannot share, reuse, or derive from code used by another qualifying implementation. Sections of code that have no bearing on the implementation of this specification are exempt from this requirement.
A Client and Server implementation are considered interoperable for a specific feature when the Server takes the defined action that the Client requests, the Client gets the expected response from a Server according to the feature, and the Server sends the expected response to the Client.
An Implementation is a Micropub Client or Server which meets all of the following criteria:
For the purposes of evaluating exit criteria, each of the following is considered a feature:
Authorization
headerx-www-form-urlencoded
requestsx-www-form-urlencoded
syntax with one or more propertiesx-www-form-urlencoded
syntax with multiple values of the same property namemultipart/form-data
to the Micropub endpointHTTP 201 Created
and aLocation
header when creating a postHTTP 202 Created
and aLocation
header when creating a postHTTP 200 OK
when updating a postHTTP 201 Created
when updating a post if the update cause the post URL to changeHTTP 204 No Content
when updating a postx-www-form-urlencoded
syntaxx-www-form-urlencoded
syntaxq=config
to retrieve the Media Endpoint and syndication targets if specifiedq=syndicate-to
to retrieve the list of syndication targetsPlease submit your implementation reports athttps://micropub.net/implementation-reports/. Instructions are provided at the URL. The implementation report template references the tests available atmicropub.rocks.
micropub.rocks provides many test cases you can use to live-test your implementation. It also is a good tool to use while developing a Micropub implementation, as it provides detailed responses when errors are encountered.
As [microformats2-parsing] has a relatively small ruleset for parsing HTML documents into a data structure, Micropub similarly defines a small set of rules to interpret HTTP POST and GET requests as Micropub commands. Where [microformats2-parsing] does not require changing the parsing rules to introduce new properties of an object such as an [h-entry], Micropub similarly does not require changing parsing rules to interpret requests that may correspond to different post types, such as posting videos vs "likes".
The Micropub syntax describes how to interpret HTTP POST and GET requests into useful server actions.
All Micropub requests to create posts are sent as UTF-8x-www-form-urlencoded
,multipart/form-data
[HTML5], or [JSON]-encoded HTTP requests. Responses typically do not include a response body, indicating the needed information (such as the URL of the created post) in HTTP headers. When a response body is necessary, itSHOULD be returned as a [JSON] encoded object.
Forx-www-form-urlencoded
andmultipart/form-data
requests, Micropub supports an extension of the standard URL encoding that includes explicit indicators of multi-valued properties. Specifically, this means in order to send multiple values for a given property, youMUST append square brackets[]
to the property name.
For example, to specify multiple values for the property "category", the request would includecategory[]=foo&category[]=bar
.
On the server side, it is expected that the server will convert this to an internal representation of an array. For example, the equivalent JSON representation of this would be:
{"category": ["foo","bar" ]}
This works equally well in multipart requests, where each value is given in a separate "part" of the request, and the name is given in a line such asContent-Disposition: form-data; name="category[]"
.
Note that the extent of the extensions to thex-www-form-urlencoded
syntax is the addition of the square brackets to indicate an array. Syntax such asfoo[0]
andfoo[bar]
is not supported, and so clients are expected to use theJSON syntax when posting more complex objects.
A few POST body property names are reserved when requests are sent asx-www-form-urlencoded
ormultipart/form-data
.
access_token
- the OAuth Bearer token authenticating the request (the access token may be sent in an HTTP Authorization header or this form parameter)h
- used to specify the object type being createdaction
- indicates whether this is andelete
, orundelete
(updates are not supported in the form-encoded syntax)url
- indicates the URL of the object being acted onmp-*
- reserved for future useWhen creating posts usingx-www-form-urlencoded
ormultipart/form-data
requests, all other properties in the request are considered properties of the object being created.
The serverMUST NOT store theaccess_token
property in the post.
Properties beginning withmp-
are reserved as a mechanism for clients to give commands to servers. Where typically properties of a post are visible to users, commands to the server are not visible to users, so it does not make sense to set a property on the post for a command. Clients and servers wishing to experiment with creating newmp-
commands are encouraged to brainstorm and document implementations atindieweb.org/Micropub-extensions.
When creating posts usingJSON syntax, properties beginning withmp-
are reserved as described above.
To create a post, send an HTTP POST request to the Micropub endpoint indicating the type of post you are creating, as well as specifying the properties of the post. If no type is specified, the default type [h-entry]SHOULD be used. Clients and serversMUST support creating posts using thex-www-form-urlencoded
syntax, andMAY also support creating posts using theJSON syntax.
h={Microformats object type}
e.g.,h=entry
All parameters not beginning with "mp-" are properties of the object being created.
e.g.,content=hello+world
To specify multiple values for a property, such as multiple categories of an h-entry, append square brackets to the property name, indicating it is an array.
e.g.,category[]=foo&category[]=bar
Properties that accept multiple valuesMUST also accept a single value, with or without the square brackets. A complete example of a form-encoded request follows.
h=entry&content=hello+world&category[]=foo&category[]=bar
To upload files, the clientMUST check for the presence of aMedia Endpoint. If there is no Media Endpoint, the client can assume that the Micropub endpoint accepts files directly, and can send the request to it directly. To upload a file to the Micropub endpoint, format the whole request asmultipart/form-data
and send the file(s) as a standard property.
For example, to upload a photo with a caption, send a request that contains three parts, namedh
,content
andphoto
.
multipart/form-data; boundary=553d9cee2030456a81931fb708ece92c--553d9cee2030456a81931fb708ece92cContent-Disposition: form-data; name="h"entry--553d9cee2030456a81931fb708ece92cContent-Disposition: form-data; name="content"Hello World!--553d9cee2030456a81931fb708ece92cContent-Disposition: form-data; name="photo"; filename="aaronpk.png"Content-Type: image/pngContent-Transfer-Encoding: binary... (binary data) ...--553d9cee2030456a81931fb708ece92c--
For properties that can accept a file upload (such asphoto
orvideo
), the Micropub endpointMUST also accept a URL value, treating that the same as if the file had been uploaded directly. The endpointMAY download [Fetch] a copy of the file at the URL and store it the same way it would store the file if it had been uploaded directly. For example:
h=entry&content=hello+world&photo=https%3A%2F%2Fphotos.example.com%2F592829482876343254.jpg
This is to support uploading files via a Media Endpoint, or by reference to other external images. See theMedia Endpoint section for more information.
In order to support more complex values of properties, you can create a post with JSON syntax by sending the entry in the parsed Microformats 2 JSON format.
Note that in this case, you cannot also upload a file, you can only reference files by URL as described above.
When creating posts in JSON format, all valuesMUST be specified as arrays, even if there is only one value, identical to the Microformats 2 JSON format. This request is sent with a content type ofapplication/json
.
Note that properties beginning withmp-
are reserved as described inReserved Properties.
POST/micropub HTTP/1.1Host: aaronpk.exampleContent-type: application/json{"type": ["h-entry"],"properties": {"content": ["hello world"],"category": ["foo","bar"],"photo": ["https://photos.example.com/592829482876343254.jpg"] }}
To include alt text along with the image being uploaded, you can use the Microformats 2 syntax to specify both the image URL and alt text for thephoto
property. Instead of the value being simply a URL, the value is instead an object with two properties:value
being the URL andalt
being the text. Note that because the value ofphoto
needs to be an object, we can't use form-encoded or multipart requests for this. Instead, we have to first upload the photo to the media endpoint, then reference the URL in a JSON request, as illustrated below.
POST/micropub HTTP/1.1Host: aaronpk.exampleContent-type: application/json{"type": ["h-entry"],"properties": {"content": ["hello world"],"category": ["foo","bar"],"photo": [ {"value":"https://photos.example.com/globe.gif","alt":"Spinning globe animation" } ] }}
The specific method described here of specifying alt text was added with the assumption that the Microformats 2 proposal for how to represent image alt text (issue 2) will be incorporated. If the referenced issue is resolved a different way, the Micropub spec should be adjusted accordingly.
Whenever possible, nested Microformats objects should be avoided. A better alternative is to reference objects by their URLs. The most common example is including an h-card for a venue, such as checking in to a location or tagging a photo with a person or location. In these cases, it is better to reference the object by URL, creating it first if necessary.
This technique has the advantage of ensuring that each object that is created has its own URL (each piece of data has its own link). This also gives the server an opportunity to handle each entity separately. E.g., rather than creating a duplicate of an existing venue, it may give back a link to one that was already created, possibly even merging newly received data first.
In some cases, it does not make sense for the nested object to have a URL. For example, when posting an h-measure value, there is no reason for the h-measure itself to have a URL, so this is an acceptable case to use the nested Microformats object syntax.
Nested objects require that the request be sent in JSON format, since the form-encoding syntax does not consistently support nested objects.
The example below creates a new "weight" measurement post as an h-entry with a h-measure objects to describe the weight and bodyfat values.
{"type": ["h-entry"],"properties": {"summary": ["Weighed 70.64 kg" ],"weight": [ {"type": ["h-measure"],"properties": {"num": ["70.64"],"unit": ["kg"] } } ],"bodyfat": [ {"type": ["h-measure"],"properties": {"num": ["19.83"],"unit": ["%"] } } ] }}
Natural language values in Micropub requestsMAY contain bidirectional text. The default base direction of Micropub text values is left-to-right. The base direction of individual natural language valuesMAY be modified as described below.
When specifying bidirectional text for a natural language value, and the base direction of the text cannot be correctly identified by the first strong directional character of that text ([BIDI]), publishing clientsSHOULD explicitly identify the default direction either by prefixing the value with an appropriate Unicode bidirectional control character, or by using HTML directional markup for HTML values.
Micropub servers that accept natural language values that contain bidirectional textSHOULD identify the base direction of any given natural language value by either: for plaintext values, scanning the text for the first strong directional character; or for HTML values, by utilizing directional markup, if available, or otherwise scanning for the first strong directional character not contained in a markup tag. When displaying these natural language values, the serverMUST determine the appropriate rendering of the content according to the [BIDI] algorithm, which may necessitate wrapping additional control characters or markup around the string prior to display, in order to apply the base direction.
If the request includes properties that the server does not recognize, itMUST ignore unrecognized properties and create the post with the values that are recognized.
This allows clients to post rich types of content to servers that support it, while also posting fallback content to servers that don't.
For example, a client may create a post that contains a weight measurement, with anh-measure
value for theweight
property, and a plaintext summary of the post in thesummary
property. Servers that don't recognize theweight
property will simply ignore it, and will create the post as a plaintext post with the summary instead.
When the post is created, the Micropub endpointMUST return either anHTTP 201 Created
status code orHTTP 202 Accepted
code, andMUST return aLocation
header indicating the URL of the created post. [RFC2616]
HTTP/1.1201 CreatedLocation: https://aaronpk.example/post/1000
If the endpoint chooses to process the request asynchronously rather than creating and storing the post immediately, itMUST return anHTTP 202 Accepted
status code, andMUST also return theLocation
header. The serverMUST do any error checking and validation of the request synchronously in order to ensure the object will be created successfully, prior to returning HTTP 202. Clients will expect the object at the indicated URL to exist at some point in the (near) future if they receive an HTTP 202 response.
If the target also provides a shortlink, or if it syndicated the post to another location, the Micropub endpointMAY return additional URLs using the HTTP Link header, along with an appropriate "rel" value. For example, it can return the short URL of a post by responding with:
Link:<http://aaron.pk/xxxxx>; rel="shortlink"or can include the location of the syndicated post with:
Link:<https://myfavoritesocialnetwork.example/aaronpk/xxxxxx>; rel="syndication"
See the "Error Response" section below for details on how to indicate an error occurred.
Micropub serversSHOULD support updating posts, including adding and removing individual properties as described in this section.
Updating entries is done with a JSON post describing the changes to make.
To update an entry, send"action": "update"
and specify the URL of the entry that is being updated using the "url" property. The requestMUST also include areplace
,add
ordelete
property (or any combination of these) containing the updates to make.
The values of each property inside thereplace
,add
ordelete
keysMUST be an array, even if there is only a single value.
While it is okay to combine add/delete operations in the same request, it only makes sense to do so when they are operating on different property-value combinations. Servers may have undefined behavior if multiple operations of the same property-value combination are sent in an update request.
Replace all values of the property. If the property does not exist already, it is created.
{"action":"update","url":"https://aaronpk.example/post/100","replace": {"content": ["hello moon"] }}
This will replace the entire entry content with the new text, leaving any other existing property of the post as is.
If there are any existing values for this property, they are not changed, the new values are added. If the property does not exist already, it is created.
Use case: adding a syndication link to a post after it has been published. For example, when a client supports posting first then syndicating to MyFavoriteSocialNetwork or Wikimedia after the fact, the site needs a way to update the original post with the new syndication URL.
To add syndication URLs, include one or more URLs in the update request.
{"action":"update","url":"https://aaronpk.example/2014/06/01/9/indieweb","add": {"syndication": ["http://web.archive.org/web/20040104110725/https://aaronpk.example/2014/06/01/9/indieweb"] }}
Use case: adding tags to a post after it's been created.
To add multiple values to a property (such as category), provide the new values in an array.
{"action":"update","url":"https://aaronpk.example/2014/06/01/9/indieweb","add": {"category": ["micropub","indieweb"] }}
If the property exists, remove it. This completely removes the specified property.
{"action":"update","url":"https://aaronpk.example/2014/06/01/9/indieweb","delete": ["category"]}
For properties with multiple values, such as categories, you can remove individual entries by value. If no values remain, the property is removed.
{"action":"update","url":"https://aaronpk.example/2014/06/01/9/indieweb","delete": {"category": ["indieweb"] }}
The serverMUST respond to successful update requests with HTTP 200, 201 or 204. If the update operation caused the URL of the post to change, the serverMUST respond with HTTP 201 and include the new URL in the HTTPLocation
header. Otherwise, the serverMUST respond with 200 or 204, depending on whether the response body has content. No body is required in the response, but the responseMAY contain a JSON object describing the changes that were made.
Micropub serversSHOULD support deleting posts, andMAY support undeleting posts.
To delete an entire entry at a URL, send a POST request containingaction=delete
and the URL of the item in theurl
property.
action=delete&url=https://aaronpk.example/2014/06/01/9/indieweb
{"action":"delete","url":"https://aaronpk.example/2014/06/01/9/indieweb"}
To undelete a post, use "undelete" as the action.
action=undelete&url=https://aaronpk.example/2014/06/01/9/indieweb
{"action":"undelete","url":"https://aaronpk.example/2014/06/01/9/indieweb"}
The serverMUST respond to successful delete and undelete requests with HTTP 200, 201 or 204. If the undelete operation caused the URL of the post to change, the serverMUST respond with HTTP 201 and include the new URL in the HTTPLocation
header. Otherwise, the serverMUST respond with 200 or 204, depending on whether the response body has content. No body is required in the response, but the responseMAY contain a JSON object describing the changes that were made.
In order to provide a better user experience for Micropub applications, as well as to overcome the limitation of being unable to upload a file with the JSON syntax, a Micropub serverMAY support a "Media Endpoint". The role of the Media Endpoint is exclusively to handle file uploads and return a URL that can be used in a subsequent Micropub request.
When a Micropub server supports a Media Endpoint, clients can start uploading a photo or other media right away while the user is still creating other parts of the post. The diagram below illustrates a user interface that demonstrates creating a photo post while the photo is uploading asynchronously.
The above user flow applies just as well to mobile apps as it does to desktop apps. In general, the user experience of an application can be improved by having more of the work done asynchronously, giving the user a chance to continue working instead of waiting for the system to finish.
To advertise that the Micropub endpoint supports a Media Endpoint, the serverMUST include a key calledmedia-endpoint
with a value of the full URL of the Media Endpoint in the Micropubconfiguration request. ClientsMUST NOT assume the Media Endpoint is on the same domain as the Micropub endpoint.
GET /micropub?q=configAuthorization: Bearer xxxxxxxxx{"media-endpoint":"https://media.example.com/micropub"}
The Media EndpointMUST accept the same access tokens that the Micropub endpoint accepts.
To upload a file to the Media Endpoint, the client sends amultipart/form-data
request with one part namedfile
. The Media EndpointMAY ignore the suggested filename that the client sends.
multipart/form-data; boundary=553d9cee2030456a81931fb708ece92c--553d9cee2030456a81931fb708ece92cContent-Disposition: form-data; name="file"; filename="sunset.jpg"Content-Type: image/jpegContent-Transfer-Encoding: binary... (binary data) ...--553d9cee2030456a81931fb708ece92c--
To include accessibility-related information such as image alt text when creating posts that contain an image, the alt text is associated with the post itself rather than the media file. This is analogous to an HTML img tag where the img tag has a src attribute pointing to the media file and an alt attribute with the alt text. SeeUploading a photo with alt text for more information.
The Media Endpoint processes the file upload, storing it in whatever backend it wishes, and generates a URL to the file. The URLSHOULD be unguessable, such as using a UUID in the path. If the request is successful, the endpointMUST return the URL to the file that was created in the HTTPLocation
header, and respond withHTTP 201 Created
. The response body is left undefined.
HTTP/1.1201 CreatedLocation: https://media.example.com/file/ff176c461dd111e6b6ba3e1d05defe78.jpg
The Micropub client can then use this URL as the value of e.g. the "photo" property of a Micropub request.
The Media EndpointMAY periodically delete files uploaded if they are not used in a Micropub request within a specific amount of time.
The Media EndpointSHOULD follow the same conventions for returning error responses as the Micropub endpoint, described inError Response.
Micropub clients may need to query the Micropub endpoint to discover its capabilities, such as finding a list of syndication targets that it displays to the user, or retrieving the source of a post to display in the updating interface.
To query, make aGET
request to the Micropub endpoint and use theq
parameter to specify what you are querying.
The Micropub endpoint URL may include a query string such as?micropub=endpoint
, so in this case, Micropub clientsMUST append theq
parameter instead of replacing the query string.
When a user initially logs in to a Micropub client, the client will want to query some initial information about the user's endpoint. The clientSHOULD make a query requestq=config
to obtain initial configuration information.
The serverSHOULD include the following information in the configuration response.
syndicate-to
(seeSyndication Targets for details on the structure of the response)media-endpoint
GET /micropub?q=configAuthorization: Bearer xxxxxxxxxAccept: application/jsonHTTP/1.1200 OKContent-type: application/json{"media-endpoint":"https://media.example.com/micropub","syndicate-to": [ {"uid":"https://myfavoritesocialnetwork.example/aaronpk","name":"aaronpk on myfavoritesocialnetwork","service": {"name":"My Favorite Social Network","url":"https://myfavoritesocialnetwork.example/","photo":"https://myfavoritesocialnetwork.example/img/icon.png" },"user": {"name":"aaronpk","url":"https://myfavoritesocialnetwork.example/aaronpk","photo":"https://myfavoritesocialnetwork.example/aaronpk/photo.jpg" } } ]}
ServersSHOULD support the configuration query, and returning all properties relevant to the server. If none of the properties apply to the server, the responseSHOULD be an empty JSON object,{}
.
ClientsSHOULD treat unexpected responses the same as an empty response, in order to handle unexpected responses from servers that don't support this query. For example, a server that does not implement the configuration query at all may return an HTTP 400 response rather than the expected 200 response with an empty JSON object.
A Micropub client can query the endpoint to return specific properties of a post. This allows a client to request only the properties it needs or knows about, supporting such uses as making an interface to add tags to a post.
Servers that support updating postsMUST support the source content query.
To query, make aGET
request to the Micropub endpoint and set theq
parameter tosource
, and include the URL of the post in theurl
parameter. The query can specify the list of properties being requested by setting one or more values for theproperties
key. If more than one is specified, use array bracket notation for each name, according to [HTML5] URL encoding.
The endpointMUST return the response in [microformats2-parsing] [JSON] format, with an object namedproperties
, where the keys are the names of the properties requested. If no properties are specified, then the responseMUST include all properties, as well as atype
property indicating the vocabulary of the post.
GET /micropub?q=source&properties[]=published&properties[]=category&url=https://aaronpk.example/post/1000Authorization: Bearer xxxxxxxxxAccept: application/jsonHTTP/1.1200 OKContent-type: application/json{"properties": {"published": ["2016-02-21T12:50:53-08:00"],"category": ["foo","bar" ] }}
GET /micropub?q=source&url=https://aaronpk.example/post/1000Authorization: Bearer xxxxxxxxxAccept: application/jsonHTTP/1.1200 OKContent-type: application/json{"type": ["h-entry"],"properties": {"published": ["2016-02-21T12:50:53-08:00"],"content": ["Hello World"],"category": ["foo","bar" ] }}
If the source of the post was written as HTML content, then the endpointMUST return thecontent
property as an object containing anhtml
property. Otherwise, the endpointMUST return a string value for thecontent
property, and the client will treat the value as plain text. This matches the behavior of the values of properties in [microformats2-parsing].
Below is an example of requesting the content of a post which was authored as HTML.
GET /micropub?q=source&properties=content&url=https://aaronpk.example/post/1000Authorization: Bearer xxxxxxxxxAccept: application/jsonHTTP/1.1200 OKContent-type: application/json{"properties": {"content": [ {"html":"<b>Hello</b> <i>World</i>" } ] }}
To return a list of supported syndication targets, set theq
parameter tosyndicate-to
.
GET /micropub?q=syndicate-to
The endpointMUST return the response in [JSON] format, with a key ofsyndicate-to
and the values being objects descriptive of the supported syndication targets. If no endpoints are defined, the value of thesyndicate-to
objectSHOULD be an empty JSON array[]
.
At a minimum, a syndication targetMUST have auid
and human-readablename
property. Theuid
can be any identifier unique to the Micropub endpoint and is not intended to be visible to the end user. Thename
is intended to be visible to the user in the posting interface, and should be descriptive of the syndication destination.
A syndication targetMAY optionally include additional details about the service or user account at the syndication destination, indicated with a property calledservice
anduser
respectively. Both service and user objectsMUST contain aname
property, intended to be displayed to the user, andMAY contain aurl
andphoto
property. The client can use the name and photo to improve the display of the syndication options to the user.
GET /micropub?q=syndicate-toAuthorization: Bearer xxxxxxxxxAccept: application/jsonHTTP/1.1200 OKContent-type: application/json{"syndicate-to": [ {"uid":"https://archive.org/","name":"archive.org" }, {"uid":"https://wikimedia.org/","name":"WikiMedia" }, {"uid":"https://myfavoritesocialnetwork.example/aaronpk","name":"aaronpk on myfavoritesocialnetwork","service": {"name":"My Favorite Social Network","url":"https://myfavoritesocialnetwork.example/","photo":"https://myfavoritesocialnetwork.example/img/icon.png" },"user": {"name":"aaronpk","url":"https://myfavoritesocialnetwork.example/aaronpk","photo":"https://myfavoritesocialnetwork.example/aaronpk/photo.jpg" } } ]}
At a minimum, a syndication destinationMUST haveuid
andname
properties. Theuid
property is opaque to the client, and is the value the client sends in the Micropub request to indicate the targets to syndicate to. Thename
property is the value the client can display to the user. The name should be unambiguously descriptive of the destination, so that if for example there are two destinations on the same service, the name can disambiguate them.
The Micropub serverMAY also include additional information about the destination service and user account. This is accomplished with the additional propertiesservice
anduser
, both of which can have three properties,name
(a human-readable name),url
andphoto
(both URLs).
The client may use the service and user properties to enhance the display of the syndication options, for example by including the user or service photos on the syndication buttons.
Servers that support syndicating postsSHOULD support thesyndicate-to
query.
Clients and servers wishing to extend the functionality of the query action are encouraged to brainstorm and document implementations atindieweb.org/Micropub-extensions.
If there was an error with the request, the endpointMUST return an appropriate HTTP status code, typically 400, 401, or 403, andMAY include a description of the error. If an error body is returned, the response bodyMUST be encoded as a [JSON] object and include at least a single property namederror
. The following error codes are defined:
"error":"forbidden"
- The authenticated user does not have permission to perform this request."error":"unauthorized"
- No access token was provided in the request. Note that this is different from the HTTP 403 response, as the 403 response should only be used when an access token is provided and the user does not have permission to perform the request."error":"insufficient_scope"
- The scope of this token does not meet the requirements for this request. The client may wish to re-authorize the user to obtain the necessary scope. The responseMAY include the"scope"
attribute with the scope necessary to successfully perform this request."error":"invalid_request"
- The request is missing a required parameter, or there was a problem with a value of one of the parametersClientsSHOULD treat unexpected error strings as a generic error. The response bodyMAY also contain anerror_description
property with a human-readable description of the error message, used to assist the client developer in understanding the error. This is not meant to be shown to the end user.
See the OAuth 2 Bearer Token [RFC6750] spec for more details on the how to return error responses.
GET /micropub?q=source&url=https://aaronpk.example/post/404Authorization: Bearer xxxxxxxxHTTP/1.1400 Bad RequestContent-type: application/json{"error":"invalid_request","error_description":"The post with the requested URL was not found"}
The vocabularies used in Micropub requestsSHOULD be the vocabularies defined by [Microformats2]. If the Microformats2 vocabulary is used, clients and serversMUST support at least the [h-entry] vocabulary. Other vocabularies with widespread usage include [h-event] and [h-card]. When creating objects, the vocabulary of the object is indicated in the parameterh
, ortype
in the JSON syntax. If no type is provided, the serverSHOULD assume a default value ofentry
.
This section is non-normative.
To indicate the object being created, use a property calledh
, (which would never be the name of a property of a Microformats object), followed by the name of the Microformats object. Examples:
h=entry
h=card
h=event
h=cite
The following properties may be included in a request to create a new [h-entry]:
Posting a new note with tags, syndicating to myfavoritesocialnetwork:
POST/micropub HTTP/1.1Host: aaronpk.exampleAuthorization: Bearer XXXXXXXXXXXContent-type: application/x-www-form-urlencoded; charset=utf-8h=entry&content=My+favorite+of+the+%23quantifiedself+trackers%2C+finally+released+their+official+API&category[]=quantifiedself&category[]=api&mp-syndicate-to=https://myfavoritesocialnetwork.example/aaronpk
POST/micropub HTTP/1.1Host: aaronpk.exampleContent-type: application/x-www-form-urlencoded; charset=utf-8Authorization: Bearer XXXXXXXh=entry&content=Hello+World
curl https://aaronpk.example/micropub -d h=entry -d "content=Hello World" -H "Authorization: Bearer XXXXXXX"
Posting a new note with tags, syndicating to myfavoritesocialnetwork:
POST/micropub HTTP/1.1Host: aaronpk.exampleAuthorization: Bearer XXXXXXXXXXXContent-type: application/x-www-form-urlencoded; charset=utf-8h=entry&content=%40BarnabyWalters+My+favorite+for+that+use+case+is+Redis.&in-reply-to=https://waterpigs.example/notes/4S0LMw/&mp-syndicate-to=https://myfavoritesocialnetwork.example/aaronpk
Posting a new article with HTML content. Note that in this case, thecontent
property is sent as an object containing the keyhtml
. This corresponds with the Microformats 2 syntax for indicating the parsed value contains HTML. Becausecontent
is an object, this request must be sent in JSON format.
POST/micropub HTTP/1.1Host: aaronpk.exampleContent-type: application/json{"type": ["h-entry"],"properties": {"name": ["Itching: h-event to iCal converter"],"content": [ {"html":"Now that I've been <a href=\"https://aaronparecki.com/events\">creating a list of events</a> on my site using <a href=\"https://p3k.io\">p3k</a>, it would be great if I could get a more calendar-like view of that list..."} ],"category": ["indieweb","p3k" ] }}
To create an article containing embedded images, the HTML of the article should include<img>
tags with the URLs of the images returned after uploading them to the Media Endpoint.
First, upload one or more images to the Media Endpoint. Typically this will happen before the article is published, such as when the user is authoring the article in a visual editor. The editor can upload the images to the Media Endpoint as soon as the user drags them into the interface, and then embed the images into the editor via the resulting URL. SeeUploading to the Media Endpoint for an example of this request.
The response after uploading the file to the Media Endpoint will be a URL that the client can use when posting the article.
HTTP/1.1201 CreatedLocation: https://media.example.com/file/ff176c461dd111e6b6ba3e1d05defe78.jpg
The client can then use this URL to embed this image in an article.
POST/micropub HTTP/1.1Host: aaronpk.exampleContent-type: application/json{"type": ["h-entry"],"properties": {"content": [ {"html":"<p>Hello World</p><p><img src=\"https://media.example.com/file/ff176c461dd111e6b6ba3e1d05defe78.jpg\"></p>"} ] }}
When a Micropub request includes a file, the entire request is sent inmultipart/form-data
encoding, and the file is named according to the property it corresponds with in the vocabulary, eitheraudio
,video
orphoto
. A requestMAY include one or more of these files.
For example, a service may post a video in thevideo
property as well as a single frame preview of the video in thephoto
property.
In PHP, these files are accessible using the $_FILES array:
$_FILES['video']$_FILES['photo']$_FILES['audio']
Note that there is no way to upload a file when the request body is JSON encoded. Instead, you can first send the photo to the Media Endpoint and then use the resulting URL in the JSON post.
The Micropub endpoint may store the file directly, or make an external request to upload it to a different backend storage, such as Amazon S3.
Micropub requestsMUST be authenticated by including a Bearer Token in either the HTTP header or a form-encoded body parameter as described in the OAuth Bearer Token RFC [RFC6750]. Micropub serversMUST accept the token using both methods.
Authorization: Bearer XXXXXXXXX
access_token=XXXXXXXXX
An app that wants to post to a user's Micropub endpoint will need to obtain authorization from the user in order to get an access token. AuthorizationSHOULD be handled via the OAuth 2.0 [RFC6749] protocol. ApplicationsMAY use the [IndieAuth] extension which supports endpoint discovery from a URL. SeeObtaining an Access Token for more details.
Micropub defines a link relation value ofmicropub
to link to a website's Micropub endpoint from the profile page identifying the user.
A Micropub clientSHOULD be able to be configured by discovering the Micropub endpoint for the user via this link relation.
The client looks for a<link rel="micropub">
tag in the HTML head of the URL used to authenticate, or anHTTP Link
header with a rel value ofmicropub
.
Link:<https://aaronpk.example/micropub>; rel="micropub"
<linkrel="micropub"href="https://aaronpk.example/micropub">
The Micropub serverMUST require the bearer token to include at least one scope value, in order to ensure posts cannot be created by arbitrary tokens.
The client may request one or more scopes during the authorization request. It does this according to standard OAuth 2.0 [RFC6749] techniques, by passing a space-separated list of scope names in the authorization request. SeeRFC6749 Section 3.3.
The authorization serverMUST indicate to the user any scopes that are part of the request, whether or not the authorization server recognizes the scopes. The authorization serverMAY also allow the user to add or remove scopes that the client requests.
Most Micropub servers require clients to obtain the "create" scope in order to create posts. However, some serversMAY require more granular scope, such as "delete", "update", or "create:video", in order to limit the abilities of various clients. SeeScope for more details and a list of all currently used values for scope.
Micropub endpoints that accept photos or other media may encounter a request from a client that contains a URL to a file on a domain other than the Micropub endpoint or Media Endpoint, such as if the client provides its own mechanism for uploading files. One defensive way Micropub servers can implement accepting URL values is to only download and store media from a list of trusted domains, such as the Micropub server's domain and its Media Endpoint, and store just the URL to the file otherwise.
These questions provide an overview of security and privacy considerations for this specification as guided by Self-Review Questionnaire: Security and Privacy ([security-privacy-questionnaire]).
The link relation type below has been registered by IANA per Section 6.2.1 of [RFC5988]:
This section is non-normative.
This section is non-normative.
You can find a list ofMicropub implementations on micropub.net
The editor wishes to thank theIndieWeb community and other implementers for their support, encouragement and enthusiasm. In particular, the editor wishes to thankAmy Guy,Barry Frost,Benjamin Roberts,Chris Webber,Christian Weiske,David Shanske,Emma Kuo,Kyle Mahan,Jeena Paradies,Malcolm Blaney,Martijn van der Ven,Marty McGuire,Mike Taylor,Pelle Wessman,Ryan Barrett,Sandro Hawke,Sven Knebel, andTantek Çelik.
This section is non-normative.
This section lists changes from the13 April 2017 PR to this version.
q
from the list of reserved POST body parameters since it is not used in POST requests.mp-
properties are also reserved in JSON syntax.This section lists changes from the18 October 2016 CR to the13 April 2017 PR.
multipart/form-data
requests for accepting media<code>
tag forx-www-form-urlencoded
andmultipart/form-data
This section lists changes from the16 August 2016 CR to the18 October 2016 CR.
not_found
from the list of error codes, changed from requiring a specific error code string to recommending these three and allowing the server to return othersmp-
andq=
functionalityThis section lists changes from the13 July 2016 WD to the16 August 2016 CR.
This section lists changes from the21 June 2016 WD to the13 July 2016 WD.
mp-action
toaction
since updates are only JSON requestsThis section lists changes from the04 May 2016 WD to the21 June 2016 WD.
access_token
valueThis section lists changes from the01 March 2016 WD to the04 May 2016 WD.
properties
key in updatessyndicate-to
response to include more details of the destinationThis section lists changes from the28 January 2016 FPWD to the01 March 2016 WD.