Build with Micro.blog logo
Build with Micro.blog
API Documentation

Posting and Micropub

View .md

Endpoints for publishing, replying, uploading media, and querying Micropub resources.

BASE URL https://micro.blog
GET /micropub

Answers Micropub queries for configuration, cross-posting services, categories, contacts, and existing posts or pages. The q parameter picks the query; an unknown value returns {}. Requires a token. q=source needs the read or update scope; the other queries accept any of read, create, update, delete, or media.

Example Request

curl -X GET "https://micro.blog/micropub?q=config" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD"

Examples

List recent posts

q=source returns items, each an h-entry with uid, name, content, summary, published, post-status, url, category, and syndication. Replies, likes, a thumbnail, and a location are added when the post has them. With url, the single h-entry comes back without the items wrapper. Pages carry microblog-template, microblog-smart, and microblog-generating instead.

{
  "items": [
    {
      "type": "h-entry",
      "properties": {
        "uid": [12345],
        "name": [""],
        "content": ["Hello world."],
        "summary": [""],
        "published": ["2026-04-26T12:00:00+00:00"],
        "post-status": ["published"],
        "url": ["https://example.micro.blog/2026/04/26/hello-world.html"],
        "category": ["Travel"],
        "syndication": []
      }
    }
  ]
}

List categories

q=category returns category names, plus Micro.blog details for each.

{
  "categories": ["Travel"],
  "microblog-categories": [
    {
      "uid": 42,
      "url": "https://example.micro.blog/categories/42",
      "name": "Travel",
      "path": "travel",
      "posts_count": 12
    }
  ]
}

Look up contacts

q=contact returns up to 10 Micro.blog users whose username starts with filter.

{
  "contacts": [
    {
      "name": "Manton Reece",
      "url": "https://www.manton.org/",
      "photo": "https://micro.blog/manton/avatar.jpg",
      "nickname": "manton"
    }
  ]
}

Query Parameters

Name Type Required Description
q string Required Query type: config, syndicate-to, category, contact, or source.
Example: config
mp-destination string Optional Blog to query, as the uid URL from a config destination. Falls back to the user’s default blog when it doesn’t match one of their blogs. Used by config, syndicate-to, category, and source.
Example: https://example.micro.blog/
mp-channel string Optional For source, list pages or collections instead of blog posts.
Example: pages
post-status string Optional For source, set to draft to list only drafts.
Example: draft
url string Optional For source, return one post by its URL instead of a list. Returns 400 when no post on the blog has this URL.
Example: https://example.micro.blog/2026/04/26/hello-world.html
category integer Optional For source, only list posts in this category ID.
Example: 42
filter string Optional For source, only list posts or pages whose title or text contains this text. For category, only list categories whose name starts with it. For contact, match usernames that start with it; at least 3 characters are needed to get results.
Example: travel
limit integer Optional For source, the maximum number of items to return.
Example: 20
offset integer Optional For source and contact, the number of items to skip.
Example: 20

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}.

Response

200 OK application/json

Returns a JSON object whose shape depends on q. The example shows q=config. Errors use the Micropub format, {"error": "invalid_request", "error_description": "..."}, with status 400.

Example Response

{
  "media-endpoint": "https://micro.blog/micropub/media",
  "destination": [
    {
      "uid": "https://example.micro.blog/",
      "name": "example.micro.blog",
      "microblog-audio": true,
      "microblog-default": true,
      "microblog-title": "Example Blog"
    }
  ],
  "post-types": [
    {
      "type": "note",
      "name": "Post",
      "properties": ["content", "published", "post-status", "category", "read-of", "mp-destination", "checkin", "location"]
    },
    {
      "type": "article",
      "name": "Article",
      "properties": ["name", "content", "published", "post-status", "category", "mp-channel", "mp-destination"]
    },
    {
      "type": "photo",
      "name": "Photo",
      "properties": ["name", "content", "published", "post-status", "category", "mp-destination", "photo", "mp-photo-alt"]
    },
    {
      "type": "reply",
      "name": "Reply",
      "properties": ["content", "in-reply-to"]
    },
    {
      "type": "bookmark",
      "name": "Bookmark",
      "properties": ["bookmark-of", "summary"]
    }
  ],
  "channels": [
    {
      "uid": "default",
      "name": "Posts"
    },
    {
      "uid": "pages",
      "name": "Pages"
    }
  ],
  "syndicate-to": [
    {
      "uid": "mastodon",
      "name": "Mastodon (@example@mastodon.social)"
    }
  ]
}
POST /micropub

