# markdown.page API

All endpoints are under `https://markdown.page/api/`.

The API is intentionally forgiving: if you can send text, you can publish markdown. **No account, API key, or special header is required.**

---

## Publish a page

**`POST /api/publish`**  
**`POST /api`** also works as a short alias.

Send Markdown in the request body and receive a public page URL. The Markdown string may be up to 1 MB.

The easiest version works with no explicit content type:

```bash
curl https://markdown.page/api/publish --data-binary '# Hello world'
```

Publish a file:

```bash
curl https://markdown.page/api/publish --data-binary @README.md
```

A plain `curl -d` also works, even though curl labels it as form data:

```bash
curl https://markdown.page/api/publish -d '# Hello world'
```

Accepted request bodies:

- raw markdown text, with any content type or no content type
- `text/markdown` or `text/plain`
- JSON string: `"# Hello"`
- JSON object with one of `markdown`, `content`, `text`, or `body`
- URL-encoded form with one of `markdown`, `content`, `text`, or `body`

JSON example:

```bash
curl https://markdown.page/api/publish \
  -H 'Content-Type: application/json' \
  -d '{"markdown":"# Hello world"}'
```

Browser/fetch clients get `201` with a `Location` header and JSON containing `slug`, `url`, and `raw_url`:

```json
{
  "slug": "JCLcR63O",
  "url": "https://markdown.page/JCLcR63O",
  "raw_url": "https://markdown.page/JCLcR63O.md"
}
```

CLI clients such as curl/wget/httpie, or any request that asks for plain text, receive only the published URL:

```bash
curl https://markdown.page/api/publish --data-binary @README.md
curl -H 'Accept: text/plain' https://markdown.page/api/publish --data-binary @README.md
```

Errors are returned as JSON by default:

```json
{
  "error": "empty_body",
  "message": "Send markdown in the request body.",
  "example": "curl https://markdown.page/api/publish --data-binary '# Hello'"
}
```

Common statuses:

- `400` — empty body, invalid JSON, binary body, or Markdown fails validation
- `413` — request envelope or Markdown exceeds its size limit
- `403` — cross-origin browser request blocked
- `415` — multipart upload; send raw markdown instead
- `429` — fair-use rate limit exceeded
- `500` — slug allocation failure

---

## Machine-readable docs

**`GET /openapi.json`** and **`GET /api/openapi.json`** return an OpenAPI 3.1 specification suitable for importing markdown.page into API marketplaces, gateways, and agent/tool catalogs.

**`GET /api`** returns human HTML to browsers and readable plaintext to CLI clients such as curl, wget, and httpie.

Public GET routes support content negotiation:

- `Accept: text/html` returns rendered HTML
- `Accept: text/plain` or `Accept: text/markdown` returns plaintext/markdown where supported
- curl/wget/httpie with `Accept: */*` receive plaintext by default
- browser defaults receive HTML

Ask for markdown/plain text:

```bash
curl -H 'Accept: text/plain' https://markdown.page/api
curl https://markdown.page/api.md
```

Explicit `.md` URLs are available on public negotiated routes for bots, agents, and clients that do not perform HTTP content negotiation. Examples: `/faq.md`, `/api.md`, `/featured/artemis-ii.md`, and `/{slug}.md`.

---

## For agents and automation

- Prefer `Accept: text/plain` when you only need URLs or markdown.
- Use `GET /{slug}.md` to retrieve source markdown for published pages.
- Use `GET /{slug}` when you want negotiated HTML or plaintext.
- Published pages are public and cannot be edited; do not publish secrets or private data.

---

## Agentic featured purchases

Featured placements are paid promotions reviewed before publication.

Plans:

- `week` — $9 USD for 7 days
- `month` — $29 USD for 30 days
- `quarter` — $79 USD for 90 days

Machine-readable pricing:

- `GET /pricing.json` (alias: `GET /featured/pricing.json`)
- `GET /pricing.md`

Free quotes:

- **x402:** `GET /api/featured/purchase/{plan}`
- **MPP:** `GET /api/featured/mpp/purchase/{plan}`

Dry-run validation:

- `POST /api/featured/validate`

Paid purchase endpoints:

- **x402:** `POST /api/featured/purchase/{plan}`
- **MPP:** `POST /api/featured/mpp/purchase/{plan}`

Both create a paid request to feature an existing page. Supported plans are `week`, `month`, and `quarter`.

