Developers
Every article here is available four ways: as HTML, as Markdown at a predictable URL, as JSON over a public API, and through an MCP server. None of those need credentials. One endpoint is paid: the full corpus in a single call, settled with x402.
What you can actually do
- List every article with metadata, to decide what to fetch.
- Fetch one article as clean Markdown, with no navigation, footer or cookie banner in the way.
- Search article text by keyword.
- Pull the entire corpus in one request, if you would rather pay once than crawl.
What you cannot do, so you do not waste a call
- There are no user accounts, so there is no authentication to obtain for the free surfaces.
- There is no write operation of any kind. Every endpoint is read-only.
- There is no private or personal data behind any endpoint.
- There is no search beyond the article corpus. This is not a web index.
Markdown mirrors
Append /index.md to any page URL, or ask for Markdown with an Accept header on the page URL itself.
curl -s https://emin.de/posts/fazua-ride-50-speed-unlock-mac/index.md
# or negotiate on the HTML URL
curl -s -H 'Accept: text/markdown' https://emin.de/posts/fazua-ride-50-speed-unlock-mac
Responses carry Vary: Accept, so a cache cannot serve the HTML representation to a client that asked
for Markdown.
JSON API
Typed schemas for every operation are in openapi.json. Errors use RFC 9457 problem details.
# every article, with metadata
curl -s https://emin.de/api/articles
# one article, including its full Markdown body
curl -s https://emin.de/api/articles/fazua-ride-50-speed-unlock-mac
# an unknown slug returns application/problem+json, status 404
curl -s -i https://emin.de/api/articles/no-such-article MCP server
Streamable HTTP at /mcp, read-only, no credentials. The server card at
/.well-known/mcp/server-card.json lists the transport and the
tools, and the tool list there matches what the server actually implements:
list_articles, get_article_markdown, search_articles,
get_site_summary, list_topics.
# initialize, then list tools
curl -s -X POST https://emin.de/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
curl -s -X POST https://emin.de/mcp \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' Paid bulk access with x402
GET /api/v1/corpus returns every article's complete Markdown in one response. An unpaid request
returns a real HTTP 402 with a machine-readable challenge stating the amount, scheme, network and recipient. The
exact values in the challenge match what openapi.json declares.
# see the challenge
curl -s -i https://emin.de/api/v1/corpus This endpoint exists because crawling is the wrong shape for bulk ingestion, not as a paywall: every article is free to read individually, as HTML, as Markdown and over the JSON API. You are paying for one call instead of many, and you are not required to.
Rate limits and deprecation
API paths carry IETF RateLimit and RateLimit-Policy headers, and an exceeded limit
returns 429 with Retry-After. The limits in those headers are the limits actually enforced.
If an endpoint is ever retired it will first return the Deprecation header (RFC 9745) and a
Sunset header (RFC 8594) with the removal date, and be marked deprecated: true in the
OpenAPI document. Nothing is removed without that sequence.
Terms
Article text is licensed CC BY 4.0: quote it, translate it, train on it, with attribution to emin.de. The site's own code is MIT and the full source is on GitHub, including the implementation of every endpoint on this page.