Creates, updates, or deletes posts, pages, collections, bookmarks, and categories through Micropub. Send form-encoded parameters, multipart form data when uploading a photo file, or a Micropub JSON body. Creating needs the create scope, action=update needs update, and action=delete needs delete.

Note: Micro.blog reads a JSON body only when there’s no name form parameter. Updates (action=update with replace, add, or delete), check-ins, locations, and read-of are only read from JSON. Array parameters in a form use [], for example category[]=Travel&category[]=Food.
Note: A post whose content starts with an @-mention becomes a reply on Micro.blog rather than a blog post, and can’t include photos. To reply to a specific post, prefer POST /posts/reply.

Example Request

curl -X POST "https://micro.blog/micropub" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --data-urlencode "h=entry" \
  --data-urlencode "content=Hello world." \
  --data-urlencode "category[]=Travel"

Examples

Create a post with JSON

Photos in JSON can be URLs or {"value": "...", "alt": "..."} objects.

curl -X POST "https://micro.blog/micropub" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --header "Content-Type: application/json" \
  --data '{
    "type": ["h-entry"],
    "properties": {
      "content": ["Hello world."],
      "photo": [{"value": "https://example.micro.blog/uploads/2026/photo.jpg", "alt": "A sunset over the bay"}],
      "category": ["Travel"]
    }
  }'

Update a post

replace can set name, content, summary, post-status, published, category, photo, audio, and video.

curl -X POST "https://micro.blog/micropub" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --header "Content-Type: application/json" \
  --data '{
    "action": "update",
    "url": "https://example.micro.blog/2026/04/26/hello-world.html",
    "replace": {
      "content": ["Hello again."]
    }
  }'

Delete a post

curl -X POST "https://micro.blog/micropub" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --data-urlencode "action=delete" \
  --data-urlencode "url=https://example.micro.blog/2026/04/26/hello-world.html"

Create a category

With mp-channel=categories, name is the category name, and path and text set its URL path and description. Creating returns 202 with the category in the same shape as q=category. action=update with the category url returns 200 with the updated category, and action=delete returns 200 with {}.

curl -X POST "https://micro.blog/micropub" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --data-urlencode "mp-channel=categories" \
  --data-urlencode "name=Travel"

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}. As Micropub allows, the token can be sent as an access_token parameter instead.
Content-Type string Required application/x-www-form-urlencoded, multipart/form-data, or application/json.

Request Body

Name Type Required Description
h string Optional Micropub object type. Send entry; Micro.blog doesn’t require it.
Example: entry
content string Optional Post text, in Markdown or HTML. A new post needs content, photo, or bookmark-of.
Example: Hello world.
name string Optional Post title. Required for a new page (mp-channel=pages) or collection (mp-channel=collections), and used as the category name when mp-channel=categories.
Example: A title for a longer post
summary string Optional Post summary. For a bookmark, the note saved with it.
Example: A short summary.
published string Optional Publish date, as an ISO 8601 date. A future date schedules the post.
Example: 2026-04-26T12:00:00+00:00
post-status string Optional Set to draft to save a draft instead of publishing.
Example: draft
category array Optional Category names for the post. Repeat as category[] for several.
Example: Travel
photo array Optional Photo URL, usually from POST /micropub/media, or a photo file in a multipart request. Repeat as photo[] for several.
Example: https://example.micro.blog/uploads/2026/photo.jpg
mp-photo-alt array Optional Alt text for each photo, in the same order as photo. Repeat as mp-photo-alt[].
Example: A sunset over the bay
audio array Optional Audio file URL from POST /micropub/media. Repeat as audio[] for several.
Example: https://example.micro.blog/uploads/2026/episode.mp3
video array Optional Video file URL from POST /micropub/media. Repeat as video[] for several.
Example: https://example.micro.blog/uploads/2026/video.mp4
in-reply-to string Optional URL being replied to. The URL of a post on Micro.blog creates a Micro.blog reply; any other URL creates a blog post that starts “In reply to”.
Example: https://www.manton.org/2026/04/26/hello.html
bookmark-of string Optional URL to save as a Micro.blog bookmark. A bookmark isn’t published to the blog.
Example: https://example.com/article
bookmark-content string Optional HTML of the bookmarked page, used instead of downloading it. Only read with bookmark-of.
Example: <html>...</html>
repost-of string Optional URL being reposted. A link to it is added to the end of the content.
Example: https://example.com/post
mp-destination string Optional Blog to post to, as the uid URL from a config destination. Defaults to the user’s default blog.
Example: https://example.micro.blog/
mp-channel string Optional pages creates a standalone page, collections creates an upload collection, and categories creates, updates, or deletes a category. Leave it out for blog posts.
Example: pages
mp-navigation string Optional For a new page, set to 1 or true to add it to the blog’s navigation.
Example: 1
mp-syndicate-to array Optional Cross-posting service uids from q=syndicate-to, sent as mp-syndicate-to[]. Without it, the post goes to every cross-posting service the blog has enabled. Send one empty value to skip cross-posting.
Example: mastodon
action string Optional update or delete. Both need url. Updates take a JSON body.
Example: delete
url string Optional URL of the post, page, reply, collection, or category to update or delete.
Example: https://example.micro.blog/2026/04/26/hello-world.html

