Developers: docs in Markdown, or one API call

Documentation is already HTML, and reviews happen in Markdown. WebInk sits in the middle when you need a readable diff, a snippet in an issue, or a fixture for a prompt. It is not a docs hosting platform and it does not crawl an entire documentation site.

One page you have open

On a docs tab, the extension converts the rendered article, including pages behind a login. Check code fences before you commit the file. A copy button from the docs theme should not become a line inside the sample. Heading depth should follow the article. The webpage to Markdown guide is the checklist.

If you already copied a fragment of HTML, skip the URL and use the HTML to Markdown tool. That is the right path for a widget snippet or a table you lifted out of view-source.

A public URL from a script

The developer API accepts a public URL and returns JSON or a Markdown body, depending on the Accept header. GET and POST /api/markdown are documented on that page, including an optional template string. Ask for text/markdown when you want the body written straight to a file. Ask for JSON when you also need the title and the other extracted fields.

The API fetch runs on the server. It sees what an anonymous request can see. It does not see your browser session, and it refuses private network targets. For localhost docs or an internal site, use the extension on the tab. The extension’s converter and the API’s converter are not the same code path. If a pipeline hashes the output, pin one of them and compare before you treat a diff as a content change.

What not to build on top

  • A bulk spider. One request is one page.
  • A promise that every docs theme emits identical fences. Spot-check a page with tabs, callouts, and a wide table.
  • An offline image archive from the API. Download .zip is an extension action. See ZIP export and the save guide.

Templates help when the file must carry front matter into a static site or a fixture folder. Variables such as {{title}} and {{url}} are listed on templates. Start with the API reference when you are writing the client, and with the extension when you are looking at the page.

Which surface belongs in the pipeline

Use the HTML to Markdown tool when a teammate pasted a fragment into chat and there is no URL to fetch. The tool strips script, style, noscript, iframe, and similar tags in the browser, converts with the same Markdown rules as the extension, and puts a leading H1 back when the fragment began with one. The download name is the slug used by the web tools. Send to AI on that page wraps the result in “Please analyze the following Markdown content:” and then the body. It does not add a URL line.

Use URL to Markdown when you want to see the API’s JSON before you script it. The page calls GET /api/markdown?url=… with Accept: application/json and shows the Markdown. The same endpoint with Accept: text/markdown, or with no JSON Accept header, returns the body alone. That is the response you redirect into a file.

Use the extension when the docs tab is logged in, rendered by the app, or served from a host the API is not allowed to fetch. The side panel is also where Download .zip, templates, the table of contents, and saved prompts live. A public mirror of the same page can still go through the API later, after you have compared one file by hand.

Requests that match the route

A body-only save of a public page:

curl -sS \
  -H "Accept: text/markdown" \
  "https://webink.app/api/markdown?url=https%3A%2F%2Fexample.com%2Fdocs%2Fcache"

JSON when you also want the title, excerpt, byline, site name, and published time the extractor found:

curl -sS \
  -H "Accept: application/json" \
  "https://webink.app/api/markdown?url=https%3A%2F%2Fexample.com%2Fdocs%2Fcache"

POST is the call that accepts a template. The template is a string with the same {{title}} and {{markdown}} style fields the extension uses. GET does not read a template query parameter.

curl -sS \
  -H "Accept: text/markdown" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/docs/cache","template":"# {{title}}\n\nSource: {{url}}\n\n{{markdown}}"}' \
  "https://webink.app/api/markdown"

Transform options on that POST are optional and limited to heading style, horizontal rule, bullet marker, code block style, emphasis delimiter, fence, and strong delimiter. If you send both a template and those options, the template is applied first and then replaced by a new conversion of the HTML. The wrapped text is discarded. Callers who need both a custom fence style and a front matter wrapper should send the options, take the body, and wrap it themselves.

