Skip to main content

Reading a page in full

A search's snippet tells the agent whether a page is the right one; the page holds the fact. jevlin fetch --stdin reads up to five pages a search returned, in full, and answers with the same envelope a search does.

jevlin fetch --stdin takes one JSON object and answers with one envelope carrying the same header as a search, with command set to fetch. It sends POST /v1/fetch to the configured router with the same key, deadline, redirect policy and user agent as a search. The router serves only pages from this account's own recent search results, and only to an account that can fetch. The skill teaches it.

jevlin fetch --stdin <<< '{"version":1,"pages":[{"source_id":"s_…"}],"query":"the fact you need"}'

The request​

fieldvalue
version1, required.
pages1 to 5 entries, required. Each is exactly one of {"source_id": "s_…"}, a page's source_id from a search's result.merged, or {"url": "https://…"}, an absolute http or https URL.
max_chars1000 to 50000: how many characters of each page to return. Absent, the router's default.
offset0 or more: where in each page's text to start. Pass a page's next_offset to read on.
queryUp to 500 characters, not blank: the router starts a long page's text near the part that matches.

Every malformed value, and any other field, answers fix_input before the router is called. A field is spelled exactly as above: Pages or VERSION is unknown_field, naming the key, exit 2, and the router is never called.

The answer​

On success, result.pages is the router's pages in its order. Each has source_id, url, title, status, content, offset, next_offset (absent at the end of the text), content_length, truncated and full_length (present when the upstream cut the page), reason (on a failed page), provider, cached and cost_micros. result.usage has the call's cost_micros and latency_ms.

A page's status is ok, failed, invalid, or not_recent:

  • ok carries the page's content.
  • failed carries a reason: upstream_failed, which a later try may fix, or unrendered, a page that needs a browser.
  • not_recent is a page not among this account's recent results, so use the host's own fetch tool for it.

A page that did not come back is not a failed call: ok stays true.

What it costs​

Each page carries its own cost_micros, and result.usage.cost_micros is the call's, in millionths of a dollar. The price per page is on Pricing and credit.

When it fails​

router answercoderetryableaction
403 fetch_unavailablefetch_unavailablefalseconnect: this account cannot fetch, and error.message says why
404 or 405fetch_not_supportedfalsereport: this router has no fetch
503 fetch_disabledfetch_disabledfalsereport: this router has fetch switched off
502, or any other 5xx (another 503 too)the router's code, else router_errortrueretry
401the router's code, else unauthorizedfalselogin
402 search_credit_onlysearch_credit_onlyfalsereport: the credit left this week is reserved for search; fetch resumes at the weekly reset or after a top-up
any other statusas for a search

A fetch is one request and is never retried by the client. A failed fetch leaves the search's results standing: the skill tells the agent to answer from them, and on fetch_unavailable, fetch_not_supported or fetch_disabled to stop fetching for the task and tell you once, without running connect.

search_credit_only means the credit left is the part of the weekly allowance kept for search: search still works, and fetch resumes at the weekly reset or when credit is added. See Rate limits and spend caps.

See also​

  • The envelope: the header every answer shares, and the failure codes.
  • The MCP server: the same request as the fetch tool.
  • In Claude Code, a request holding a ' or a $ goes through a file in the requests folder; see Claude Code.