How do you convert a web page to Markdown to feed it to an AI model?
In short: The cleanest way to give a web page to a model is to convert it to Markdown first: menus, scripts and style code are dropped, while headings, paragraphs, lists and links stay. On the Wiozen API the POST /v1/web/fetch endpoint does this; you put only url in the body and get back the page title and its Markdown text. You then send that text to any chat model along with your question.
Why Markdown instead of HTML?
The HTML of a news or blog page is several times longer than the text you actually read: navigation menus, cookie notices, tracking scripts, inline styles. Send it to a model as is and you pay for every bit of it as input tokens, while the model hunts for the real text inside the noise. Markdown keeps only the content and its structure, so the same page goes out in fewer tokens and in a more readable form.
Markdown also keeps heading levels and lists. For requests like "summarize the third section" or "pull out the prices in the table", the model can see how the page is laid out.
How do I fetch a page in one request?
Send a JSON body to the endpoint with your API key. The only required field is url:
curl https://api.wiozen.com/v1/web/fetch \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/blog/post"}'The response contains the page title and the text converted to Markdown; read the text from the markdown field, or from content if that's missing. If url is missing, the request is rejected with 400 Missing required parameter: url, and a body that isn't a JSON object also gets 400. These errors aren't charged.
How do I get a model to summarize the fetched page?
Two requests are enough: fetch the page, then send the text with your question to the chat endpoint. The same key works on both:
import requests
H = {"Authorization": "Bearer sk-gw-..."}
BASE = "https://api.wiozen.com/v1"
page = requests.post(f"{BASE}/web/fetch", json={"url": "https://example.com/blog/post"},
headers=H, timeout=60).json()
text = page.get("markdown") or page.get("content") or ""
r = requests.post(f"{BASE}/chat/completions", headers=H, timeout=600, json={
"model": "wiozen-anthropic",
"max_tokens": 16000,
"messages": [{"role": "user",
"content": "Summarize this article in 5 bullet points:\n\n" + text[:60000]}],
})
print(r.json()["choices"][0]["message"]["content"])text[:60000] in the example cuts the text at about 60,000 characters, which is roughly 15,000 tokens. For very long pages, splitting the text into sections and asking about each one is an alternative to cutting it. All the text you send is charged as input; we cover what long input costs in what is a context window.
Which pages can't be fetched?
The page is fetched by a server on the internet, not by your computer, so only public addresses starting with http or https work. Wiozen doesn't fetch localhost, local network addresses or private IP ranges (such as 192.168.x.x or 10.x.x.x). You can't read a development server on your own machine or an intranet page with this endpoint.
The request carries only the address; your browser session, cookies or passwords don't go with it. So the protected content of a page that needs a login doesn't come through. A failed fetch isn't charged.
Where do I see the charge?
Each fetch comes off your balance like a chat request and gets its own row on the Usage page of your dashboard, where you see the exact cost of that request. A small amount is held from your balance when it starts; if your balance doesn't cover it, the request doesn't start and you get 429 Quota exhausted. Fetches also count toward the daily query limit, and any spend limit on your key applies here too.
If you need to send the same page to a model twice, fetching it once and keeping the Markdown on your side saves you the second fetch. We explain how to follow spend request by request in tracking spend request by request.
Frequently asked questions
Which endpoint converts a web page to Markdown?
POST https://api.wiozen.com/v1/web/fetch. Only the url field is required in the body.
Do I need a separate key?
No. The Wiozen API key you use for chat and image endpoints works here too.
Can I fetch a page on localhost or my local network?
No. The page is fetched by a server on the internet, so only public http and https addresses work.
Can pages behind a login be fetched?
No. The request doesn't carry your session, so content behind a login doesn't come through.
Do I pay for a failed fetch?
No. Pages that can't be fetched and bad requests such as a missing url aren't charged.
The full list of endpoints, with examples, is in the docs.
More guides: How can you use an AI API from Turkey without a credit card? · How do you connect an OpenAI-compatible API to a tool you already use? · How do you calculate the cost of an AI API? · What should I do if my AI API key has leaked? · How do you generate images with an AI API, and what does one image cost? · Why does my AI API return a 429 error, and how do I fix it? · Why do long AI API requests time out: streaming or non-streaming? · Anthropic Messages API or OpenAI Chat Completions: which one should I use? · What is a context window, and what is a 1 million token context good for? · Which AI model should I choose: deciding by price, context and quality · Why does a reasoning model return an empty answer, and why are thinking tokens charged? · Why is my API balance running out faster than expected? Tracking spend request by request · How do you get AI to write and publish articles in WordPress automatically? · How do you find blog topics from RSS feeds and Google Trends? · Does AI-written content show up on Google and in AI answers? · How do you get internal links into AI-written WordPress articles? · How do you get AI to generate a different featured image for every WordPress post? · How do you write a content brief when an AI writes your blog posts? · What should you watch for when an AI writes recipes for your food blog? · How do you fix errors when connecting a WordPress plugin to your AI API account? · Why does my AI article bot stop halfway in WordPress? "Run is stuck" and LiteSpeed · Why are my scheduled WordPress posts late? WP-Cron and a real server cron · How do I get an AI article bot to write blog posts in English or another language? · What does "Content Bot cannot generate articles" mean? Reading the bot's log