Web fetch

⚠️
Preview — this feature is being built; the design below is the spec.

The built-in syntic_web_fetch tool lets the model read the full content of a web page or online PDF during a request. Syntic downloads the page, turns it into clean text and hands it to the model. Pair it with web search (search finds pages, fetch reads them in full) or use it alone when the user gives an address.

When to use it

  • “Summarise this article” or “What does this page say about returns?” with a link.
  • Reading documentation pages, release notes or public PDFs.
  • Following up on search results that need more than a snippet.

Endpoint and auth

POST https://app.syntic.ai/v1/chat/completions (and Messages), Authorization: Bearer sk_live_....

Tool definition

FieldTypeRequiredDetails
typestringYes"syntic_web_fetch"
max_usesintegerNoFetches allowed in this request, 1 to 20. Default 5.
allowed_domains / blocked_domainsarray of stringsNoAs on web search.
max_content_tokensintegerNoTruncate each page to this many tokens. Default 20,000, maximum 100,000.
citationsobjectNo{"enabled": true} to cite passages from fetched pages.

Which addresses can be fetched

To stop the tool being used to leak data, the model may fetch only addresses that already appear in the conversation (in a user message, a tool result or an earlier search result). It cannot invent new addresses or build them from private data.

AllowedNot allowed
Public http and https pages and PDFsPrivate, internal or loopback addresses
Redirects up to 5 hops (each hop checked again)Non-standard ports other than 80, 443, 8080, 8443
Pages up to 10 MBPages that need a login, cookies or JavaScript to show content

Response

Like web search: the answer text, annotations when citations are on, and a record of the fetches:

{
  "message": {
    "role": "assistant",
    "content": "The returns window is 30 days and plants must be unopened.",
    "server_tool_calls": [
      { "id": "srv_02", "type": "syntic_web_fetch", "url": "https://shop.example.com/returns", "status": "ok", "content_tokens": 1830, "truncated": false }
    ]
  },
  "usage": { "prompt_tokens": 2410, "completion_tokens": 19, "total_tokens": 2429, "server_tool_use": { "web_fetch_requests": 1 } }
}
statusMeaning
okContent read.
not_allowedAddress not in the conversation, blocked by domain rules or not public.
failedTimeout, HTTP error or unsupported content.
too_largeOver 10 MB.

Failed fetches are reported to the model, which explains the problem or tries another source.

Examples

curl https://app.syntic.ai/v1/chat/completions \
  -H "Authorization: Bearer $SYNTIC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "Amara S1.2",
    "stream": false,
    "tools": [{ "type": "syntic_web_fetch", "max_uses": 2, "citations": { "enabled": true } }],
    "messages": [{ "role": "user", "content": "Summarise https://shop.example.com/returns in three bullet points." }]
  }'

Errors

Unified envelope. Individual fetch failures do not fail the request.

StatuscodeCause
400server_tool_not_supportedThe model cannot use web fetch.
400invalid_domain_filterBoth lists sent or malformed domains.
400invalid_max_content_tokensAbove 100,000.
403tool_disabledTurned off for your organisation.

Pricing and limits

Fetch feeNone. You pay only for the fetched content as input tokens.
Fetches per request20
Timeout15 seconds per fetch
CachePages are cached for up to 15 minutes per organisation.

Build notes for the platform team

  • Same server-side loop as web search; ship right after it.
  • Every fetch and every redirect hop goes through the shared outbound URL checks with DNS pinning.
  • Enforce the “address already in the conversation” rule in the server, not in the prompt.
Was this page helpful?