Back to Manual

Micropub API

Pika supports the Micropub standard, an open API for creating and updating posts from third-party apps. You can use any Micropub client to publish to your Pika blog.

Contents


Setup

Go to Settings and click App tokens. Create a new token and copy it immediately — it won’t be shown again. Your token has create, update, and media scopes.

Your Micropub endpoint is:

https://pika.page/micropub

Your media endpoint is:

https://pika.page/micropub/media

If you’re using a Micropub client that supports endpoint discovery, it will find these automatically. Pika includes a <link rel="micropub"> tag in your blog’s HTML that points clients to your endpoint.


Using iA Writer

iA Writer has built-in Micropub support on Mac, iPhone, and iPad.

  1. Create an app token in Settings → App tokens on Pika and copy it to your clipboard.
  2. In iA Writer, go to Settings → Publishing → + button → Micropub.
  3. Choose Enter Token Manually.
  4. Enter your blog’s URL (e.g. https://you.pika.page) and paste your app token. iA Writer will discover your Micropub endpoint automatically.
  5. While still in iA Writer’s Publishing settings, with Micropub selected, click Options… and set the format to Markdown.

To send your post to Pika as a draft, right-click a document in your library and choose Publish → New Draft on Micropub. Note: Pika uses the leading heading (#, ##, or ###) in your post as the blog post title. Pika does not use the iA Writer filename as the blog post title.


Using Drafts

You can publish a draft post from Drafts by installing the Post to Pika action.

  1. Create an app token in Settings → App tokens on Pika and copy it to your clipboard.
  2. Install the Post to Pika action as a basic action in Drafts.
  3. Run the action for the first time. When prompted, paste your app token when asked for the authentication token.

Write your post in Drafts, then run the Post to Pika action to send it as a draft to Pika. If the first line of your draft is a Markdown heading (#, ##, ###, etc) it is used as the post title.


Using Obsidian

You can publish from Obsidian by installing the Pika.publish plugin. Pika.publish was created by Otávio, and all instructions for setup are included at the plugin page linked above. Thank you, Otávio!


Authentication

All requests require a Bearer token in the Authorization header:

Authorization: Bearer YOUR_TOKEN

Creating posts

Send a POST request to /micropub. Content supports Markdown.

Form-encoded

POST /micropub
Content-Type: application/x-www-form-urlencoded

h=entry&content=Hello+**world**&name=My+Post&category[]=ruby&category[]=rails

JSON

POST /micropub
Content-Type: application/json

{
  "type": ["h-entry"],
  "properties": {
    "content": ["Hello **world**"],
    "name": ["My Post"],
    "category": ["ruby", "rails"]
  }
}

To create a draft post add the following property:

"post-status": ["draft"]

On success the response is 201 Created with a Location header pointing to the new post. If the user has a custom domain, the Location header will point to the post on that custom domain. The Location header will point to the Pika dashboard page to edit the post when saving a draft post.


Updating posts

Updates use JSON and require the post URL. Three operations are supported:

Replace properties

{
  "action": "update",
  "url": "https://you.pika.page/posts/my-post",
  "replace": {
    "content": ["Updated **content**"],
    "name": ["New Title"],
    "category": ["new-tag"],
    "post-status": ["draft"]
  }
}

Add values

{
  "action": "update",
  "url": "https://you.pika.page/posts/my-post",
  "add": {
    "category": ["another-tag"]
  }
}

Remove values

{
  "action": "update",
  "url": "https://you.pika.page/posts/my-post",
  "delete": {
    "category": ["remove-this-tag"]
  }
}

On success the response is 200 OK with the updated post properties.

Photos work a little differently. See the media endpoint for adding, changing, or removing a photo from an existing post.


Querying

Use GET requests to query your Micropub endpoint.

Server configuration

GET /micropub?q=config

Returns the media endpoint URL.

Post source

GET /micropub?q=source&url=https://you.pika.page/posts/my-post

Returns the post’s properties including content (as Markdown), title, tags, status, and published date. To request specific properties only, add properties[]=name&properties[]=content.

Any embed in the post comes back as the link it was made from, on a line by itself, so editing a post in your client and sending it back keeps the player intact.

Custom HTML comes back as a pikahtml code fence, which is the form Pika reads back in.


Media endpoint

Upload images before creating or updating a post. The media endpoint accepts JPEG, PNG, GIF, and WebP files.

POST /micropub/media
Content-Type: multipart/form-data

file=@photo.jpg

On success the response is 201 Created with a Location header containing the image URL. Use this URL in your post content or as a photo property:

{
  "type": ["h-entry"],
  "properties": {
    "content": ["Check out this photo"],
    "photo": ["https://pika.page/micropub/media/abc123"]
  }
}

Photos can also include alt text:

"photo": [{"value": "https://pika.page/micropub/media/abc123", "alt": "A sunset"}]

Adding a photo to an existing post

Upload the image, then add its URL as a photo property in an update. The image is appended to the end of the post:

{
  "action": "update",
  "url": "https://you.pika.page/posts/my-post",
  "add": {
    "photo": [{"value": "https://pika.page/micropub/media/abc123", "alt": "A sunset"}]
  }
}

Changing or removing a photo

Pika keeps photos in the post body rather than as a property of their own, so anything beyond appending means editing the body: replace the post’s content, referencing each image in Markdown wherever you want it, and leaving out any you’re removing. Since replace overwrites the whole body, include the rest of the post’s text too:

{
  "action": "update",
  "url": "https://you.pika.page/posts/my-post",
  "replace": {
    "content": ["Check out this photo\n\n![A sunset](https://pika.page/micropub/media/abc123)"]
  }
}
Media endpoint flow for client developers
1. UPLOAD IMAGES

   For each image in the post, upload it first:

   POST /micropub/media
   Authorization: Bearer <token>
   Content-Type: multipart/form-data
   file=@photo.jpg

   Response:
   201 Created
   Location: https://pika.page/micropub/media/abc123


2. USE THE URLS IN YOUR POST

   Reference the returned URLs in your markdown
   content or as photo properties:

   POST /micropub
   Authorization: Bearer <token>
   Content-Type: application/json

   {
     "properties": {
       "content": ["![My cat](https://pika.page/micropub/media/abc123)"],
       "name": ["Post With Photos"]
     }
   }

   Response:
   201 Created
   Location: <post URL>

   Pika recognizes its own media URLs and efficiently
   uses the original upload — no re-downloading.

3. PREVIEWING UPLOADS

   GET /micropub/media/abc123 requires the same
   Bearer token. Use this to preview uploads in
   your client before submitting the post.


4. UPLOAD NEW IMAGES

   Updating a post works the same way. Upload any
   image the post does not already have:

   POST /micropub/media
   Authorization: Bearer <token>
   Content-Type: multipart/form-data
   file=@cover.jpg

   Response:
   201 Created
   Location: https://pika.page/micropub/media/def456


5. USE THE URLS TO UPDATE YOUR POST

   Send the URL as a photo to append it to the post:

   POST /micropub
   Authorization: Bearer <token>
   Content-Type: application/json

   {
     "action": "update",
     "url": "https://you.pika.page/posts/my-post",
     "add": {
       "photo": ["https://pika.page/micropub/media/def456"]
     }
   }

   Response:
   200 OK

Supported properties

content
Post body in Markdown. Images in content are automatically processed and stored by Pika.
name
Post title. Omit for a titleless post.
category
Tags. Pass as an array for multiple tags. Supports add and remove on update.
post-status
draft or published. Defaults to published.
published
Publish date as an ISO 8601 datetime (e.g. 2025-06-15T10:30:00Z).
photo
One or more image URLs to append to the post. Supports alt text via the object format.

Error responses

Errors follow the Micropub spec format:

{"error": "invalid_request", "error_description": "Missing content."}

Match on error. The error_description is human-readable and its wording may change.

401 Unauthorizedunauthorized
Missing or invalid token.
403 Forbiddeninsufficient_scope
Token does not have the required scope. The response includes a scope property naming it.
403 Forbiddenforbidden
You have reached the post limit on your Pika Pup account.
400 Bad Requestinvalid_request
Missing required fields or unsupported action.
404 Not Foundinvalid_request
Post not found (on update or query).
422 Unprocessable Entityinvalid_request
Post rejected when saving. Details in error_description.
429 Too Many Requests
Rate limit exceeded. See Rate limits.

Rate limits

The Micropub API is rate-limited per IP address. If you receive a 429 Too Many Requests response, back off before retrying — do not retry immediately.

Use exponential backoff starting at one minute. Retrying without waiting will keep your requests throttled.


Embeds

A link to a supported service becomes an embedded player, just as it does when you paste one into the Pika editor. Put the link on a line by itself:

Here is the song I cannot stop playing.

https://open.spotify.com/album/1ykUUKAFhLcHFdcaBHiOsx

Note: Auto-embedding of Bandcamp URLs via Micropub is currently not supported.


Custom HTML Pro

Custom HTML is code you write yourself that renders exactly as written on your site. The same block the ••• “More” menu adds in the editor. Over Micropub, write one as a fenced code block tagged pikahtml:

Here is the episode.

```pikahtml
<a data-flickr-embed="true" data-footer="true"
   href="https://www.flickr.com/photos/nasacommons/9461054584/in/album-72157634975731504"
   title="STS-66 Atlantis Landing and Chute Deployment at Edwards">
  <img src="https://live.staticflickr.com/5337/9461054584_f9445d4ac7_3k.jpg"
       width="3054" height="2383"
       alt="STS-66 Atlantis Landing and Chute Deployment at Edwards" />
</a>
<script async src="//embedr.flickr.com/assets/client-code.js" charset="utf-8"></script>
```

A source query returns your blocks in the same pikahtml form, so a client can fetch a post, edit it, and send it back without losing the block. Changing the code, or adding a new fence, requires an active Pika Pro subscription.

Note: an API token that can create posts can therefore publish HTML that runs on your site. Treat your tokens accordingly, and revoke any you no longer use.