Read a page
curl -X POST https://api.marrow.navii.online/v1/scrape \ -H "Authorization: Bearer mrw_xxx" -H "Content-Type: application/json" \ -d '{"url":"https://en.wikipedia.org/wiki/Web_scraping","formats":["markdown"]}'The page comes back in data.data.body.
Parameters
Section titled “Parameters”| field | default | what it does |
|---|---|---|
url | — | required. Missing it is 400 url-required. |
formats | ["markdown"] | markdown is the only format served. Anything else is refused by name — see When a read stops. ⚠️ The singular format is not accepted; it used to mean something else (Obsidian frontmatter) and a silently-ignored spelling would have changed what you got. |
depth | "shallow" | "deep" runs a real browser: JavaScript executes, hidden sections are revealed. Slower, and the only way to read a page that draws itself client-side. |
maxAge | 86400000 (24h) | Milliseconds. How old a stored capture may be before we go and fetch again. 0 forces a live capture. The freshness default, in full. |
max_pages | 1 | Follow the page’s own “next” control up to this many pages, 1–25. Declaring more than 1 is the request to walk — you do not also need depth:"deep". Outside the range is 400 max-pages-invalid. |
max_tokens | none | A ceiling on what comes back. See below. |
timeout | 30000 | Milliseconds allowed for each page load. The whole read has its own 90-second deadline regardless. |
Billing. One read is one credit; a walked read is one credit per page actually fetched, so
a max_pages: 10 call costs at most 10 and bills what it got. A read served from cache is 0.1.
A read that stops is not billed at all.
Capping the size
Section titled “Capping the size”🚨 max_pages bounds what we fetch. It does not bound what you are handed. Ten pages of a
link index is ten page loads on our side and one large document on yours, and the two numbers
are not related: an index page is mostly hrefs, an article is mostly prose.
max_tokens is the second ceiling. It is estimated, not tokenised by any particular model —
ASCII at 4 characters per token, everything else at 2 — so treat it as a bound, not a count.
-d '{"url":"https://news.ycombinator.com/","max_pages":2,"max_tokens":3000}'What it cost you: tokenUsage
Section titled “What it cost you: tokenUsage”Every read reports its size, budget or no budget. With no max_tokens, you get the
measurement and nothing else:
"tokenUsage": { "rawTokens": 11003, "used": 11003, "truncated": false }Add a budget and four more fields appear, describing the cut:
"tokenUsage": { "rawTokens": 28819, "used": 3000, "budget": 3000, "truncated": true, "mode": "blocks", "blocksIncluded": 37, "blocksTotal": 402}| field | always? | means |
|---|---|---|
rawTokens | ✅ | the size of the document before any ceiling. Read it once without a budget to find out whether a budget is worth setting at all. |
used | ✅ | what you were actually handed. Equal to rawTokens when nothing was cut. |
truncated | ✅ | whether anything was dropped. |
budget | only with max_tokens | the ceiling you asked for. ⚠️ Absent means you did not ask for one — it is never reported as 0, because 0 would mean you asked for nothing. |
mode | only with max_tokens | how it was cut. blocks = whole blocks were selected by score, so you got complete pieces. text = there were no blocks to choose from, so the body itself was cut at the ceiling. |
blocksIncluded / blocksTotal | only with max_tokens | in blocks mode, how much of the document made it. In text mode both are 0 — ⚠️ that is “there was nothing to select from”, not “nothing was selected”. |
Where the cut lands, the body ends with ... [truncated by token budget]. A link that was cut
through the middle is removed rather than handed to you half-written.
⚠️ The budget does not lower the bill. You are charged for the pages we fetched, which is what
cost us the browser — see max_pages above. Setting max_tokens buys you back
context, not credits.
🚨 depth changes how much you get for the same one credit, in both directions. Measured on
2026-09-17: a 4gamer article is 8,654 estimated tokens on the default path and 1,587 with
depth:"deep" — the deep read strips the furniture. The Hacker News front page is 2,430 by default
and 14,636 deep, because a deep read harvests every link. Same URL, same price, and nothing
tells you which you are about to get. Read rawTokens and decide from there.
⚠️ Do not set it when you want the whole page. Building a catalog from a reference table is the clearest case: a budget silently gives you a shorter page, and a shorter page gives you a shorter catalog that still looks complete.