---
title: "Accept: text/markdown content negotiation explained"
url: https://hostmy.blog/docs/rankready/accept-markdown-negotiation/
date: 2026-08-24
modified: 2026-08-25
lang: en
author: "Aditya Sharma"
description: "How RankReady answers the same canonical URL with HTML or Markdown depending on the Accept header, and why .md URLs never vary."
word_count: 787
---

# Accept: text/markdown content negotiation explained

This page explains how one URL on your site can return two different formats depending on who asks, how RankReady implements that, and how to test each case with a single command.

## What content negotiation is

Every HTTP request can carry an `Accept` header saying which formats the client can handle. A browser asks for HTML. A tool that wants plain text can ask for `text/markdown` instead. The server reads the header and picks a representation of the same resource.

The point is that the URL does not change. One canonical address, one piece of content, more than one way of expressing it. A link you share stays the link everyone uses, whether the thing following it wants a rendered page or plain text.

## How RankReady handles it

There are two behaviours, and the distinction is the important part of this page.

### The canonical URL negotiates

On your normal post URL, the `Accept` header decides the response:

| Request asks for | Response |
| ---------------- | -------- |
| `text/markdown` | Markdown |
| `text/html` | HTML, exactly as before |
| A type that cannot be served | `406` |

The `406` is a real answer, not a failure. It tells the client that the resource exists but not in the format it asked for, which is more useful than quietly returning HTML to something that said it could not read HTML.

### Distinct .md URLs never negotiate

A `.md` URL such as `/your-post-slug.md` always serves Markdown, regardless of the `Accept` header. This is deliberate, and the reason is cache safety.

Shared caches, whether that is a plugin, your host's page cache or a CDN, store a response against a URL. When one URL can return different bodies depending on a request header, every cache in the chain has to be configured to know that. Any layer that has not been told will serve whichever body it happened to store first, to everyone. That is how a plain text file ends up delivered to a browser, or a themed HTML page ends up delivered to a tool expecting Markdown.

Keeping `.md` URLs single purpose removes the question entirely. One address, one representation, safe to cache anywhere without special configuration. Negotiation stays on the canonical URL where it belongs, and the `.md` address remains the boring, reliable option.

## Turn it on in RankReady

- In wp-admin, open **RankReady**.
- Go to the **AI Visibility** tab, ending in `tab=crawlers`.
- Open the **Markdown** subtab, `sub=markdown`.
- Switch the feature on and save.

The same setting controls both the `.md` addresses and negotiation on the canonical URL. No [AI provider](https://hostmy.blog/docs/rankready/choose-ai-provider-cost/) key is involved.

![The Markdown settings screen in the RankReady AI Visibility tab](https://hostmy.blog/wp-content/uploads/2026/08/rr-markdown-v2-scaled.png)One toggle covers both the .md endpoints and Accept header negotiation.

## Verify all three cases

Use a real post URL. Pull one out of your `/llms.txt` if you are unsure, rather than typing a slug from memory.

**Ask for Markdown on the canonical URL:**

`curl -s -H 'Accept: text/markdown' https://your-site.com/your-post-slug/ | head -20`
You should get Markdown. Headings appear as `##`, and there is no theme markup.

**Ask for HTML on the same URL:**

`curl -s -H 'Accept: text/html' https://your-site.com/your-post-slug/ | head -5`
You should get your normal page, starting with a doctype. Nothing about your site for human visitors changes.

**Ask for something unsupported:**

`curl -s -o /dev/null -w '%{http_code}n' -H 'Accept: application/pdf' https://your-site.com/your-post-slug/`
You should see `406`. If you see `200`, negotiation is not reaching RankReady. Check the feature is on, then check what sits in front of the site.

**Confirm the .md URL does not vary:**

`curl -s -H 'Accept: text/html' https://your-site.com/your-post-slug.md | head -5`
Markdown is the correct result here. The `.md` URL ignoring your `Accept` header is the design working as intended.

## When negotiation does not appear to work

If the canonical URL returns HTML no matter what you ask for, something upstream is answering before WordPress does:

- Clear your page cache and try again. A cached HTML response will be replayed to every request regardless of headers.
- Test with the page cache plugin temporarily disabled to isolate it.
- If you sit behind a CDN, check whether it caches the canonical URL without accounting for the `Accept` header. Many do by default.
- Go to **Settings, Permalinks** and click Save Changes to rebuild rewrite rules.

Where a cache in front of your site cannot be made header aware, the `.md` URLs are the answer. They work through any cache because they never vary, which is precisely why they exist.

## How much this reaches

Only some clients send `Accept: text/markdown`. Many do not, and support changes without announcement. Negotiation is worth having, but it should never be your only route. The distinct `.md` URLs and your `/llms.txt` index cover clients that never send the header at all, and none of these mechanisms guarantee that anything reads your content. They only guarantee it is available in a clean form.