Response

202 OK application/json

A new blog post returns 202 with its URL in the Location header and a JSON body holding url, preview, and edit. New pages, new collections, and posts replying to sites outside Micro.blog return 202 with url. Bookmarks and replies to Micro.blog posts return 202 with an empty body. Updates and deletes return 200 with an empty body, or 404 when url isn’t found. Category changes return the category instead. Errors return 400 with {"error": "invalid_request", "error_description": "..."}.

Example Response

{
  "url": "https://example.micro.blog/2026/04/26/hello-world.html",
  "preview": "https://micro.blog/account/posts/123/preview/12345",
  "edit": "https://micro.blog/account/posts/123/edit/12345"
}
GET /micropub/media

Lists files uploaded to a blog, newest first. Only q=source is supported; any other query returns {}. The upload endpoint itself is advertised by GET /micropub?q=config. Requires a token with the read scope.

Example Request

curl -X GET "https://micro.blog/micropub/media?q=source&limit=20" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD"

Query Parameters

Name Type Required Description
q string Required Set to source.
Example: source
mp-destination string Optional Blog to list uploads for, as the uid URL from a config destination. Defaults to the user’s default blog.
Example: https://example.micro.blog/
filter string Optional Only list uploads whose alt text, generated description, keywords, or URL contains this text.
Example: sunset
microblog-collection string Optional Collection URL. Lists that collection’s uploads in their collection order, ignoring limit and offset.
Example: https://example.micro.blog/collections/7
limit integer Optional Maximum number of uploads to return.
Example: 20
offset integer Optional Number of uploads to skip.
Example: 20

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}.

Response

200 OK application/json

Returns an items array. Images include alt, microblog-ai (whether the alt text was generated), and sizes and cdn URLs; medium and small appear when those sizes exist. Videos with a poster image return url, poster, published, microblog-id, and duration instead.

Example Response

{
  "items": [
    {
      "url": "https://example.micro.blog/uploads/2026/photo.jpg",
      "published": "2026-04-26T12:00:00+00:00",
      "alt": "A sunset over the bay",
      "microblog-ai": false,
      "microblog-id": 12345,
      "sizes": {
        "large": "https://example.micro.blog/uploads/2026/photo.jpg",
        "medium": "https://example.micro.blog/uploads/2026/m-photo.jpg"
      },
      "cdn": {
        "large": "https://cdn.uploads.micro.blog/123/2026/photo.jpg",
        "medium": "https://cdn.uploads.micro.blog/123/2026/m-photo.jpg"
      }
    }
  ]
}
POST /micropub/media

Uploads a photo, video, or audio file, or updates or deletes an existing upload. Uploading needs the media scope and action=delete needs delete; action=update needs write. External blogs only accept images.

Example Request

curl -X POST "https://micro.blog/micropub/media" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --form "file=@/path/to/photo.jpg"

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}.
Content-Type string Required multipart/form-data for an upload.

