# Gemini — URL context (`tools[].urlContext`) **Status:** DOCUMENTED + LIVE_VERIFIED (2026-09-18 run — see "Live verification" section at the end) Sources: - https://ai.google.dev/gemini-api/docs/generate-content/url-context · https://ai.google.dev/gemini-api/docs/url-context - https://ai.google.dev/api/generate-content (#UrlContext #UrlContextMetadata #UrlMetadata #UrlRetrievalStatus #UsageMetadata) - https://ai.google.dev/gemini-api/docs/pricing · https://ai.google.dev/gemini-api/docs/changelog (experimental 2025-05, GA 2025-08) Last verified: 2026-09-18 (docs only) ## 1. Request `tools: [{"urlContext": {}}]` — no fields. URLs are taken from the prompt text (full URL with protocol). Retrieval is two-step: internal index cache, then live fetch fallback. Interactions API: `{"type":"url_context"}`. ## 2. Response | Field | Notes | |---|---| | `candidates[].urlContextMetadata.urlMetadata[]` | `{retrievedUrl, urlRetrievalStatus}` | | `urlRetrievalStatus` enum | `URL_RETRIEVAL_STATUS_SUCCESS`, `URL_RETRIEVAL_STATUS_ERROR`, `URL_RETRIEVAL_STATUS_PAYWALL`, `URL_RETRIEVAL_STATUS_UNSAFE` (content moderation failed), `URL_RETRIEVAL_STATUS_UNSPECIFIED` | | `usageMetadata.toolUsePromptTokenCount` (+ `toolUsePromptTokensDetails[]`) | tokens of the fetched content, billed as input | | with `includeServerSideToolInvocations` | `toolCall{toolType:URL_CONTEXT,args:{urls[]}}` / `toolResponse{response:{urls_metadata:[{retrieved_url,url_retrieval_status}]}}` | ## 3. Limits | Limit | Value | |---|---| | URLs per request | 20 | | Content per URL | 34 MB | | Accessibility | public URLs only — no localhost/127.0.0.1, private networks, tunnels (ngrok, pinggy), logins, paywalls | | Supported content types | text: `text/html`, `application/json`, `text/plain`, `text/xml`, `text/css`, `text/javascript`, `text/csv`, `text/rtf`; images: `image/png`, `image/jpeg`, `image/bmp`, `image/webp`; `application/pdf` | | Unsupported | paywalled content, YouTube videos (use video understanding), Google Workspace files (Docs/Sheets), video and audio files | | Nested links | not followed | | Live API | not supported | ## 4. Billing Free tier: free. Paid: fetched content is charged as **input tokens** at the model's rate (no per-call fee). ## 5. Models and combinations Guide table: gemini-3.8/3.7/3.6/3.5-flash, 3.5-flash-lite, 3.1-pro-preview, 3.1-flash-lite, 3-flash-preview, 2.5-pro/flash/flash-lite (model pages add gemini-3-pro-preview, 3.1-flash-lite-preview, robotics ER 2). Combinable with `googleSearch` (search → read pages), `codeExecution`, function calling (Gemini 3, Preview), structured outputs (Gemini 3). Not with `fileSearch`. The guide's "Limitations" still states "Tool use with function calling is currently unsupported" — superseded for Gemini 3 by tool combination; UNVERIFIED for 2.5. ## 6. Examples ```bash curl -s "https://generativelanguage.googleapis.com/v1beta/models/gemini-3.5-flash-lite:generateContent" \ -H "x-goog-api-key: $GEMINI_API_KEY" -H "Content-Type: application/json" \ -d '{"contents":[{"parts":[{"text":"Summarize https://ai.google.dev/gemini-api/docs/url-context in one sentence."}]}],"tools":[{"urlContext":{}}]}' ``` ```python r = client.models.generate_content(model="gemini-3.5-flash-lite", contents="Summarize https://ai.google.dev/gemini-api/docs/url-context", config=types.GenerateContentConfig(tools=[types.Tool(url_context=types.UrlContext())])) print(r.candidates[0].url_context_metadata) ``` ```ts const r = await ai.models.generateContent({ model: 'gemini-3.5-flash-lite', contents: 'Summarize https://ai.google.dev/gemini-api/docs/url-context', config: { tools: [{ urlContext: {} }] } }); console.log(r.candidates?.[0]?.urlContextMetadata); ``` ## Live verification (2026-09-18) **LIVE_VERIFIED** on `gemini-3.5-flash-lite` (`tmp-live/gemini-tools/c_url_context.json`): `tools:[{"urlContext":{}}]` + `"Summarize https://example.com in 5 words."` → HTTP 200; `candidates[0].urlContextMetadata = {urlMetadata:[{retrievedUrl:"https://example.com", urlRetrievalStatus:"URL_RETRIEVAL_STATUS_ERROR"}]}` (example.com could not be fetched, the model still answered from memory); `usageMetadata` gained `toolUsePromptTokenCount: 130` + `toolUsePromptTokensDetails` — the retrieved content is billed as input tokens even when retrieval fails. Example `examples/gemini/tools/url-context/url_context.py`, test `tests/gemini/test_tools.py::test_url_context_metadata`.