CARVIEW |
Micropub
W3C Working Draft
- This version:
- https://www.w3.org/TR/2016/WD-micropub-20160713/
- Latest published version:
- https://www.w3.org/TR/micropub/
- Latest editor's draft:
- https://micropub.net/draft/
- Test suite:
- https://micropub.rocks/
- Implementation report:
- https://micropub.net/implementation-reports/
- Previous version:
- https://www.w3.org/TR/2016/WD-micropub-20160621/
- Editor:
- Aaron Parecki
- Repository:
- Github
- Issues
- Commits
Copyright © 2016 W3C® (MIT, ERCIM, Keio, Beihang). W3C liability, trademark and permissive document license rules apply.
Abstract
Micropub is an open API standard used to create posts on one's own domain using third-party clients. Web apps and native apps (e.g., iPhone, Android) can use Micropub to post short notes, photos, events or other posts to your own site.
Author's Note
This section is non-normative.
This specification was contributed to the W3C from the IndieWeb community. More history and evolution of Micropub can be found on the IndieWeb wiki.
Status of This Document
This section describes the status of this document at the time of its publication. Other documents may supersede this document. A list of current W3C publications and the latest revision of this technical report can be found in the W3C technical reports index at https://www.w3.org/TR/.
This document was published by the Social Web Working Group as a Working Draft. This document is intended to become a W3C Recommendation. If you wish to make comments regarding this document, please send them to public-socialweb@w3.org (subscribe, archives). All comments are welcome.
Please see the Working Group's implementation report.
Publication as a Working Draft does not imply endorsement by the W3C Membership. This is a draft document and may be updated, replaced or obsoleted by other documents at any time. It is inappropriate to cite this document as other than work in progress.
This document was produced by a group operating under the 5 February 2004 W3C Patent Policy. W3C maintains a public 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 contains Essential Claim(s) must disclose the information in accordance with section 6 of the W3C Patent Policy.
This document is governed by the 1 September 2015 W3C Process Document.
1. Introduction
This section is non-normative.
Micropub is a spec to create content 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, or responses) 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.
1.2 Background
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.
2. Conformance
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].
2.1 Conformance Classes
This section describes the conformance criteria for Micropub clients and servers.
2.1.1 Publishing Clients
A conforming Micropub client that creates posts:
- MUST support sending x-www-form-urlencoded requests
- MUST support the [h-entry] vocabulary
- If the client creates posts by uploading file attachments, it MUST check for the presence of a Media Endpoint and if present, send the file there instead of to the Micropub endpoint
- SHOULD handle server error messages gracefully, presenting helpful messages to the user
- SHOULD support endpoint discovery given an [IndieAuth] identity URL
2.1.2 Editing Clients
A conforming Micropub client that edits posts:
- MUST support sending JSON-encoded requests
- MUST support the [h-entry] vocabulary
2.1.3 Servers
A conforming Micropub server:
2.2 Candidate Recommendation Exit Criteria
For this specification to exit the CR stage, there must be at 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:
2.2.1 Client
A Micropub Client is an implementation that sends Micropub requests to create or otherwise manipulate posts. The conformance criteria are described in Conformance Classes above.
2.2.2 Server
A Micropub Server is an implementation that can create and optionally edit and delete posts given a Micropub request. The Micropub server MAY also support a Media Endpoint for handling file uploads outside of the primary Micropub endpoint. The conformance criteria are described in Conformance Classes above.
2.2.3 Independent
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.
2.2.4 Interoperable
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.
2.2.5 Implementation
An Implementation is a Micropub Client or Server which meets all of the following criteria:
- implements the corresponding conformance class of the specification
- is available to the general public, as downloadable software or as a hosted service
- is not experimental (i.e. is intended for a wide audience and could be used on a daily basis)
- is suitable for a person to use as his/her primary implementation on a website
2.2.6 Feature
For the purposes of evaluating exit criteria, each of the following is considered a feature:
- Discovering the Micropub endpoint given the profile URL of a user
- Authenticating requests by including the access token in the HTTP
Authorization
header - Authenticating requests by including the access token in the post body for
x-www-form-urlencoded
requests - Limiting the ability to create posts given an access token by requiring that the access token contain at least one OAuth 2.0 scope value
- Creating a post using
x-www-form-urlencoded
syntax with one or more properties - Creating a post using JSON syntax with one or more properties
- Creating a post using
x-www-form-urlencoded
syntax with multiple values of the same property name - Creating a post using JSON syntax with multiple values of the same property name
- Creating a post using
x-www-form-urlencoded
syntax including a nested Microformats2 object - Creating a post using JSON syntax including a nested Microformats2 object
- Uploading a file to the specified Media Endpoint
- Creating a post with a file by sending the request as
multipart/form-data
to the Micropub endpoint - Returning
HTTP 201 Created
and aLocation
header when creating a post - Returning
HTTP 202 Created
and aLocation
header when creating a post - Updating a post and replacing all values of a property
- Updating a post and adding a value to a property
- Updating a post and removing a value from a property
- Returning
HTTP 200 OK
when updating a post - Returning
HTTP 201 Created
when updating a post if the update cause the post URL to change - Returning
HTTP 204 No Content
when updating a post - Deleting a post using
x-www-form-urlencoded
syntax - Deleting a post using JSON syntax
- Undeleting a post using
x-www-form-urlencoded
syntax - Undeleting a post using JSON syntax
- Uploading a photo to the Media Endpoint and using the resulting URL when creating a post
- Querying the Micropub endpoint with
q=config
to retrieve the Media Endpoint and syndication targets if specified - Querying the Micropub endpoint with
q=syndicate-to
to retrieve the list of syndication targets - Querying the Micropub endpoint for a post's source content without specifying a list of properties
- Querying the Micropub endpoint for a post's source content looking only for specific properties
2.3 Test Suite and Reporting
Please submit your implementation reports at https://micropub.net/implementation-reports/. Instructions are provided at the URL. The implementation report template references the tests available at micropub.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.
3. Syntax
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.
3.1 Overview
All Micropub requests to create posts are sent as x-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, it SHOULD be returned as a [JSON] encoded object.
3.2 Reserved Properties
A few POST body property names are reserved when requests are sent as x-www-form-urlencoded or multipart 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 createdq
- used to query a Micropub endpointurl
- indicates the URL of the object being changedaction
- indicates whether this is adelete
, orundelete
mp-*
- reserved for future use
When creating posts, all other properties in the request are considered properties of the object being created.
The server MUST NOT store the access_token
property in the post.
3.3 Create
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 servers MUST support creating posts using the x-www-form-urlencoded encoding, and MAY also support creating posts using the JSON 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, use array bracket notation for the property name.
e.g., category[]=foo&category[]=bar
Properties that accept multiple values MUST also accept a single value as a string. A complete example of a form-encoded request follows.
h=entry&content=hello+world&category[]=foo&category[]=bar
3.3.1 Uploading Files
To upload files, the client MUST check for the presence of a Media 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 as multipart/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, named h
, content
and photo
.
multipart/form-data; boundary=553d9cee2030456a81931fb708ece92c
--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="h"
entry
--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="content"
Hello World!
--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="photo"; filename="aaronpk.png"
Content-Type: image/png
Content-Transfer-Encoding: binary
... (binary data) ...
--553d9cee2030456a81931fb708ece92c--
For properties that can accept a file upload (such as photo
or video
), the Micropub endpoint MUST also accept a URL value, treating that the same as if the file had been uploaded directly. The endpoint MAY download 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://photos.example.com/592829482876343254.jpg
This is to support uploading files via a Media Endpoint, or by reference to other external images. See the Media Endpoint section for more information.
The Accessible Platform Architectures Working Group has raised an issue requesting examples of how to include accessibility-related information such as image alt text when creating posts that contain an image. Please see Issue 34 to track the progress of this issue.
3.3.2 JSON Syntax
Alternately, 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 values MUST be specified as arrays, identical to the Microformats 2 JSON format.
{
"type": ["h-entry"],
"properties": {
"content": ["hello world"],
"category": ["foo","bar"],
"photo": ["https://photos.example.com/592829482876343254.jpg"]
}
}
3.3.3 Nested Microformats Objects
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.
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.
h=entry
&summary=Weighed+155.73+pounds
&weight[type]=h-measure
&weight[properties][num]=155.73
&weight[properties][unit]=lb
&bodyfat[type]=h-measure
&bodyfat[properties][num]=19.83
&bodyfat[properties][unit]=%
{
"type": ["h-entry"],
"properties": {
"summary": [
"Weight 155.73 pounds"
],
"weight": [
{
"type": ["h-measure"],
"properties": {
"num": ["155.73"],
"unit": ["lb"]
}
}
],
"bodyfat": [
{
"type": ["h-measure"],
"properties": {
"num": ["19.83"],
"unit": ["%"]
}
}
]
}
}
3.3.4 Unrecognized Properties
If the request includes properties that the server does not recognize, it SHOULD create the post anyway with any values that are recognized, and SHOULD store the unrecognized values internally, and return them when queried.
This allows clients to post rich types of content to servers that recognize it, while also posting fallback content to servers that don't.
3.3.5 Response
When the post is created, the Micropub endpoint MUST return either an HTTP 201 Created
status code or HTTP 202 Accepted
code, and MUST return a Location
header indicating the URL of the created post. [RFC2616]
HTTP/1.1 201 Created
Location: https://aaronpk.example/post/1000
If the endpoint chooses to process the request asynchronously rather than creating and storing the post immediately, it MUST return an
HTTP 202 Accepted
status code, and MUST also return the Location
header in this case. If the server is going to return 202, it MUST ensure the object will be created successfully prior to returning 202, as clients will expect the object at the indicated URL to exist at some point in the (near) future. In other words, the server must do any error checking and validation before returning 202.
If the target also provides a shortlink, or if it syndicated the post to another location, the Micropub endpoint MAY 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"
Error Response
See the "Error Responses" section below for details on how to indicate an error occurred.
3.4 Update
Micropub servers SHOULD 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 request MUST also include either a replace
,
add
or delete
property containing the updates to make.
The values of each property inside the replace
, add
or delete
keys MUST be an array, even if there is only a single value.
3.4.1 Replace
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.
3.4.2 Add
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.
Adding a syndication URL
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": ["https://web.archive.org/web/20040104110725/https://aaronpk.example/2014/06/01/9/indieweb"]
}
}
Adding Tags
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": ["webmention","indieweb"]
}
}
3.4.3 Remove
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"]
}
}
3.4.4 Response
The server MUST respond to successful update requests with HTTP 200, 201 or 204. If the update operation caused the URL of the post to change, the server MUST respond with HTTP 201 and include the new URL in the HTTP Location
header. Otherwise, the server MUST respond with 200 or 204, depending on whether the response body has content. No body is required in the response, but the response MAY contain a JSON object describing the changes that were made.
3.5 Delete
Micropub servers SHOULD support deleting posts, and MAY support undeleting posts.
To delete an entire entry at a URL, send a POST request containing
action=delete
and the URL of the item in the
url
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"
}
3.6 Media Endpoint
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 server MAY 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.
3.6.1 Discovery
To advertise that the Micropub endpoint supports a Media Endpoint, the server MUST include a key called media-endpoint
with a value of the full URL of the Media Endpoint in the Micropub configuration request. Clients MUST NOT assume the Media Endpoint is on the same domain as the Micropub endpoint.
GET /micropub?q=config
Authorization: Bearer xxxxxxxxx
{
"media-endpoint": "https://media.example.com/micropub"
}
3.6.2 Authentication
The Media Endpoint MUST accept the same access tokens that the Micropub endpoint accepts.
3.6.3 Request
To upload a file to the Media Endpoint, the client sends a multipart/form-data
request with one part named file
. The Media Endpoint MAY ignore the suggested filename that the client sends.
multipart/form-data; boundary=553d9cee2030456a81931fb708ece92c
--553d9cee2030456a81931fb708ece92c
Content-Disposition: form-data; name="file"; filename="sunset.jpg"
Content-Type: image/jpeg
Content-Transfer-Encoding: binary
... (binary data) ...
--553d9cee2030456a81931fb708ece92c--
The Accessible Platform Architectures Working Group has raised an issue requesting examples of how to include accessibility-related information such as image alt text when creating posts that contain an image. Please see Issue 34 to track the progress of this issue.
3.6.4 Response
The Media Endpoint processes the file upload, storing it in whatever backend it wishes, and generates a URL to the file. The URL SHOULD be unguessable, such as using a UUID in the path. If the request is successful, the endpoint MUST return the URL to the file that was created in the HTTP Location
header, and respond with HTTP 201 Created
. The response body is left undefined.
HTTP/1.1 201 Created
Location: 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 Endpoint MAY periodically delete files uploaded if they are not used in a Micropub request within a specific amount of time.
3.7 Querying
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 a GET
request to the Micropub endpoint and use the
q
parameter to specify what you are querying.
The Micropub endpoint may include a query string such as ?micropub=endpoint
, so in this case, Micropub clients MUST append the q
parameter instead of replacing the query string.
3.7.1 Configuration
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 client SHOULD make a query request q=config
to obtain initial configuration information.
The server SHOULD include the following information in the configuration response.
- The list of syndication endpoints supported (see Syndication Targets for details)
- The Media Endpoint if supported
GET /micropub?q=config
Authorization: Bearer xxxxxxxxx
{
"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"
}
}
]
}
3.7.2 Source Content
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.
To query, make a GET
request to the Micropub endpoint and set the q
parameter to source
, and include the URL of the post in the url
parameter. The query can specify the list of properties being requested by setting one or more values for the properties
key. If more than one is specified, use array bracket notation for each name, according to [HTML5] URL encoding.
The endpoint MUST return the response in [microformats2-parsing] [JSON] format, with an object named properties
, where the keys are the names of the properties requested. If no properties are specified, then the response MUST include all properties, as well as a type
property indicating the vocabulary of the post.
GET /micropub?q=source&properties[]=published&properties[]=category&url=https://aaronpk.example/post/1000
Authorization: Bearer xxxxxxxxx
{
"properties": {
"published": ["2016-02-21T12:50:53-08:00"],
"category": [
"foo",
"bar"
]
}
}
GET /micropub?q=source&url=https://aaronpk.example/post/1000
Authorization: Bearer xxxxxxxxx
{
"type": "h-entry",
"properties": {
"published": ["2016-02-21T12:50:53-08:00"],
"content": ["Hello World"],
"category": [
"foo",
"bar"
]
}
}
HTML Content
If the source of the post was written as HTML content, then the endpoint MUST return the content
property as an object containing an html
property. Otherwise, the endpoint MUST return a string value for the content
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/1000
Authorization: Bearer xxxxxxxxx
{
"properties": {
"content": [
{
"html": "<b>Hello</b> <i>World</i>"
}
]
}
}
3.7.3 Syndication Targets
To return a list of supported syndication targets, set the q
parameter to syndicate-to
.
GET /micropub?q=syndicate-to
The endpoint MUST return the response in [JSON] format, with a key of syndicate-to
and the values being objects descriptive of the supported syndication targets.
GET /micropub?q=syndicate-to
Authorization: Bearer xxxxxxxxx
Accept: application/json
HTTP/1.1 200 OK
Content-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 destination MUST have uid
and name
properties. The uid
property is opaque to the client, and is the value the client sends in the Micropub request to indicate the targets to syndicate to. The name
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 server MAY also include additional information about the destination service and user account. This is accomplished with the additional properties service
and user
, both of which can have three properties, name
(a human-readable name), url
and photo
(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.
3.8 Error Response
If there was an error with the request, the endpoint MUST return an appropriate HTTP status code, typically 400, 401, or 403, and MAY include a description of the error. If an error body is returned, the response body MUST be encoded as a [JSON] object and include at least a single property named error
with the value set to one of the below:
- HTTP 403:
forbidden
- The authenticated user does not have permission to perform this request - HTTP 401:
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 response MAY include the "scope" attribute with the scope necessary to successfully perform this request. - HTTP 400:
invalid_request
- The request is missing a required parameter, or there was a problem with a value of one of the parameters - HTTP 400:
not_found
- The post with the requested URL was not found
The response body MAY also contain an error_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/404
Authorization: Bearer xxxxxxxx
HTTP/1.1 400 Bad Request
Content-type: application/json
{
"error": "not_found",
"error_description": "The post with the requested URL was not found"
}
4. Vocabulary
The vocabularies used in Micropub requests SHOULD be the vocabularies defined by [Microformats2] version 2. If the Microformats2 vocabulary is used, clients and servers MUST 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 parameter h
, or type
in the JSON syntax. If no type is provided, the server SHOULD assume a default value of entry
.
4.1 Examples of Creating Objects
This section is non-normative.
To indicate the object being created, use a property called h
, (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]:
- name
- summary
- content
- published
- updated
- category
- location
- in-reply-to
- like-of
- repost-of
- syndication - Pass one or more URLs pointing to places where this entry already exists. Can be used for importing existing content to a site.
- like-of
- mp-syndicate-to = https://myfavoritesocialnetwork.example/aaronpk, https://archive.org/, etc.
- This property is giving a command to the Micropub endpoint, rather than just creating data, so it uses the mp- prefix.
4.1.1 New Note
Posting a new note with tags, syndicating to myfavoritesocialnetwork:
- content
- category
- published (optional, defaults to "now" if not present. Useful for writing offline and syncing later.)
- mp-syndicate-to
POST /micropub HTTP/1.1
Host: aaronpk.example
Authorization: Bearer XXXXXXXXXXX
Content-type: application/x-www-form-urlencoded
h=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
Minimal Example
POST /micropub HTTP/1.1
Host: aaronpk.example
Content-type: application/x-www-form-urlencoded
Authorization: Bearer XXXXXXX
h=entry
&content=Hello+World
curl https://aaronpk.example/micropub -d h=entry -d "content=Hello World" -H "Authorization: Bearer XXXXXXX"
4.1.2 New Reply
Posting a new note with tags, syndicating to myfavoritesocialnetwork:
- content
- in-reply-to
- published
- mp-syndicate-to
POST /micropub HTTP/1.1
Host: aaronpk.example
Authorization: Bearer XXXXXXXXXXX
Content-type: application/x-www-form-urlencoded
h=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
4.1.3 New Article
Posting a new article with HTML content. Note that in this case, the content
property is actually sent as an object containing the key html
. This corresponds with the Microformats 2 syntax for indicating the parsed value contains HTML.
- name
- content[html]
- category
- published
POST /micropub HTTP/1.1
Host: aaronpk.example
Content-type: application/x-www-form-urlencoded
h=entry
&name=Itching%3A+h-event+to+iCal+converter
&content[html]=Now+that+I%27ve+been+%3Ca+href%3D%22http%3A%2F%2Faaronparecki.com%22%3Ecreating+a+list+of+events%3C%2Fa%3E
+on+my+site+it+would+be+great+if+I+could+get+a+more+calendar-like+view+of+that+list...
&category[]=indieweb&category[]=hevent&category[]=events
&category[]=calendar&category[]=p3k
4.1.4 Adding Files
When a Micropub request includes a file, the entire request is sent in multipart form-data encoding, and the file is named according to the property it corresponds with in the vocabulary, either audio
, video
or photo
. A request MAY include one or more of these files.
For example, a service may post a video in the video
property as well as a single frame preview of the video in the photo
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.
5. Authentication and Authorization
5.1 Authentication
Micropub requests MUST 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 servers MUST accept the token using both methods.
HTTP Header
Authorization: Bearer XXXXXXXXX
Form-Encoded Body Parameter
access_token=XXXXXXXXX
5.2 Authorization
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. Authorization SHOULD be handled via the OAuth 2.0 [RFC6749] protocol, including the [IndieAuth] extension which supports endpoint discovery from a URL. See Obtaining an Access Token for more details.
5.3 Endpoint Discovery
Micropub defines a link relation value of micropub
to link to a website's Micropub endpoint from the profile page identifying the user.
A Micropub client SHOULD be able to be configured by authenticating with a domain name using [IndieAuth]. During this authentication (and authorization), the client discovers the Micropub endpoint which will be used to create posts, as well as obtains an access token it will use in the Micropub requests.
The client looks for a <link rel="micropub">
tag in the HTML head of the URL used to authenticate, or sends an HTTP Link
header with a rel value of micropub
.
HTTP Link Header
Link: <https://aaronpk.example/micropub>; rel="micropub"
HTML Link Tag
<link rel="micropub" href="https://aaronpk.example/micropub">
5.4 Scope
The Micropub server MUST 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 techniques, by passing a space-separated list of scope names in the authorization request. [RFC6749]
The authorization server MUST indicate to the user any scopes that are part of the request, whether or not the authorization server recognizes the scopes. The authorization server MAY 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 servers MAY require more granular scope, such as "delete", "update", or "create:video", in order to limit the abilities of various clients. See Scope for more details and a list of all currently used values for scope.
6. IANA Considerations
The link relation type below has been registered by IANA per Section 6.2.1 of [RFC5988]:
- Relation Name:
- micropub
- Description:
- Used for discovery of a Micropub endpoint which can be used to create posts according to the Micropub protocol.
- Reference:
- W3C Micropub Specification (https://www.w3.org/TR/micropub/)
A. Resources
This section is non-normative.
A.1 Implementations
This section is non-normative.
You can find a list of Micropub implementations on micropub.net
B. Acknowledgements
The editor wishes to thank the IndieWeb community and other implementers for their support, encouragement and enthusiasm.
C. Change Log
This section is non-normative.
C.1 Changes from 21 June 2016 WD to this version
- Clarified requirement of supporting file uploads directly or supporting a Media Endpoint
- Updated indiewebcamp.com references to indieweb.org due to redirects
- Rename
mp-action
toaction
since updates are only JSON requests - Added link to test suite in document header
- Added section describing how to submit implementation reports
- Added conformance criteria and classes section
- Updated example URLs
- Added list of features for exit criteria
- Added note about the accessibility group review
C.2 Changes from 04 May 2016 WD to 21 June 2016 WD
- Clarified use of arrays vs single values in requests
- Drop form-encoded syntax for update requests
- Removed warning about lack of interoperable implementations based on new implementations
- Updated list of implementations
- Added explicit note about not storing the
access_token
value - Added details and diagram on using a Media Endpoint for handling file uploads separately
- Expanded introduction and background
- Moved list of implementations out of this document onto https://micropub.net/implementations
C.3 Changes from 01 March 2016 WD to 04 May 2016 version
This section lists changes from the 01 March 2016 FPWD to this Working Draft
- Removed extra nesting of
properties
key in updates - Non-normative typo fixes
- Added HTTP 201 with Location header as a response for updates
- Updated
syndicate-to
response to include more details of the destination
C.4 Changes from 28 January 2016 FPWD to 01 March 2016 version
This section lists changes from the 28 January 2016 FPWD to this Working Draft
- Corrected references to be normative where appropriate
- Added new Conformance section summarizing conformance requirements for Micropub Clients and Servers
- Clarified that a server should create the post with any properties recognized when it receives a request with unrecognized properties
- Added a section on querying the Micropub endpoint for the source of specific properties, to better support editing
- Added new "Vocabulary" section which normatively references Microformats 2 vocabularies
- Micropub servers MAY include a JSON object describing the changes that were applied for Updates
- Added a section listing specific error responses, also referencing the OAuth 2 Bearer Token spec for other error responses
- If there is a response body, it SHOULD be JSON
- Default to create an h-entry if no type is specified
- Clarified posting files and sending HTML content
- Reorganized "How To" section into an "Authentication and Authorization" section
- Fixed some examples of HTTP requests that were missing the response headers
- Updated references from Microformats to Microformats 2
D. References
D.1 Normative references
- [HTML5]
- Ian Hickson; Robin Berjon; Steve Faulkner; Travis Leithead; Erika Doyle Navara; Edward O'Connor; Silvia Pfeiffer. W3C. HTML5. 28 October 2014. W3C Recommendation. URL: https://www.w3.org/TR/html5/
- [JSON]
- D. Crockford. IETF. The application/json Media Type for JavaScript Object Notation (JSON). July 2006. Informational. URL: https://tools.ietf.org/html/rfc4627
- [RFC2119]
- S. Bradner. IETF. Key words for use in RFCs to Indicate Requirement Levels. March 1997. Best Current Practice. URL: https://tools.ietf.org/html/rfc2119
- [RFC2616]
- R. Fielding; J. Gettys; J. Mogul; H. Frystyk; L. Masinter; P. Leach; T. Berners-Lee. IETF. Hypertext Transfer Protocol -- HTTP/1.1. June 1999. Draft Standard. URL: https://tools.ietf.org/html/rfc2616
- [RFC5988]
- M. Nottingham. IETF. Web Linking. October 2010. Proposed Standard. URL: https://tools.ietf.org/html/rfc5988
- [RFC6749]
- D. Hardt, Ed.. IETF. The OAuth 2.0 Authorization Framework. October 2012. Proposed Standard. URL: https://tools.ietf.org/html/rfc6749
- [RFC6750]
- M. Jones; D. Hardt. IETF. The OAuth 2.0 Authorization Framework: Bearer Token Usage. October 2012. Proposed Standard. URL: https://tools.ietf.org/html/rfc6750
- [h-entry]
- Tantek Çelik. microformats.org. h-entry. Living Specification. URL: https://microformats.org/wiki/h-entry
- [microformats2-parsing]
- Tantek Çelik. microformats.org. Microformats2 Parsing. Living Specification. URL: https://microformats.org/wiki/microformats2-parsing
D.2 Informative references
- [IndieAuth]
- Aaron Parecki. indieweb.org. IndieAuth. Living Specification. URL: https://indieweb.org/IndieAuth-spec
- [Microformats2]
- Tantek Çelik. microformats.org. Microformats 2. Living Specification. URL: https://microformats.org/wiki/microformats2
- [RFC5870]
- A. Mayrhofer; C. Spanring. IETF. A Uniform Resource Identifier for Geographic Locations ('geo' URI). June 2010. Proposed Standard. URL: https://tools.ietf.org/html/rfc5870
- [h-adr]
- Tantek Çelik. microformats.org. h-adr. Living Specification. URL: https://microformats.org/wiki/h-adr
- [h-card]
- Tantek Çelik. microformats.org. h-card. Living Specification. URL: https://microformats.org/wiki/h-card
- [h-event]
- Tantek Çelik. microformats.org. h-event. Living Specification. URL: https://microformats.org/wiki/h-event
1.1 Social Web Working Group
Micropub is one of two client APIs being produced by the Social Web Working Group with slightly different use cases and approaches. Interested implementers should check out and review the other approach, ActivityPub, as well.