The fetch tries a search-crawler identity and then a Chrome browser identity. Each attempt allows five redirects, a 15 second timeout, and about 10 MB of response body. A missing URL is a 400. A fetch that yields no article is a 404 with an error message. Responses that succeed advertise a public cache of two hours, with stale-while-revalidate of one day, and they vary on Accept. Do not point a tight content hash at a response you have not pinned to one converter and one day.

Private targets never reach that fetch. The URL must be http or https, and the resolved address must not be loopback, private, link-local, carrier-grade NAT, or unique-local. A docs site on localhost or a typical RFC 1918 host is an extension job. The developer API page is the longer reference, and /api/openapi.json is the generated description of the same route. llms.txt at the site root is a short brief for agents that need the public links without scraping the marketing pages.

Review the Markdown before you commit it

Docs themes hide the real sample inside tabs, callouts, and “copy” buttons. Open one page that has all three and read the fence. You want the sample, the language tag when the page provided one, and no “Copied!” line inside the code. A table should still have a header separator. A callout can become a blockquote. If the theme’s tab widget left every hidden panel in the document, the Markdown will contain every panel. That is an extraction limit, not a reason to average two runs.

A cleaned fragment from a cache article looks like this in a fixture file. It is an illustration of the shape, not a recording of the API:

# Cache

Source: https://example.com/docs/cache

## Delete on write

Remove the key in the same request that updates the row.

```text
DEL user:42:profile
```

Commit that file next to the code that renders it. When the upstream docs change, reconvert and read the diff as prose. A fence-marker change after you saved new transform options is a tool change. Note it in the pull request so reviewers do not treat it as a docs edit.

Extension options that affect a committed file

Until transform options are saved, the extension converter uses ATX headings, hyphen bullets, fenced backticks, and asterisk emphasis. The options form shows a suggested set that includes plus bullets and underscore italics. Those suggestions apply after you save the form. Prettier formatting runs by default (width 2, code blocks included) and returns the original Markdown if formatting fails. Turn it off in options when a snapshot must match the converter’s raw fences.

The extension strips a leading # title line. A fixture that must start with the docs title needs that heading in the template. The API path does not use this extension post-step. If your generator sometimes shells out to the extension and sometimes calls the API, the presence of the H1 will flap.

AI Fix, the wrench in the side panel, sends the Markdown through a formatting model and is disabled past 100,000 characters. It is a manual cleanup, not a step to hide inside a CI job. Translation is similarly a side-panel action and requires {{markdown}} in the selected template. Neither one is part of /api/markdown.

FAQ

Does GET /api/markdown accept a template?

GET accepts a url query parameter and returns Markdown unless you send Accept: application/json. A template string and transform options belong on POST /api/markdown. If a POST body includes both, the transform step runs after the template and replaces the Markdown with a fresh conversion of the HTML. Send one of them, or apply the template in your own code after you receive the body.

Will the API fetch localhost or an intranet host?

The API allows http and https, then blocks addresses that resolve to loopback, private, link-local, carrier-grade NAT, or unique-local ranges. Use the extension on a tab that is already open for docs that only exist on your machine or behind a VPN. The extension reads that document. It does not ask the API to fetch it.

Are extension Markdown and API Markdown interchangeable in a snapshot test?

They are different converters. The extension extracts the article in the browser, converts it with WebInk’s Markdown rules, then applies your template and optional formatting. The API uses its own reader. If you also send transform options, those options run a second conversion that replaces the text. Pin one path if a snapshot must mean the docs changed.

Can the API return a ZIP of images?

It returns Markdown text or a JSON object with the extracted fields. Download .zip is an extension action. It fetches remote Markdown images, writes the successful ones under images/, and rewrites those links. A script that needs the files can read the URLs from the Markdown and download them itself.

Where is the reference for the endpoint?

The developer page on this site documents GET and POST /api/markdown, including the Accept header and the optional template. An OpenAPI document is served at /api/openapi.json. llms.txt at the site root is a short product brief for agents, with links to the tools and the API page.

More from WebInk