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

Authentication

View .md

Email sign-in, token verification, and IndieAuth endpoints.

BASE URL https://micro.blog
POST /account/signin

Emails a sign-in link to an existing account. When app_name and redirect_url match a registered app, the link opens redirect_url with a temporary token appended, such as epilogue://signin/ABCDEF1234567890ABCD. Exchange that token with POST /account/verify within 15 minutes. No authentication is required.

Note: Apps that use this sign-in flow must be registered with Micro.blog before sending app_name and redirect_url. Email help@micro.blog with the app name and redirect URL to request registration.

Example Request

curl -X POST "https://micro.blog/account/signin?email=example%40example.com&app_name=Example+App&redirect_url=exampleapp%3A%2F%2Fsignin%2F"

Query Parameters

Name Type Required Description
email string Required Email address for the account.
Example: example@example.com
app_name string Optional Name of the registered app requesting access. Without it, the email links to a sign-in on the Micro.blog website instead of your app.
Example: Example App
redirect_url string Optional Registered redirect URL for the app. Required when app_name is set, and the pair must match a registered app. The temporary token is appended to the end of this URL.
Example: exampleapp://signin/

Response

200 OK application/json

Returns an empty JSON object when the email is sent. Errors also return 200 with an error message, for example {"error": "Email address not found."} or {"error": "App name and redirect URL must be registered."}.

Example Response

{}
POST /account/verify

Exchanges the temporary token from the sign-in email for a permanent app token, or checks an existing app token, and returns account information. Send the token as a parameter, not in an Authorization header. Always store the returned token, because it can differ from the one you sent. Temporary tokens are exchanged for a permanent one, and tokens close to expiry are renewed.

Example Request

curl -X POST "https://micro.blog/account/verify?token=ABCDEF1234567890ABCD"

Query Parameters

Name Type Required Description
token string Required The temporary token from the sign-in redirect, or an existing app token. Pass the bare token value, without a Bearer prefix.
Example: ABCDEF1234567890ABCD

Response Properties

token string Bearer Token
Token to send as Authorization: Bearer {token} on authenticated requests.
Note: This token must be included in the Authorization header as Bearer {token} for authenticated API requests.
Example: ABCDEF1234567890ABCD
name string
The user’s display name. Same value as full_name.
Example: Manton Reece
username string
The user’s username.
Example: manton
avatar string
URL to the user’s avatar image.
Example: https://avatars.micro.blog/avatars/2026/1.jpg
bio string
The user’s bio.
default_site string
Hostname of the user’s default hosted blog, or an empty string when there isn’t one.
Example: manton.micro.blog
full_name string
The user’s full name.
Example: Manton Reece
gravatar_url string
URL to the user’s avatar image. Same value as avatar.
Example: https://avatars.micro.blog/avatars/2026/1.jpg
has_site boolean
Whether the user has a hosted Micro.blog blog.
Example: true
has_inkwell boolean
Whether the user has access to Inkwell.
Example: true
plan string
The user’s current subscription plan.
Example: premium
plans array of string
Array containing the user’s current plan.
Example: [premium]
is_fullaccess boolean
Always true. Kept for older clients.
Example: true
is_premium boolean
Whether the user has a premium subscription.
Example: true
is_using_ai boolean
Whether the user has AI features turned on.

Response

200 OK application/json

Returns the API token and account information. An unknown or expired token also returns 200, with {"error": "App token was not valid."}.

Example Response

{
  "token": "ABCDEF1234567890ABCD",
  "name": "Manton Reece",
  "username": "manton",
  "avatar": "https://avatars.micro.blog/avatars/2026/1.jpg",
  "bio": "",
  "default_site": "manton.micro.blog",
  "full_name": "Manton Reece",
  "gravatar_url": "https://avatars.micro.blog/avatars/2026/1.jpg",
  "has_site": true,
  "has_inkwell": true,
  "plan": "premium",
  "plans": [
    "premium"
  ],
  "is_fullaccess": true,
  "is_premium": true,
  "is_using_ai": false
}
GET /indieauth/auth

IndieAuth authorization endpoint. Send the user’s browser here to approve your app. The user signs in on the Micro.blog website if needed, sees an authorization screen, and on approval is redirected to redirect_uri with code and state query parameters. The code is valid for 60 seconds and can be used once. Exchange it with POST /indieauth/token, or with POST /indieauth/auth if you only need the user’s identity. Open this URL in a browser, not with an API token. Requests that send an Authorization header get a 403.

Note: redirect_uri must have the same scheme, host, and port as client_id, unless the client metadata at client_id lists it. A JSON document with redirect_uris, or <link rel="redirect_uri"> tags in an HTML page, both work. Apps with a custom URL scheme must publish client metadata. The JSON metadata can also set client_name and logo_uri for the authorization screen.

Example Request

curl -X GET "https://micro.blog/indieauth/auth?client_id=https%3A%2F%2Fexample-app.com%2F&redirect_uri=https%3A%2F%2Fexample-app.com%2Fcallback&state=state123&response_type=code&scope=profile+create+media&code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM&code_challenge_method=S256"

