---
title: How to serve documentation for agents
description: Learn how to serve markdown to agents and HTML for humans from the same URL
url: /kb/guide/how-to-serve-documentation-for-agents
canonical_url: "https://vercel.com/kb/guide/how-to-serve-documentation-for-agents"
published: 2026-01-14
last_updated: 2026-01-17
authors: Anthony Shew
related:
  - /docs/sitemap.md
install_vercel_plugin: npx plugins add vercel/vercel-plugin
---

Content negotiation allows clients to request different representations of the same resource using the HTTP-standard `Accept` header, rather than requiring different URLs.

For example, the Vercel documentation uses this technique to respond with markdown when an agent requests docs:

```bash
# Responds with HTML
curl https://vercel.com/docs


<!-- docsgraph:related -->
## Related pages

> **For AI agents:** Follow these links to understand how this page connects to the rest of the Vercel ecosystem. For the full cross-link map (inbound, outbound, prerequisites, and semantic neighbors), see the .graph.md link below.

- [Making agent-friendly pages with content negotiation](https://vercel.com/blog/making-agent-friendly-pages-with-content-negotiation?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related)
- [Markdown and Agent Discovery](https://vercel.com/docs/agent-resources/markdown-access?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Learn how Vercel serves documentation to AI agents as Markdown and helps them discover related pages through content neg
- [Docs pages support Markdown responses](https://vercel.com/changelog/docs-pages-support-markdown-responses?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related)
- [Serving Static Files](https://vercel.com/docs/platforms/multi-tenant-platforms/serving-static-files?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Serve tenant-specific static files like robots.txt, sitemap.xml, and llms.txt dynamically using route handlers.
- [Agent Resources](https://vercel.com/docs/agent-resources?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Resources for building with AI on Vercel, including documentation access, MCP servers, and agent skills.
- [Docs Contribution Guide](https://nextjs.org/docs/community/contribution-guide?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Learn how to contribute to Next.js Documentation
- [Make your documentation readable by AI agents](https://vercel.com/kb/guide/make-your-documentation-readable-by-ai-agents?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Serve markdown to AI agents using content negotiation, .md endpoints, agent auto-detection, llms.txt,   sitemap.md, and
- [vercel agent](https://vercel.com/docs/cli/agent?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Generate an AGENTS.md file with Vercel deployment best practices using the vercel agent CLI command.
- [Agent Readability: A Specification for AI-Optimized Websites](https://vercel.com/kb/guide/agent-readability-spec?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — When an agent visits your site, it needs to quickly find, read, and understand your pages. Sites that are easy for agent
- [Rendering content based on device](https://vercel.com/kb/guide/rendering-content-based-on-device?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Learn how to render different content based on the user agent in your Middleware.
- [Migrate to Vercel from Netlify](https://vercel.com/kb/guide/migrate-to-vercel-from-netlify?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=related) — Migrate your website's configuration from Netlify to Vercel

Full cross-link map for this page: [/kb/guide/how-to-serve-documentation-for-agents.graph.md](/kb/guide/how-to-serve-documentation-for-agents.graph.md?from=related&source_path=%2Fkb%2Fguide%2Fhow-to-serve-documentation-for-agents&source_site=vercel-kb&relationship=graph)
<!-- /docsgraph:related -->

# Responds with markdown
curl -H "Accept: text/markdown" https://vercel.com/docs
```

This guide assumes that your content is authored using markdown in a Next.js app, but can be adapted to your content authoring strategy and framework by converting your content to markdown on-the-fly.

## Create a Route Handler for markdown responses

First, create a [Route Handler](https://nextjs.org/docs/app/getting-started/route-handlers) that returns markdown responses when it is requested:

```typescript
import { notFound } from 'next/navigation';
import { getMarkdownContent } from '@/lib/content';

export async function GET(
  _req: Request,
  { params }: { params: Promise<{ slug?: string[] }> }
) {
  const { slug } = await params;
  const content = getMarkdownContent(slug?.join('/') ?? 'index');

  if (!content) {
    notFound();
  }

  return new Response(content, {
    headers: {
      'Content-Type': 'text/markdown',
    },
  });
}
```

## Creating conditional responses

Add a function to your `next.config.ts` that handles the `Accept` header and use it to rewrite to the Route Handler you created previously:

```javascript
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  rewrites() {
    function markdownRewrite(prefix: string) {
      return {
        source: `${prefix}/:path*`,
        has: [
          {
            type: 'header',
            key: 'accept',
            value: '(.*)text/markdown(.*)',
          },
        ],
        destination: `${prefix}/:path*.md`,
      };
    }
    return {
      beforeFiles: [
        markdownRewrite('/docs'),
      ],
    };
  },
};

export default nextConfig;
```

## Add a sitemap.md

Leave a discovery point to the rest of your documentation in these responses, so the LLM knows where to continue searching for helpful content if it doesn’t find what it needs on the first try.

For example, [see the sitemap.md for the Vercel documentation](https://vercel.com/docs/sitemap.md).

In the following snippet, a table of contents is created to show the LLM all paths where it can retrieve more information in markdown:

```typescript
import { createTableOfContents, TocItem } from "@lib/content";

function renderTocItems(items: TocItem[], indent = '') {
  let sitemap = '';

  for (const item of items) {
    sitemap += `${indent}- [${item.title}](/${item.path})\n`;
    if (item.children) {
      sitemap += renderTocItems(item.children, `${indent}  `);
    }
  }

  return sitemap;
}

export async function GET() {
  const tableOfContents = createTableOfContents(`content`);

  const sitemap = `# Documentation sitemap\n\n${renderTocItems(tableOfContents)}`

  return new Response(sitemap, { headers: { 'Content-Type': 'text/markdown' } });
}
```

## Test it out

You can now use `curl` to receive different response types of your content.

```bash
# Responds with HTML
curl https://your-domain.com/docs

# Responds with markdown
curl -H "Accept: text/markdown" https://your-domain.com/docs
```