Skip to main content

Overview

The Web2MD REST API lets you convert any webpage or raw HTML to clean Markdown programmatically. Use it to build pipelines, automate content ingestion, or integrate Web2MD into your own tools.
The REST API requires a PRO plan. Generate your API key from the Web2MD dashboard.

Machine-readable specs

ResourceURLDescription
OpenAPI 3.1 spec/api/v1/openapi.jsonFull API schema for code generation and tooling
AI plugin manifest/.well-known/ai-plugin.jsonAgent discovery (ChatGPT Plugins / AI assistants)
Use the OpenAPI spec to auto-generate client SDKs or import into tools like Postman, Swagger UI, or AI agent frameworks.

Authentication

All requests must include your API key in the Authorization header:
Authorization: Bearer w2m_your_key_here
API keys are prefixed with w2m_ and are tied to your account.

Endpoint

POST https://web2md.org/api/v1/convert

Request body

FieldTypeRequiredDescription
urlstringOne of url or htmlThe URL of the page to convert
htmlstringOne of url or htmlRaw HTML string to convert
optionsobjectNoConversion options (see below)
Provide either url or html, not both. The request will fail with a 400 error if both are present or neither is provided.

Options

FieldTypeDefaultDescription
includeImagesbooleantrueInclude image references in output
includeLinksbooleantruePreserve hyperlinks in output
includeMetabooleantruePrepend page metadata as YAML front matter

Response

A successful response returns:
{
  "success": true,
  "data": {
    "markdown": "# Page Title\n\nConverted content...",
    "metadata": {
      "title": "Page Title",
      "url": "https://example.com/article",
      "extractedAt": "2026-03-22T10:30:00.000Z",
      "wordCount": 1250,
      "tokenCount": 1680,
      "readingTime": 5,
      "author": "Jane Doe",
      "publishedDate": "2026-03-20",
      "description": "A brief summary extracted from the page meta tags."
    }
  }
}
FieldTypeDescription
titlestringPage title extracted from <title>
urlstringSource URL (if provided)
extractedAtstringISO 8601 timestamp of the conversion
wordCountintegerTotal word count (English words + CJK characters)
tokenCountintegerEstimated LLM token count
readingTimeintegerEstimated reading time in minutes
authorstring?Author name from meta tags or JSON-LD
publishedDatestring?Publication date (YYYY-MM-DD)
descriptionstring?Page description from Open Graph or meta tags

Rate limits

API requests are rate-limited to 60 requests per minute per API key. If you exceed the limit, the API returns a 429 status code. Wait for the reset window before retrying.

Error responses

StatusMeaningExample
400Bad request — missing or conflicting inputBoth url and html provided, or neither
401Unauthorized — invalid or missing API keyMissing Authorization header
422Unprocessable — the URL could not be fetchedTarget site returned an error or timed out
429Rate limit exceededMore than 60 requests in one minute
500Internal server errorUnexpected failure on our end
All error responses follow this shape:
{
  "success": false,
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "Rate limit exceeded. Try again in 45 seconds."
  }
}

Examples

Convert a URL with curl

curl -X POST https://web2md.org/api/v1/convert \
  -H "Authorization: Bearer w2m_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/blog/post",
    "options": {
      "includeImages": true,
      "includeLinks": true,
      "includeMeta": false
    }
  }'

Convert raw HTML with curl

curl -X POST https://web2md.org/api/v1/convert \
  -H "Authorization: Bearer w2m_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Hello World</h1><p>This is a <strong>test</strong> paragraph.</p>"
  }'

JavaScript (fetch)

const response = await fetch("https://web2md.org/api/v1/convert", {
  method: "POST",
  headers: {
    "Authorization": "Bearer w2m_your_key_here",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://example.com/blog/post",
    options: {
      includeImages: true,
      includeLinks: true,
    },
  }),
});

const result = await response.json();

if (result.success) {
  console.log(result.data.markdown);
  console.log(`Word count: ${result.data.metadata.wordCount}`);
} else {
  console.error(result.error.message);
}
Store your API key in an environment variable rather than hardcoding it. For example, use process.env.WEB2MD_API_KEY in Node.js.