Query Parameters

Name Type Required Description
client_id string Required Your app’s client ID, an http or https URL. Micro.blog fetches it for the app name, logo, and allowed redirect URLs.
Example: https://example-app.com/
redirect_uri string Required URL to send the user back to after approval. See the note above for which URLs are accepted.
Example: https://example-app.com/callback
me string Optional The user’s blog URL. Defaults to the user’s hosted Micro.blog blog.
Example: https://example.micro.blog/
state string Optional Opaque value returned unchanged to redirect_uri. Use it to protect against CSRF.
Example: state123
response_type string Optional IndieAuth response type. Send code.
Example: code
scope string Optional Space-separated scopes to request. Supported scopes are profile, read, write, create, update, delete, media, follow, and channels. Others are ignored. write includes read, create, update, delete, and media.
Example: profile create media
code_challenge string Optional PKCE code challenge, the 43-character base64url SHA-256 hash of your code verifier. When set, the token exchange must send the matching code_verifier.
Example: E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
code_challenge_method string Optional PKCE method. Must be S256 when code_challenge is set.
Example: S256

Response

200 OK text/html

Returns the authorization screen. Users who aren’t signed in are redirected to the sign-in page first. An invalid PKCE challenge or a redirect_uri that isn’t allowed returns a 400 error page.

Example Response

<!doctype html>
<html>
  <body>IndieAuth authorization screen</body>
</html>
POST /indieauth/auth

Verifies an IndieAuth authorization code and returns the user’s identity, without issuing an access token. Use it when your app only needs to know who signed in. No authentication is required.

Example Request

curl -X POST "https://micro.blog/indieauth/auth?code=AUTHCODE&client_id=https%3A%2F%2Fexample-app.com%2F&redirect_uri=https%3A%2F%2Fexample-app.com%2Fcallback&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

Query Parameters

Name Type Required Description
code string Required Authorization code from the redirect.
Example: AUTHCODE
client_id string Required The same client_id sent to GET /indieauth/auth.
Example: https://example-app.com/
redirect_uri string Required The same redirect_uri sent to GET /indieauth/auth.
Example: https://example-app.com/callback
code_verifier string Optional PKCE code verifier, 43 to 128 characters. Required when the authorization request included code_challenge.
Example: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

Response

200 OK application/json

Returns the user’s blog URL and profile. An invalid, expired, or already used code, or a mismatched client_id, redirect_uri, or code_verifier, returns 400 with {"error": "invalid_grant", "error_description": "..."}.

Example Response

{
  "me": "https://manton.micro.blog/",
  "profile": {
    "name": "Manton Reece",
    "url": "https://manton.micro.blog/",
    "photo": "https://avatars.micro.blog/avatars/2026/1.jpg",
    "nickname": "manton"
  }
}
GET /indieauth/token

Returns the blog URL, app name, scopes, and profile for an access token. Use it to check a token you already have.

Example Request

curl -X GET "https://micro.blog/indieauth/token" \
  --header "Authorization: Bearer ABCDEF1234567890ABCD"

Header Parameters

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

Response

200 OK application/json

Returns token information. client_id is the name of the app the token was issued to, and scope is a space-separated list. An unknown or expired token returns 400 with the plain-text message Token or user not found.

Example Response

{
  "me": "https://manton.micro.blog/",
  "client_id": "Example App",
  "scope": "profile create media",
  "profile": {
    "name": "Manton Reece",
    "url": "https://manton.micro.blog/",
    "photo": "https://avatars.micro.blog/avatars/2026/1.jpg",
    "nickname": "manton"
  }
}
POST /indieauth/token

Exchanges an IndieAuth authorization code for an access token and the user’s profile. No authentication is required.

Example Request

curl -X POST "https://micro.blog/indieauth/token?code=AUTHCODE&client_id=https%3A%2F%2Fexample-app.com%2F&redirect_uri=https%3A%2F%2Fexample-app.com%2Fcallback&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"

Query Parameters

Name Type Required Description
code string Required Authorization code from the redirect.
Example: AUTHCODE
client_id string Required The same client_id sent to GET /indieauth/auth.
Example: https://example-app.com/
redirect_uri string Required The same redirect_uri sent to GET /indieauth/auth.
Example: https://example-app.com/callback
code_verifier string Optional PKCE code verifier, 43 to 128 characters. Required when the authorization request included code_challenge.
Example: dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

Response

200 OK application/json

Returns the granted scopes and profile. token_type and access_token are included only when the user granted a scope other than profile. An invalid, expired, or already used code, or a mismatched client_id, redirect_uri, or code_verifier, returns 400 with {"error": "invalid_grant", "error_description": "..."}.

Example Response

{
  "scope": "profile create media",
  "me": "https://manton.micro.blog/",
  "profile": {
    "name": "Manton Reece",
    "url": "https://manton.micro.blog/",
    "photo": "https://avatars.micro.blog/avatars/2026/1.jpg",
    "nickname": "manton"
  },
  "token_type": "Bearer",
  "access_token": "ABCDEF1234567890ABCD"
}