Request Body

Name Type Required Description
file file Optional The file to upload. Required unless action is delete or update.
Example: @/path/to/photo.jpg
mp-destination string Optional Blog to upload to, as the uid URL from a config destination. Defaults to the user’s default blog.
Example: https://example.micro.blog/
action string Optional delete removes the upload at url. update sets the alt text of the upload at url to alt.
Example: delete
url string Optional URL of the upload to delete or update.
Example: https://example.micro.blog/uploads/2026/photo.jpg
alt string Optional New alt text, with action=update.
Example: A sunset over the bay

Response

202 OK application/json

An upload returns 202 with the file URL in the Location header and in the body. poster is a poster image URL for videos and an empty string otherwise. action=delete and action=update return 200 with an empty body; delete returns 404 when the upload isn’t found. Errors return 400 with {"error": "invalid_request", "error_description": "..."}.

Example Response

{
  "url": "https://example.micro.blog/uploads/2026/photo.jpg",
  "poster": ""
}
POST /micropub/media/append

Uploads one chunk of a large video or audio file. Send every chunk with the same file_id, in order, then call POST /micropub/media/finished. Requires a token with the media scope. External blogs don’t support chunked uploads.

Example Request

curl -X POST "https://micro.blog/micropub/media/append" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --form "file_id=12345" \
  --form "file_data=data:;base64,AAAA"

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}.

Request Body

Name Type Required Description
file_id integer Required Identifier your app generates for the file, shared by all of its chunks.
Example: 12345
file_data string Required Base64-encoded chunk data. A data URL prefix such as data:;base64, is stripped.
Example: data:;base64,AAAA
mp-destination string Optional Blog the file is for, as the uid URL from a config destination. Defaults to the user’s default blog.
Example: https://example.micro.blog/

Response

200 OK application/json

Returns an empty JSON object. Errors return 400 with {"error": "invalid_request", "error_description": "..."}.

Example Response

{}
POST /micropub/media/finished

Marks a chunked upload as complete and starts processing it. Poll GET /micropub/media/waiting for the final URL. Requires a token with the media scope.

Example Request

curl -X POST "https://micro.blog/micropub/media/finished" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --form "file_id=12345" \
  --form "file_name=video.mov"

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}.

Request Body

Name Type Required Description
file_id integer Required The file_id used for the appended chunks.
Example: 12345
file_name string Required Original file name. Its extension tells Micro.blog the file type.
Example: video.mov
mp-destination string Optional Blog the file is for, as the uid URL from a config destination. Defaults to the user’s default blog.
Example: https://example.micro.blog/

Response

200 OK application/json

Returns an empty JSON object once processing is queued. Errors return 400 with {"error": "invalid_request", "error_description": "..."}.

Example Response

{}
GET /micropub/media/waiting

Returns whether a chunked upload is still processing and, once it’s done, its URL. Requires a token with the media or read scope.

Example Request

curl -X GET "https://micro.blog/micropub/media/waiting?file_id=12345" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD"

Query Parameters

Name Type Required Description
file_id integer Required The file_id used for the upload.
Example: 12345

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}.

Response

200 OK application/json

url is null until processing finishes.

Example Response

{
  "is_processing": false,
  "url": "https://example.micro.blog/uploads/2026/video.mp4"
}
POST /posts/reply

Replies to a Micro.blog post or reply. Requires a token with the create scope.

Example Request

curl -X POST "https://micro.blog/posts/reply" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD" \
  --data-urlencode "id=77479242" \
  --data-urlencode "content=@manton Thanks for the update."

Header Parameters

Name Type Required Description
Authorization string Required Bearer token for authentication. Format: Bearer {token}.

Request Body

Name Type Required Description
id integer Required ID of the post being replied to.
Example: 77479242
content string Required Reply text, in Markdown. Include the @-mentions for everyone you’re replying to. text is accepted as an alias.
Example: @manton Thanks for the update.

Response

200 OK application/json

Returns an empty JSON object on success. When the reply can’t be sent, for example because replying is disabled, a trial account has no payment method, or it mentions a fediverse or Bluesky user without that service connected, the status is still 200 and the body is {"error": "..."}.

Example Response

{}