These endpoints are for agents and use HTTP `402 Payment Required`. A request without payment receives a machine-readable x402 or MPP payment challenge. After the agent pays and retries with the payment credential, the endpoint records the purchase as `paid_pending_review` for admin approval before launch. Review is typically within 48 hours.

Refund/rejection policy: promotions are reviewed before launch. Stripe rejections are refunded manually where appropriate. x402 and MPP payments are irreversible on-chain/testnet rails; rejected crypto-rail purchases receive manual resolution or promotion credit where technically possible while payments development continues.

Status:

- `GET /api/featured/purchases/{id}`

Review criteria:

- Page URL or pageId must already exist on markdown.page.
- Featured slug must use lowercase letters, numbers, and hyphens.
- Featured slug must not already be used by another page or pending purchase.
- Pages must comply with markdown.page content and security rules; spam, phishing, illegal content, harassment, and malware are rejected.

Example unpaid x402 response shape:

```http
HTTP/1.1 402 Payment Required
Payment-Required: <base64 payment requirements>
Content-Type: application/json
```

The decoded x402 requirements include the selected plan price, network such as `base-sepolia`, facilitator URL, and `payTo` address. Retry the same POST with the x402 payment credential headers.

Example unpaid MPP response shape:

```http
HTTP/1.1 402 Payment Required
WWW-Authenticate: Payment <challenge parameters>
Content-Type: application/json
```

The MPP challenge includes amount, currency, recipient, challenge expiry, and Tempo method details. Retry the same POST with `Authorization: Payment ...`.

Example body:

```json
{
  "articleUrl": "https://markdown.page/JCLcR63O",
  "featuredSlug": "hello-world",
  "contact": "you@example.com",
  "requestId": "agent-run-2026-05-31-001"
}
```

`requestId` is strongly recommended for idempotency and status lookup. It must be 8-128 characters using letters, numbers, underscore, period, colon, or hyphen. Agentic purchase ids are deterministic per rail: `x402:{requestId}` or `mpp:{requestId}`. Reusing the same `requestId` with the same rail and payment credential refers to the same purchase; reusing a payment credential for a different purchase is rejected.

Successful paid response:

```json
{
  "ok": true,
  "id": "x402:agent-run-2026-05-31-001",
  "provider": "x402",
  "status": "paid_pending_review",
  "pageId": "JCLcR63O",
  "featuredSlug": "hello-world",
  "plan": "week",
  "durationDays": 7,
  "approvalRequired": true
}
```

---

## MCP tools

**`POST /mcp`** exposes a public MCP-compatible HTTP JSON-RPC endpoint. **No account, API key, or auth header is required.** Transport is request/response HTTP JSON-RPC only; SSE streaming is not supported.

Tools:

```txt
publish_markdown({ markdown: string })
get_featured_pricing({})
validate_featured_purchase({ plan?, articleUrl? or pageId?, featuredSlug })
get_featured_purchase_status({ id: string })
```

`publish_markdown` uses the same validation, storage path, size limits, and fair-use rate limiting as `POST /api/publish`. Successful calls return MCP text content plus structured URL metadata: `slug`, `url`, and `raw_url`.

Featured commerce division of labor: MCP provides pricing discovery, pre-payment validation, and status lookup inside the agent loop; payment settlement happens over the raw HTTP `402 Payment Required` endpoints above. Status is also available over HTTP at `GET /api/featured/purchases/{id}`.

Example JSON-RPC call:

```bash
curl https://markdown.page/mcp \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"publish_markdown","arguments":{"markdown":"# Hello from MCP"}}}'
```

For full MCP tool schemas, see [`/mcp`](https://markdown.page/mcp). For agent discovery, see [`/llms.txt`](https://markdown.page/llms.txt). Agents can also load the task-focused [`markdown-page` skill](https://markdown.page/skill.md).

---

## Get raw markdown

**`GET /{slug}.md`**

Returns the original markdown source for a published page as `text/markdown; charset=utf-8`. Returns `404` if the page doesn't exist.

Example:

```bash
curl https://markdown.page/JCLcR63O.md
```

---

## Markdown rules

Standard Markdown plus GFM: headings, bold, italic, strikethrough, lists, task lists, links, images, inline code, fenced code blocks, blockquotes, and tables. Images must use `https://` or `http://` URLs. Links support `https://`, `http://`, and `mailto:`. Raw HTML, custom CSS, and JavaScript are not accepted. Maximum page size is 1 MB.
