diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 3e7b112..5354007 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ jobs: lint: timeout-minutes: 10 name: lint - runs-on: ${{ github.repository == 'stainless-sdks/context.dev-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -37,7 +37,7 @@ jobs: build: timeout-minutes: 5 name: build - runs-on: ${{ github.repository == 'stainless-sdks/context.dev-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: (github.event_name == 'push' || github.event.pull_request.head.repo.fork) && (github.event_name != 'push' || github.event.head_commit.message != 'codegen metadata') permissions: contents: read @@ -88,7 +88,7 @@ jobs: test: timeout-minutes: 10 name: test - runs-on: ${{ github.repository == 'stainless-sdks/context.dev-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} + runs-on: ${{ startsWith(github.repository, 'stainless-sdks/') && 'depot-ubuntu-24.04' || 'ubuntu-latest' }} if: github.event_name == 'push' || github.event.pull_request.head.repo.fork steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 78baf5b..69e82f1 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.5.0" + ".": "2.6.0" } diff --git a/.stats.yml b/.stats.yml index 7cfdbba..0ac1eb3 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 30 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-fb56935a194e69348fecd985f7cf8b249795b46af2fb32f6c5c8ef648cf10c15.yml -openapi_spec_hash: 7260a560474283b7ad6ac5d426058ac9 -config_hash: daabb160675d86b354711da1e77e5129 +configured_endpoints: 32 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-242450ea46eb8c3e843fd6c4bf87e73192b5f62f6da697cd091d13c6aa7a991b.yml +openapi_spec_hash: c1c561976de1abcacede71fd5ab9b3d9 +config_hash: 70e7e80b5e87f94981bee396c6cd41e8 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5763f2c..54d170a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,21 @@ # Changelog +## 2.6.0 (2026-07-22) + +Full Changelog: [v2.5.0...v2.6.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v2.5.0...v2.6.0) + +### Features + +* **api:** api update ([8c1f563](https://github.com/context-dot-dev/context-typescript-sdk/commit/8c1f563edf6dcc1d73f9227991031bda015c658f)) +* **api:** api update ([8b7d1bd](https://github.com/context-dot-dev/context-typescript-sdk/commit/8b7d1bdb94fb10c9912d783040ac577b015b8f8e)) +* **api:** api update ([270e0f4](https://github.com/context-dot-dev/context-typescript-sdk/commit/270e0f48fc2b8d3e313b744562220c2ed8b2b82f)) +* **api:** api update ([4ad7020](https://github.com/context-dot-dev/context-typescript-sdk/commit/4ad70200cc9afd8ae4cf97b2bec2e40149636d16)) +* **api:** api update ([23b9a00](https://github.com/context-dot-dev/context-typescript-sdk/commit/23b9a006879c27aa6f11c18b7967acf67e95c3d5)) +* **api:** api update ([fa3004d](https://github.com/context-dot-dev/context-typescript-sdk/commit/fa3004d20081d2eb9cc4f3d2906990972b62d9f2)) +* **api:** api update ([424b19c](https://github.com/context-dot-dev/context-typescript-sdk/commit/424b19c072dcbeea4bc2f1e24a1470bb6df15b5b)) +* **api:** manual updates ([cb78520](https://github.com/context-dot-dev/context-typescript-sdk/commit/cb785201d3f7ad522b69dfaa048baaa9ba5483b6)) +* **stlc:** configurable CI runner and private-production-repo support in workflow templates ([762d40d](https://github.com/context-dot-dev/context-typescript-sdk/commit/762d40d91a3cfd7ed0b7810470c8add41081dca2)) + ## 2.5.0 (2026-07-12) Full Changelog: [v2.4.0...v2.5.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v2.4.0...v2.5.0) diff --git a/api.md b/api.md index 3690f8c..fdc70b0 100644 --- a/api.md +++ b/api.md @@ -94,6 +94,8 @@ Types: - MonitorUpdateResponse - MonitorListResponse - MonitorDeleteResponse +- MonitorGetCreditUsageResponse +- MonitorGetLimitsResponse - MonitorListAccountChangesResponse - MonitorListAccountRunsResponse - MonitorListChangesResponse @@ -108,6 +110,8 @@ Methods: - client.monitors.update(monitorID, { ...params }) -> MonitorUpdateResponse - client.monitors.list({ ...params }) -> MonitorListResponse - client.monitors.delete(monitorID) -> MonitorDeleteResponse +- client.monitors.getCreditUsage({ ...params }) -> MonitorGetCreditUsageResponse +- client.monitors.getLimits() -> MonitorGetLimitsResponse - client.monitors.listAccountChanges({ ...params }) -> MonitorListAccountChangesResponse - client.monitors.listAccountRuns({ ...params }) -> MonitorListAccountRunsResponse - client.monitors.listChanges(monitorID, { ...params }) -> MonitorListChangesResponse diff --git a/package.json b/package.json index 0c02ef7..008caa7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "context.dev", - "version": "2.5.0", + "version": "2.6.0", "description": "The official TypeScript library for the Context Dev API", "author": "Context Dev ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/manifest.json b/packages/mcp-server/manifest.json index b231a54..a024e4d 100644 --- a/packages/mcp-server/manifest.json +++ b/packages/mcp-server/manifest.json @@ -1,7 +1,7 @@ { "dxt_version": "0.2", "name": "context.dev-mcp", - "version": "2.5.0", + "version": "2.6.0", "description": "The official MCP Server for the Context Dev API", "author": { "name": "Context Dev", diff --git a/packages/mcp-server/package.json b/packages/mcp-server/package.json index 1623f8b..d964768 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "context.dev-mcp", - "version": "2.5.0", + "version": "2.6.0", "description": "The official MCP Server for the Context Dev API", "author": "Context Dev ", "types": "dist/index.d.ts", diff --git a/packages/mcp-server/src/code-tool-worker.ts b/packages/mcp-server/src/code-tool-worker.ts index 4dc928f..2abec5e 100644 --- a/packages/mcp-server/src/code-tool-worker.ts +++ b/packages/mcp-server/src/code-tool-worker.ts @@ -129,6 +129,8 @@ const fuse = new Fuse( 'client.utility.prefetch', 'client.monitors.create', 'client.monitors.delete', + 'client.monitors.getCreditUsage', + 'client.monitors.getLimits', 'client.monitors.list', 'client.monitors.listAccountChanges', 'client.monitors.listAccountRuns', diff --git a/packages/mcp-server/src/local-docs-search.ts b/packages/mcp-server/src/local-docs-search.ts index 4137d54..a392002 100644 --- a/packages/mcp-server/src/local-docs-search.ts +++ b/packages/mcp-server/src/local-docs-search.ts @@ -56,23 +56,26 @@ const EMBEDDED_METHODS: MethodEntry[] = [ httpMethod: 'post', summary: 'Parse Bytes', description: - 'Converts raw text, source code, web/data, PDF, Microsoft Office, and image bytes into LLM-usable Markdown. The base request costs 1 credit. When OCR runs (requires ocr=true), the entire call costs 5 credits; ocr=true requests where no OCR ends up running still cost 1 credit.', + 'Converts raw text, source code, web/data, PDF, Microsoft Office, and image bytes into LLM-usable Markdown.', stainlessPath: '(resource) parse > (method) handle', qualified: 'client.parse.handle', params: [ 'body: string;', + 'client?: string;', 'extension?: string;', - 'includeImages?: boolean;', - 'includeLinks?: boolean;', - 'ocr?: boolean;', + "includeImages?: boolean | 'true' | 'false';", + "includeLinks?: boolean | 'true' | 'false';", + "ocr?: boolean | 'true' | 'false';", 'pdf?: { end?: number; start?: number; };', - 'shortenBase64Images?: boolean;', - 'useMainContentOnly?: boolean;', + "shortenBase64Images?: boolean | 'true' | 'false';", + 'tags?: string[];', + "useMainContentOnly?: boolean | 'true' | 'false';", + "zdr?: 'enabled' | 'disabled';", ], response: '{ markdown: string; success: true; type: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - "## handle\n\n`client.parse.handle(body: string, extension?: string, includeImages?: boolean, includeLinks?: boolean, ocr?: boolean, pdf?: { end?: number; start?: number; }, shortenBase64Images?: boolean, useMainContentOnly?: boolean): { markdown: string; success: true; type: string; key_metadata?: object; }`\n\n**post** `/parse`\n\nConverts raw text, source code, web/data, PDF, Microsoft Office, and image bytes into LLM-usable Markdown. The base request costs 1 credit. When OCR runs (requires ocr=true), the entire call costs 5 credits; ocr=true requests where no OCR ends up running still cost 1 credit.\n\n### Parameters\n\n- `body: string`\n\n- `extension?: string`\n Optional file extension hint. Case-insensitive; a leading dot is accepted (e.g. \".pdf\").\n\n- `includeImages?: boolean`\n Include image references in Markdown output\n\n- `includeLinks?: boolean`\n Preserve hyperlinks in Markdown output\n\n- `ocr?: boolean`\n Gates all OCR. When true, PDFs get embedded-image OCR (recognized text inserted at each image's position in page reading order, preserving the text layer; pdf.start/pdf.end limit the page range), scanned PDFs with no text layer get full-document OCR, and raster images get their visible text transcribed. When false, no OCR runs: scanned PDFs may yield no content and images return only format/dimension metadata. Calls where OCR actually runs cost 5 credits instead of 1.\n\n- `pdf?: { end?: number; start?: number; }`\n PDF page-range controls. Use start/end to limit parsing (and OCR when ocr=true) to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `shortenBase64Images?: boolean`\n Shorten base64-encoded image data in the Markdown output\n\n- `useMainContentOnly?: boolean`\n Extract only the main content from HTML-like inputs\n\n### Returns\n\n- `{ markdown: string; success: true; type: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `markdown: string`\n - `success: true`\n - `type: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.parse.handle(fs.createReadStream('path/to/file'));\n\nconsole.log(response);\n```", + "## handle\n\n`client.parse.handle(body: string, client?: string, extension?: string, includeImages?: boolean | 'true' | 'false', includeLinks?: boolean | 'true' | 'false', ocr?: boolean | 'true' | 'false', pdf?: { end?: number; start?: number; }, shortenBase64Images?: boolean | 'true' | 'false', tags?: string[], useMainContentOnly?: boolean | 'true' | 'false', zdr?: 'enabled' | 'disabled'): { markdown: string; success: true; type: string; key_metadata?: object; }`\n\n**post** `/parse`\n\nConverts raw text, source code, web/data, PDF, Microsoft Office, and image bytes into LLM-usable Markdown.\n\n### Parameters\n\n- `body: string`\n\n- `client?: string`\n Optional client identifier used for usage attribution.\n\n- `extension?: string`\n Optional file extension hint, such as pdf, docx, xlsx, pptx, html, json, csv, md, py, rtf, jpg, png, or txt.\n\n- `includeImages?: boolean | 'true' | 'false'`\n Include image references in Markdown output\n\n- `includeLinks?: boolean | 'true' | 'false'`\n Preserve hyperlinks in Markdown output\n\n- `ocr?: boolean | 'true' | 'false'`\n When true for PDF inputs, detect and OCR images embedded in the selected pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. pdf.start/pdf.end limit the inclusive page range. When false, all OCR is disabled, including the automatic scanned-PDF fallback.\n\n- `pdf?: { end?: number; start?: number; }`\n PDF page-range options as a JSON object, e.g. {\"start\": 2, \"end\": 5}.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `shortenBase64Images?: boolean | 'true' | 'false'`\n Shorten base64-encoded image data in the Markdown output\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `useMainContentOnly?: boolean | 'true' | 'false'`\n Extract only the main content from HTML-like inputs\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ markdown: string; success: true; type: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `markdown: string`\n - `success: true`\n - `type: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.parse.handle(fs.createReadStream('path/to/file'));\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.parse.handle', @@ -114,27 +117,31 @@ const EMBEDDED_METHODS: MethodEntry[] = [ endpoint: '/web/scrape/html', httpMethod: 'get', summary: 'Scrape HTML', - description: 'Scrapes the given URL and returns the raw HTML content of the page.', + description: + 'Scrapes the given URL and returns the raw HTML content of the page. The base request costs 1 credit; requests with browser actions cost 2 credits.', stainlessPath: '(resource) web > (method) web_scrape_html', qualified: 'client.web.webScrapeHTML', params: [ 'url: string;', + "actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[];", 'country?: string;', 'excludeSelectors?: string[];', 'headers?: object;', - 'includeFrames?: boolean;', + "includeFrames?: boolean | 'true' | 'false';", 'includeSelectors?: string[];', 'maxAgeMs?: number;', - 'pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; };', - 'settleAnimations?: boolean;', + "pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; };", + "settleAnimations?: boolean | 'true' | 'false';", + 'tags?: string[];', 'timeoutMS?: number;', - 'useMainContentOnly?: boolean;', + "useMainContentOnly?: boolean | 'true' | 'false';", 'waitForMs?: number;', + "zdr?: 'enabled' | 'disabled';", ], response: '{ html: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; type: string; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - '## web_scrape_html\n\n`client.web.webScrapeHTML(url: string, country?: string, excludeSelectors?: string[], headers?: object, includeFrames?: boolean, includeSelectors?: string[], maxAgeMs?: number, pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }, settleAnimations?: boolean, timeoutMS?: number, useMainContentOnly?: boolean, waitForMs?: number): { html: string; metadata: object; success: true; type: string; url: string; key_metadata?: object; }`\n\n**get** `/web/scrape/html`\n\nScrapes the given URL and returns the raw HTML content of the page.\n\n### Parameters\n\n- `url: string`\n Full URL to scrape (must include http:// or https:// protocol)\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code for the website request location. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove from the result. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: "nav", "footer", ".ad-banner", "[aria-hidden=true]".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean`\n When true, iframes are rendered inline into the returned HTML.\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching subtrees (and their descendants) are kept and everything else is dropped. When omitted, the entire document is kept. Examples: "article.main", "#content", "[role=main]".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image\'s position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean`\n When true, waits briefly for CSS and transition animations to settle before extracting HTML. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean`\n When true, return only the page\'s main content in the HTML response, excluding headers, footers, sidebars, and navigation when detectable.\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load. Min: 0. Max: 30000 (30 seconds). \n\n### Returns\n\n- `{ html: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; type: string; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `html: string`\n - `metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }`\n - `success: true`\n - `type: string`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from \'context.dev\';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeHTML({ url: \'https://example.com\' });\n\nconsole.log(response);\n```', + "## web_scrape_html\n\n`client.web.webScrapeHTML(url: string, actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[], country?: string, excludeSelectors?: string[], headers?: object, includeFrames?: boolean | 'true' | 'false', includeSelectors?: string[], maxAgeMs?: number, pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }, settleAnimations?: boolean | 'true' | 'false', tags?: string[], timeoutMS?: number, useMainContentOnly?: boolean | 'true' | 'false', waitForMs?: number, zdr?: 'enabled' | 'disabled'): { html: string; metadata: object; success: true; type: string; url: string; key_metadata?: object; }`\n\n**get** `/web/scrape/html`\n\nScrapes the given URL and returns the raw HTML content of the page. The base request costs 1 credit; requests with browser actions cost 2 credits.\n\n### Parameters\n\n- `url: string`\n Full URL to scrape (must include http:// or https:// protocol)\n\n- `actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[]`\n Optional browser actions executed in array order after the page loads and before content is captured. Requires a paid plan. Send a JSON array in the query parameter. Maximum: 5 actions.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove from the result. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: \"nav\", \"footer\", \".ad-banner\", \"[aria-hidden=true]\".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean | 'true' | 'false'`\n When true, iframes are rendered inline into the returned HTML.\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching subtrees (and their descendants) are kept and everything else is dropped. When omitted, the entire document is kept. Examples: \"article.main\", \"#content\", \"[role=main]\".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean | 'true' | 'false'`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean | 'true' | 'false'`\n When true, waits briefly for CSS and transition animations to settle before extracting HTML. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean | 'true' | 'false'`\n When true, return only the page's main content in the HTML response, excluding headers, footers, sidebars, and navigation when detectable.\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load. Min: 0. Max: 30000 (30 seconds).\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ html: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; type: string; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `html: string`\n - `metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }`\n - `success: true`\n - `type: string`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeHTML({ url: 'https://example.com' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.webScrapeHTML', @@ -164,7 +171,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->webScrapeHTML', example: - "web->webScrapeHTML(\n url: 'https://example.com',\n country: 'de',\n excludeSelectors: ['string'],\n headers: ['foo' => 'J!'],\n includeFrames: true,\n includeSelectors: ['string'],\n maxAgeMs: 0,\n pdf: ['end' => 1, 'ocr' => true, 'shouldParse' => true, 'start' => 1],\n settleAnimations: true,\n timeoutMs: 1000,\n useMainContentOnly: true,\n waitForMs: 0,\n);\n\nvar_dump($response);", + "web->webScrapeHTML(\n url: 'https://example.com',\n actions: [['do' => 'wait', 'timeMs' => 0]],\n country: 'de',\n excludeSelectors: ['x'],\n headers: ['foo' => 'J!'],\n includeFrames: 'true',\n includeSelectors: ['x'],\n maxAgeMs: 0,\n pdf: ['end' => 1, 'ocr' => 'true', 'shouldParse' => 'true', 'start' => 1],\n settleAnimations: 'true',\n tags: ['production', 'team-alpha'],\n timeoutMs: 1,\n useMainContentOnly: 'true',\n waitForMs: 0,\n zdr: 'enabled',\n);\n\nvar_dump($response);", }, http: { example: @@ -178,30 +185,33 @@ const EMBEDDED_METHODS: MethodEntry[] = [ httpMethod: 'get', summary: 'Scrape Markdown', description: - 'Scrapes the given URL into LLM usable Markdown. Inspect key_metadata on JSON responses from a recognized API key; use error_code to distinguish stable failure categories.\n\n### Billing & errors\n\n| HTTP status | Billed? | Meaning |\n| --- | --- | --- |\n| 200 | Yes — 1 credit | Successful scrape, including a zero-length result when includeSelectors matched nothing |\n| 400 | No | Invalid input, skipped PDF, or the page could not be scraped |\n| 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code |\n| 404 | No | Target page returned or fingerprinted as not found |\n| 408 | No | Request timed out |\n| 415 | No | Unsupported content type |\n| 429 | No | Per-minute rate limit exceeded; honor Retry-After |\n| 500 | No | Internal error |', + 'Scrapes the given URL into LLM usable Markdown. Inspect key_metadata on JSON responses from a recognized API key; use error_code to distinguish stable failure categories.\n\n### Billing & errors\n\n| HTTP status | Billed? | Meaning |\n| --- | --- | --- |\n| 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing |\n| 400 | No | Invalid input, skipped PDF, or the page could not be scraped |\n| 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code |\n| 404 | No | Target page returned or fingerprinted as not found |\n| 408 | No | Request timed out |\n| 415 | No | Unsupported content type |\n| 429 | No | Per-minute rate limit exceeded; honor Retry-After |\n| 500 | No | Internal error |', stainlessPath: '(resource) web > (method) web_scrape_md', qualified: 'client.web.webScrapeMd', params: [ 'url: string;', + "actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[];", 'country?: string;', 'excludeSelectors?: string[];', 'headers?: object;', - 'includeFrames?: boolean;', - 'includeImages?: boolean;', - 'includeLinks?: boolean;', + "includeFrames?: boolean | 'true' | 'false';", + "includeImages?: boolean | 'true' | 'false';", + "includeLinks?: boolean | 'true' | 'false';", 'includeSelectors?: string[];', 'maxAgeMs?: number;', - 'pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; };', - 'settleAnimations?: boolean;', - 'shortenBase64Images?: boolean;', + "pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; };", + "settleAnimations?: boolean | 'true' | 'false';", + "shortenBase64Images?: boolean | 'true' | 'false';", + 'tags?: string[];', 'timeoutMS?: number;', - 'useMainContentOnly?: boolean;', + "useMainContentOnly?: boolean | 'true' | 'false';", 'waitForMs?: number;', + "zdr?: 'enabled' | 'disabled';", ], response: '{ contentLength: number; markdown: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - '## web_scrape_md\n\n`client.web.webScrapeMd(url: string, country?: string, excludeSelectors?: string[], headers?: object, includeFrames?: boolean, includeImages?: boolean, includeLinks?: boolean, includeSelectors?: string[], maxAgeMs?: number, pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }, settleAnimations?: boolean, shortenBase64Images?: boolean, timeoutMS?: number, useMainContentOnly?: boolean, waitForMs?: number): { contentLength: number; markdown: string; metadata: object; success: true; url: string; key_metadata?: object; }`\n\n**get** `/web/scrape/markdown`\n\nScrapes the given URL into LLM usable Markdown. Inspect key_metadata on JSON responses from a recognized API key; use error_code to distinguish stable failure categories.\n\n### Billing & errors\n\n| HTTP status | Billed? | Meaning |\n| --- | --- | --- |\n| 200 | Yes — 1 credit | Successful scrape, including a zero-length result when includeSelectors matched nothing |\n| 400 | No | Invalid input, skipped PDF, or the page could not be scraped |\n| 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code |\n| 404 | No | Target page returned or fingerprinted as not found |\n| 408 | No | Request timed out |\n| 415 | No | Unsupported content type |\n| 429 | No | Per-minute rate limit exceeded; honor Retry-After |\n| 500 | No | Internal error |\n\n### Parameters\n\n- `url: string`\n Full URL to scrape into LLM usable Markdown (must include http:// or https:// protocol)\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code for the website request location. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove before conversion to Markdown. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: "nav", "footer", ".ad-banner", "[aria-hidden=true]".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean`\n When true, the contents of iframes are rendered to Markdown.\n\n- `includeImages?: boolean`\n Include image references in Markdown output\n\n- `includeLinks?: boolean`\n Preserve hyperlinks in Markdown output\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before conversion to Markdown. When omitted, the entire document is kept. Examples: "article.main", "#content", "[role=main]".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image\'s position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean`\n When true, waits briefly for CSS and transition animations to settle before converting to Markdown. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `shortenBase64Images?: boolean`\n Shorten base64-encoded image data in the Markdown output\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean`\n Extract only the main content of the page, excluding headers, footers, sidebars, and navigation\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before converting the page to Markdown. Min: 0. Max: 30000 (30 seconds). \n\n### Returns\n\n- `{ contentLength: number; markdown: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `contentLength: number`\n - `markdown: string`\n - `metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }`\n - `success: true`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from \'context.dev\';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeMd({ url: \'https://example.com\' });\n\nconsole.log(response);\n```', + "## web_scrape_md\n\n`client.web.webScrapeMd(url: string, actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[], country?: string, excludeSelectors?: string[], headers?: object, includeFrames?: boolean | 'true' | 'false', includeImages?: boolean | 'true' | 'false', includeLinks?: boolean | 'true' | 'false', includeSelectors?: string[], maxAgeMs?: number, pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }, settleAnimations?: boolean | 'true' | 'false', shortenBase64Images?: boolean | 'true' | 'false', tags?: string[], timeoutMS?: number, useMainContentOnly?: boolean | 'true' | 'false', waitForMs?: number, zdr?: 'enabled' | 'disabled'): { contentLength: number; markdown: string; metadata: object; success: true; url: string; key_metadata?: object; }`\n\n**get** `/web/scrape/markdown`\n\nScrapes the given URL into LLM usable Markdown. Inspect key_metadata on JSON responses from a recognized API key; use error_code to distinguish stable failure categories.\n\n### Billing & errors\n\n| HTTP status | Billed? | Meaning |\n| --- | --- | --- |\n| 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing |\n| 400 | No | Invalid input, skipped PDF, or the page could not be scraped |\n| 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code |\n| 404 | No | Target page returned or fingerprinted as not found |\n| 408 | No | Request timed out |\n| 415 | No | Unsupported content type |\n| 429 | No | Per-minute rate limit exceeded; honor Retry-After |\n| 500 | No | Internal error |\n\n### Parameters\n\n- `url: string`\n Full URL to scrape into LLM usable Markdown (must include http:// or https:// protocol)\n\n- `actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[]`\n Optional browser actions executed in array order after the page loads and before content is captured. Requires a paid plan. Send a JSON array in the query parameter. Maximum: 5 actions.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove before conversion to Markdown. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: \"nav\", \"footer\", \".ad-banner\", \"[aria-hidden=true]\".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean | 'true' | 'false'`\n When true, the contents of iframes are rendered to Markdown.\n\n- `includeImages?: boolean | 'true' | 'false'`\n Include image references in Markdown output\n\n- `includeLinks?: boolean | 'true' | 'false'`\n Preserve hyperlinks in Markdown output\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before conversion to Markdown. When omitted, the entire document is kept. Examples: \"article.main\", \"#content\", \"[role=main]\".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean | 'true' | 'false'`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean | 'true' | 'false'`\n When true, waits briefly for CSS and transition animations to settle before converting to Markdown. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `shortenBase64Images?: boolean | 'true' | 'false'`\n Shorten base64-encoded image data in the Markdown output\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean | 'true' | 'false'`\n Extract only the main content of the page, excluding headers, footers, sidebars, and navigation\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before converting the page to Markdown. Min: 0. Max: 30000 (30 seconds).\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ contentLength: number; markdown: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `contentLength: number`\n - `markdown: string`\n - `metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }`\n - `success: true`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeMd({ url: 'https://example.com' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.webScrapeMd', @@ -230,7 +240,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->webScrapeMd', example: - "web->webScrapeMd(\n url: 'https://example.com',\n country: 'de',\n excludeSelectors: ['string'],\n headers: ['foo' => 'J!'],\n includeFrames: true,\n includeImages: true,\n includeLinks: true,\n includeSelectors: ['string'],\n maxAgeMs: 0,\n pdf: ['end' => 1, 'ocr' => true, 'shouldParse' => true, 'start' => 1],\n settleAnimations: true,\n shortenBase64Images: true,\n timeoutMs: 1000,\n useMainContentOnly: true,\n waitForMs: 0,\n);\n\nvar_dump($response);", + "web->webScrapeMd(\n url: 'https://example.com',\n actions: [['do' => 'wait', 'timeMs' => 0]],\n country: 'de',\n excludeSelectors: ['x'],\n headers: ['foo' => 'J!'],\n includeFrames: 'true',\n includeImages: 'true',\n includeLinks: 'true',\n includeSelectors: ['x'],\n maxAgeMs: 0,\n pdf: ['end' => 1, 'ocr' => 'true', 'shouldParse' => 'true', 'start' => 1],\n settleAnimations: 'true',\n shortenBase64Images: 'true',\n tags: ['production', 'team-alpha'],\n timeoutMs: 1,\n useMainContentOnly: 'true',\n waitForMs: 0,\n zdr: 'enabled',\n);\n\nvar_dump($response);", }, http: { example: @@ -244,22 +254,24 @@ const EMBEDDED_METHODS: MethodEntry[] = [ httpMethod: 'get', summary: 'Scrape Images', description: - 'Extract image assets from a web page, including standard URLs, inline SVGs, data URIs, responsive image sources, metadata, CSS backgrounds, video posters, and embeds. The base request costs 1 credit. When enrichment is enabled, the entire call costs 5 credits.', + 'Extract image assets from a web page, including standard URLs, inline SVGs, data URIs, responsive image sources, metadata, CSS backgrounds, video posters, and embeds. The base request costs 1 credit, or 2 credits with browser actions. When enrichment is enabled, the entire call costs 5 credits, including requests that also use actions.', stainlessPath: '(resource) web > (method) web_scrape_images', qualified: 'client.web.webScrapeImages', params: [ 'url: string;', - 'dedupe?: boolean;', - 'enrichment?: { classification?: boolean; hostedUrl?: boolean; maxTimePerMs?: number; resolution?: boolean; };', + "actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[];", + "dedupe?: boolean | 'true' | 'false';", + "enrichment?: { classification?: boolean | 'true' | 'false'; hostedUrl?: boolean | 'true' | 'false'; maxTimePerMs?: number; resolution?: boolean | 'true' | 'false'; };", 'headers?: object;', 'maxAgeMs?: number;', + 'tags?: string[];', 'timeoutMS?: number;', 'waitForMs?: number;', ], response: "{ images: { alt: string; element: 'img' | 'svg' | 'link' | 'source' | 'video' | 'css' | 'object' | 'meta' | 'background'; src: string; type: 'url' | 'html' | 'base64'; enrichment?: { height?: number; mimetype?: string; type?: 'photography' | 'illustration' | 'logo' | 'wordmark' | 'icon' | 'pattern' | 'graphic' | 'other'; url?: string; width?: number; }; }[]; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", markdown: - "## web_scrape_images\n\n`client.web.webScrapeImages(url: string, dedupe?: boolean, enrichment?: { classification?: boolean; hostedUrl?: boolean; maxTimePerMs?: number; resolution?: boolean; }, headers?: object, maxAgeMs?: number, timeoutMS?: number, waitForMs?: number): { images: object[]; success: true; url: string; key_metadata?: object; }`\n\n**get** `/web/scrape/images`\n\nExtract image assets from a web page, including standard URLs, inline SVGs, data URIs, responsive image sources, metadata, CSS backgrounds, video posters, and embeds. The base request costs 1 credit. When enrichment is enabled, the entire call costs 5 credits.\n\n### Parameters\n\n- `url: string`\n Page URL to inspect. Must include http:// or https://.\n\n- `dedupe?: boolean`\n When true, visually duplicate images are removed: every image is loaded and perceptually hashed, and only the highest-resolution copy of each duplicate group is kept. Images that cannot be downloaded or hashed are kept. Default: false.\n\n- `enrichment?: { classification?: boolean; hostedUrl?: boolean; maxTimePerMs?: number; resolution?: boolean; }`\n Optional per-image processing, sent as deep-object query params such as enrichment[resolution]=true.\n - `classification?: boolean`\n Classify each image by visual asset type.\n - `hostedUrl?: boolean`\n Host materializable images on the Brand.dev CDN and return their URL and MIME type.\n - `maxTimePerMs?: number`\n Per-image enrichment timeout in milliseconds. Default: 30000. Maximum: 60000.\n - `resolution?: boolean`\n Measure image width and height when possible.\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `maxAgeMs?: number`\n Reuse a cached result this many milliseconds old or newer. Default: 86400000 (1 day). Set to 0 to bypass cache. Maximum: 2592000000 (30 days).\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before collecting images. Min: 0. Max: 30000 (30 seconds). \n\n### Returns\n\n- `{ images: { alt: string; element: 'img' | 'svg' | 'link' | 'source' | 'video' | 'css' | 'object' | 'meta' | 'background'; src: string; type: 'url' | 'html' | 'base64'; enrichment?: { height?: number; mimetype?: string; type?: 'photography' | 'illustration' | 'logo' | 'wordmark' | 'icon' | 'pattern' | 'graphic' | 'other'; url?: string; width?: number; }; }[]; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `images: { alt: string; element: 'img' | 'svg' | 'link' | 'source' | 'video' | 'css' | 'object' | 'meta' | 'background'; src: string; type: 'url' | 'html' | 'base64'; enrichment?: { height?: number; mimetype?: string; type?: 'photography' | 'illustration' | 'logo' | 'wordmark' | 'icon' | 'pattern' | 'graphic' | 'other'; url?: string; width?: number; }; }[]`\n - `success: true`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeImages({ url: 'https://example.com' });\n\nconsole.log(response);\n```", + "## web_scrape_images\n\n`client.web.webScrapeImages(url: string, actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[], dedupe?: boolean | 'true' | 'false', enrichment?: { classification?: boolean | 'true' | 'false'; hostedUrl?: boolean | 'true' | 'false'; maxTimePerMs?: number; resolution?: boolean | 'true' | 'false'; }, headers?: object, maxAgeMs?: number, tags?: string[], timeoutMS?: number, waitForMs?: number): { images: object[]; success: true; url: string; key_metadata?: object; }`\n\n**get** `/web/scrape/images`\n\nExtract image assets from a web page, including standard URLs, inline SVGs, data URIs, responsive image sources, metadata, CSS backgrounds, video posters, and embeds. The base request costs 1 credit, or 2 credits with browser actions. When enrichment is enabled, the entire call costs 5 credits, including requests that also use actions.\n\n### Parameters\n\n- `url: string`\n Page URL to inspect. Must include http:// or https://.\n\n- `actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[]`\n Optional browser actions executed in array order after the page loads and before content is captured. Requires a paid plan. Send a JSON array in the query parameter. Maximum: 5 actions.\n\n- `dedupe?: boolean | 'true' | 'false'`\n When true, visually duplicate images are removed: every image is loaded and perceptually hashed, and only the highest-resolution copy of each duplicate group is kept. Images that cannot be downloaded or hashed are kept. Default: false.\n\n- `enrichment?: { classification?: boolean | 'true' | 'false'; hostedUrl?: boolean | 'true' | 'false'; maxTimePerMs?: number; resolution?: boolean | 'true' | 'false'; }`\n Optional per-image processing, sent as deep-object query params such as enrichment[resolution]=true.\n - `classification?: boolean | 'true' | 'false'`\n Classify each image by visual asset type.\n - `hostedUrl?: boolean | 'true' | 'false'`\n Host materializable images on the Brand.dev CDN and return their URL and MIME type.\n - `maxTimePerMs?: number`\n Per-image enrichment timeout in milliseconds. Default: 30000. Maximum: 60000.\n - `resolution?: boolean | 'true' | 'false'`\n Measure image width and height when possible.\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `maxAgeMs?: number`\n Reuse a cached result this many milliseconds old or newer. Default: 86400000 (1 day). Set to 0 to bypass cache. Maximum: 2592000000 (30 days).\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before collecting images. Min: 0. Max: 30000 (30 seconds).\n\n### Returns\n\n- `{ images: { alt: string; element: 'img' | 'svg' | 'link' | 'source' | 'video' | 'css' | 'object' | 'meta' | 'background'; src: string; type: 'url' | 'html' | 'base64'; enrichment?: { height?: number; mimetype?: string; type?: 'photography' | 'illustration' | 'logo' | 'wordmark' | 'icon' | 'pattern' | 'graphic' | 'other'; url?: string; width?: number; }; }[]; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `images: { alt: string; element: 'img' | 'svg' | 'link' | 'source' | 'video' | 'css' | 'object' | 'meta' | 'background'; src: string; type: 'url' | 'html' | 'base64'; enrichment?: { height?: number; mimetype?: string; type?: 'photography' | 'illustration' | 'logo' | 'wordmark' | 'icon' | 'pattern' | 'graphic' | 'other'; url?: string; width?: number; }; }[]`\n - `success: true`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeImages({ url: 'https://example.com' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.webScrapeImages', @@ -289,7 +301,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->webScrapeImages', example: - "web->webScrapeImages(\n url: 'https://example.com',\n dedupe: true,\n enrichment: [\n 'classification' => true,\n 'hostedURL' => true,\n 'maxTimePerMs' => 1,\n 'resolution' => true,\n ],\n headers: ['foo' => 'J!'],\n maxAgeMs: 0,\n timeoutMs: 1000,\n waitForMs: 0,\n);\n\nvar_dump($response);", + "web->webScrapeImages(\n url: 'https://example.com',\n actions: [['do' => 'wait', 'timeMs' => 0]],\n dedupe: 'true',\n enrichment: [\n 'classification' => 'true',\n 'hostedURL' => 'true',\n 'maxTimePerMs' => 1,\n 'resolution' => 'true',\n ],\n headers: ['foo' => 'J!'],\n maxAgeMs: 0,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1,\n waitForMs: 0,\n);\n\nvar_dump($response);", }, http: { example: @@ -309,42 +321,45 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'domain: string;', 'headers?: object;', 'maxLinks?: number;', + 'sitemapUrl?: string;', + 'tags?: string[];', 'timeoutMS?: number;', 'urlRegex?: string;', + "zdr?: 'enabled' | 'disabled';", ], response: '{ domain: string; meta: { errors: number; sitemapsDiscovered: number; sitemapsFetched: number; sitemapsSkipped: number; }; success: true; urls: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - "## web_scrape_sitemap\n\n`client.web.webScrapeSitemap(domain: string, headers?: object, maxLinks?: number, timeoutMS?: number, urlRegex?: string): { domain: string; meta: object; success: true; urls: string[]; key_metadata?: object; }`\n\n**get** `/web/scrape/sitemap`\n\nCrawl an entire website's sitemap and return all discovered page URLs.\n\n### Parameters\n\n- `domain: string`\n Domain to build a sitemap for\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `maxLinks?: number`\n Maximum number of links to return from the sitemap crawl. Defaults to 10,000. Minimum is 1, maximum is 100,000.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `urlRegex?: string`\n Optional RE2-compatible regex pattern. Only URLs matching this pattern are returned and counted against maxLinks.\n\n### Returns\n\n- `{ domain: string; meta: { errors: number; sitemapsDiscovered: number; sitemapsFetched: number; sitemapsSkipped: number; }; success: true; urls: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `domain: string`\n - `meta: { errors: number; sitemapsDiscovered: number; sitemapsFetched: number; sitemapsSkipped: number; }`\n - `success: true`\n - `urls: string[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeSitemap({ domain: 'domain' });\n\nconsole.log(response);\n```", + "## web_scrape_sitemap\n\n`client.web.webScrapeSitemap(domain: string, headers?: object, maxLinks?: number, sitemapUrl?: string, tags?: string[], timeoutMS?: number, urlRegex?: string, zdr?: 'enabled' | 'disabled'): { domain: string; meta: object; success: true; urls: string[]; key_metadata?: object; }`\n\n**get** `/web/scrape/sitemap`\n\nCrawl an entire website's sitemap and return all discovered page URLs.\n\n### Parameters\n\n- `domain: string`\n Domain to build a sitemap for\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `maxLinks?: number`\n Maximum number of links to return from the sitemap crawl. Defaults to 10,000. Minimum is 1, maximum is 100,000.\n\n- `sitemapUrl?: string`\n Optional explicit sitemap URL. When provided, exactly this sitemap is crawled instead of discovering the domain's sitemaps.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `urlRegex?: string`\n Optional RE2-compatible regex pattern. Only URLs matching this pattern are returned and counted against maxLinks.\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ domain: string; meta: { errors: number; sitemapsDiscovered: number; sitemapsFetched: number; sitemapsSkipped: number; }; success: true; urls: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `domain: string`\n - `meta: { errors: number; sitemapsDiscovered: number; sitemapsFetched: number; sitemapsSkipped: number; }`\n - `success: true`\n - `urls: string[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeSitemap({ domain: 'xxx' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.webScrapeSitemap', example: - "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.web.webScrapeSitemap({ domain: 'domain' });\n\nconsole.log(response.domain);", + "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.web.webScrapeSitemap({ domain: 'xxx' });\n\nconsole.log(response.domain);", }, python: { method: 'web.web_scrape_sitemap', example: - 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.web.web_scrape_sitemap(\n domain="domain",\n)\nprint(response.domain)', + 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.web.web_scrape_sitemap(\n domain="xxx",\n)\nprint(response.domain)', }, go: { method: 'client.Web.WebScrapeSitemap', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Web.WebScrapeSitemap(context.TODO(), contextdev.WebWebScrapeSitemapParams{\n\t\tDomain: "domain",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Domain)\n}\n', + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Web.WebScrapeSitemap(context.TODO(), contextdev.WebWebScrapeSitemapParams{\n\t\tDomain: "xxx",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Domain)\n}\n', }, ruby: { method: 'web.web_scrape_sitemap', example: - 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.web.web_scrape_sitemap(domain: "domain")\n\nputs(response)', + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.web.web_scrape_sitemap(domain: "xxx")\n\nputs(response)', }, cli: { method: 'web web_scrape_sitemap', - example: "context-dev web web-scrape-sitemap \\\n --api-key 'My API Key' \\\n --domain domain", + example: "context-dev web web-scrape-sitemap \\\n --api-key 'My API Key' \\\n --domain xxx", }, php: { method: 'web->webScrapeSitemap', example: - "web->webScrapeSitemap(\n domain: 'domain',\n headers: ['foo' => 'J!'],\n maxLinks: 1,\n timeoutMs: 1000,\n urlRegex: '^https?://[^/]+/blog/',\n);\n\nvar_dump($response);", + "web->webScrapeSitemap(\n domain: 'xxx',\n headers: ['foo' => 'J!'],\n maxLinks: 1,\n sitemapURL: 'https://example.com',\n tags: ['production', 'team-alpha'],\n timeoutMs: 1,\n urlRegex: '^https?://[^/]+/blog/',\n zdr: 'enabled',\n);\n\nvar_dump($response);", }, http: { example: @@ -366,18 +381,20 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'directUrl?: string;', 'domain?: string;', "fullScreenshot?: 'true' | 'false';", - "handleCookiePopup?: 'true' | 'false';", + "handleCookiePopup?: boolean | 'true' | 'false';", 'maxAgeMs?: number;', "page?: 'login' | 'signup' | 'blog' | 'careers' | 'pricing' | 'terms' | 'privacy' | 'contact';", 'scrollOffset?: number;', + 'tags?: string[];', 'timeoutMS?: number;', 'viewport?: { height?: number; width?: number; };', 'waitForMs?: number;', + "zdr?: 'enabled' | 'disabled';", ], response: "{ code?: number; domain?: string; height?: number; key_metadata?: { credits_consumed: number; credits_remaining: number; }; screenshot?: string; screenshotType?: 'viewport' | 'fullPage'; status?: string; width?: number; }", markdown: - "## screenshot\n\n`client.web.screenshot(colorScheme?: 'light' | 'dark', country?: string, directUrl?: string, domain?: string, fullScreenshot?: 'true' | 'false', handleCookiePopup?: 'true' | 'false', maxAgeMs?: number, page?: 'login' | 'signup' | 'blog' | 'careers' | 'pricing' | 'terms' | 'privacy' | 'contact', scrollOffset?: number, timeoutMS?: number, viewport?: { height?: number; width?: number; }, waitForMs?: number): { code?: number; domain?: string; height?: number; key_metadata?: object; screenshot?: string; screenshotType?: 'viewport' | 'fullPage'; status?: string; width?: number; }`\n\n**get** `/web/screenshot`\n\nCapture a screenshot of a website.\n\n### Parameters\n\n- `colorScheme?: 'light' | 'dark'`\n Optional parameter to choose the site's visual theme in the screenshot. Use 'light' or 'dark' when the site offers both appearances.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code for the website request location. When provided, Context.dev fetches the target page from that country.\n\n- `directUrl?: string`\n A specific URL to screenshot directly, bypassing domain resolution (e.g., 'https://example.com/pricing'). When provided, the screenshot is taken of this exact URL. You must provide either 'domain' or 'directUrl', but not both.\n\n- `domain?: string`\n Domain name to take screenshot of (e.g., 'example.com', 'google.com'). The domain will be automatically normalized and validated. You must provide either 'domain' or 'directUrl', but not both.\n\n- `fullScreenshot?: 'true' | 'false'`\n Optional parameter to determine screenshot type. If 'true', takes a full page screenshot capturing all content. If 'false' or not provided, takes a viewport screenshot (standard browser view).\n\n- `handleCookiePopup?: 'true' | 'false'`\n Optional parameter to control cookie/consent popup handling. If 'true', we dismiss cookie banner before capture. If 'false' or not provided, captures the page without that step.\n\n- `maxAgeMs?: number`\n Return a cached screenshot if a prior screenshot for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always capture fresh.\n\n- `page?: 'login' | 'signup' | 'blog' | 'careers' | 'pricing' | 'terms' | 'privacy' | 'contact'`\n Optional parameter to specify which page type to screenshot. If provided, the system will scrape the domain's links and use heuristics to find the most appropriate URL for the specified page type (30 supported languages). If not provided, screenshots the main domain landing page. Only applicable when using 'domain', not 'directUrl'.\n\n- `scrollOffset?: number`\n Optional vertical scroll offset in pixels for capturing a long page in viewport-sized chunks. When provided, the full page is captured once and the returned image is the viewport-sized slice that begins at this Y offset (e.g. request scrollOffset=0, then 1080, then 2160 to walk a 1920x1080 landing page top to bottom). The final slice may be shorter than the viewport height. Takes precedence over fullScreenshot. Max: 100000.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `viewport?: { height?: number; width?: number; }`\n Optional browser viewport dimensions for the screenshot. Defaults to 1920x1080.\n - `height?: number`\n Viewport height in pixels.\n - `width?: number`\n Viewport width in pixels.\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before taking the screenshot. Min: 0. Max: 30000 (30 seconds). Defaults to 3000 ms when omitted.\n\n### Returns\n\n- `{ code?: number; domain?: string; height?: number; key_metadata?: { credits_consumed: number; credits_remaining: number; }; screenshot?: string; screenshotType?: 'viewport' | 'fullPage'; status?: string; width?: number; }`\n\n - `code?: number`\n - `domain?: string`\n - `height?: number`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `screenshot?: string`\n - `screenshotType?: 'viewport' | 'fullPage'`\n - `status?: string`\n - `width?: number`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.screenshot();\n\nconsole.log(response);\n```", + "## screenshot\n\n`client.web.screenshot(colorScheme?: 'light' | 'dark', country?: string, directUrl?: string, domain?: string, fullScreenshot?: 'true' | 'false', handleCookiePopup?: boolean | 'true' | 'false', maxAgeMs?: number, page?: 'login' | 'signup' | 'blog' | 'careers' | 'pricing' | 'terms' | 'privacy' | 'contact', scrollOffset?: number, tags?: string[], timeoutMS?: number, viewport?: { height?: number; width?: number; }, waitForMs?: number, zdr?: 'enabled' | 'disabled'): { code?: number; domain?: string; height?: number; key_metadata?: object; screenshot?: string; screenshotType?: 'viewport' | 'fullPage'; status?: string; width?: number; }`\n\n**get** `/web/screenshot`\n\nCapture a screenshot of a website.\n\n### Parameters\n\n- `colorScheme?: 'light' | 'dark'`\n Optional parameter to choose the site's visual theme in the screenshot. Use 'light' or 'dark' when the site offers both appearances.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `directUrl?: string`\n A specific URL to screenshot directly, bypassing domain resolution (e.g., 'https://example.com/pricing'). When provided, the screenshot is taken of this exact URL. You must provide either 'domain' or 'directUrl', but not both.\n\n- `domain?: string`\n Domain name to take screenshot of (e.g., 'example.com', 'google.com'). The domain will be automatically normalized and validated. You must provide either 'domain' or 'directUrl', but not both.\n\n- `fullScreenshot?: 'true' | 'false'`\n Optional parameter to determine screenshot type. If 'true', takes a full page screenshot capturing all content. If 'false' or not provided, takes a viewport screenshot (standard browser view).\n\n- `handleCookiePopup?: boolean | 'true' | 'false'`\n Optional parameter to control cookie/consent popup handling. If 'true', we dismiss cookie banner before capture. If 'false' or not provided, captures the page without that step.\n\n- `maxAgeMs?: number`\n Return a cached screenshot if a prior screenshot for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always capture fresh.\n\n- `page?: 'login' | 'signup' | 'blog' | 'careers' | 'pricing' | 'terms' | 'privacy' | 'contact'`\n Optional parameter to specify which page type to screenshot. If provided, the system will scrape the domain's links and use heuristics to find the most appropriate URL for the specified page type (30 supported languages). If not provided, screenshots the main domain landing page. Only applicable when using 'domain', not 'directUrl'.\n\n- `scrollOffset?: number`\n Optional vertical scroll offset in pixels for capturing a long page in viewport-sized chunks. When provided, the full page is captured once and the returned image is the viewport-sized slice that begins at this Y offset (e.g. request scrollOffset=0, then 1080, then 2160 to walk a 1920x1080 landing page top to bottom). The final slice may be shorter than the viewport height. Takes precedence over fullScreenshot. Max: 100000.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `viewport?: { height?: number; width?: number; }`\n Optional browser viewport dimensions for the screenshot. Defaults to 1920x1080.\n - `height?: number`\n Viewport height in pixels.\n - `width?: number`\n Viewport width in pixels.\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before taking the screenshot. Min: 0. Max: 30000 (30 seconds). Defaults to 3000 ms when omitted.\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ code?: number; domain?: string; height?: number; key_metadata?: { credits_consumed: number; credits_remaining: number; }; screenshot?: string; screenshotType?: 'viewport' | 'fullPage'; status?: string; width?: number; }`\n\n - `code?: number`\n - `domain?: string`\n - `height?: number`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `screenshot?: string`\n - `screenshotType?: 'viewport' | 'fullPage'`\n - `status?: string`\n - `width?: number`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.screenshot();\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.screenshot', @@ -406,7 +423,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->screenshot', example: - "web->screenshot(\n colorScheme: 'light',\n country: 'de',\n directURL: 'https://example.com',\n domain: 'domain',\n fullScreenshot: 'true',\n handleCookiePopup: 'true',\n maxAgeMs: 0,\n page: 'login',\n scrollOffset: 0,\n timeoutMs: 1000,\n viewport: ['height' => 240, 'width' => 240],\n waitForMs: 0,\n);\n\nvar_dump($response);", + "web->screenshot(\n colorScheme: 'light',\n country: 'de',\n directURL: 'https://example.com',\n domain: 'xxx',\n fullScreenshot: 'true',\n handleCookiePopup: 'true',\n maxAgeMs: 0,\n page: 'login',\n scrollOffset: 0,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1,\n viewport: ['height' => 240, 'width' => 240],\n waitForMs: 0,\n zdr: 'enabled',\n);\n\nvar_dump($response);", }, http: { example: @@ -439,15 +456,17 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'settleAnimations?: boolean;', 'shortenBase64Images?: boolean;', 'stopAfterMs?: number;', + 'tags?: string[];', 'timeoutMS?: number;', 'urlRegex?: string;', 'useMainContentOnly?: boolean;', 'waitForMs?: number;', + "zdr?: 'enabled' | 'disabled';", ], response: '{ metadata: { maxCrawlDepth: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }; results: { markdown: string; metadata: { crawlDepth: number; finalUrl: string; sourceUrl: string; statusCode: number; success: boolean; title: string; url: string; additionalMeta?: object; alternates?: object[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; twitter?: object; }; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - '## web_crawl_md\n\n`client.web.webCrawlMd(url: string, country?: string, excludeSelectors?: string[], followSubdomains?: boolean, includeFrames?: boolean, includeImages?: boolean, includeLinks?: boolean, includeSelectors?: string[], maxAgeMs?: number, maxDepth?: number, maxPages?: number, pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }, settleAnimations?: boolean, shortenBase64Images?: boolean, stopAfterMs?: number, timeoutMS?: number, urlRegex?: string, useMainContentOnly?: boolean, waitForMs?: number): { metadata: object; results: object[]; key_metadata?: object; }`\n\n**post** `/web/crawl`\n\nPerforms a crawl starting from a given URL, extracts page content as Markdown, and returns results for all crawled pages.\n\n### Parameters\n\n- `url: string`\n The starting URL for the crawl (must include http:// or https:// protocol)\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev\'s supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove before each crawled page is converted to Markdown. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: "nav", "footer", ".ad-banner", "[aria-hidden=true]".\n\n- `followSubdomains?: boolean`\n When true, follow links on subdomains of the starting URL\'s domain (e.g. docs.example.com when starting from example.com). www and apex are always treated as equivalent.\n\n- `includeFrames?: boolean`\n When true, the contents of iframes are rendered to Markdown for each crawled page.\n\n- `includeImages?: boolean`\n Include image references in the Markdown output\n\n- `includeLinks?: boolean`\n Preserve hyperlinks in the Markdown output\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before each crawled page is converted to Markdown. When omitted, the entire document is kept. Examples: "article.main", "#content", "[role=main]".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `maxDepth?: number`\n Maximum link depth from the starting URL (0 = only the starting page)\n\n- `maxPages?: number`\n Maximum number of pages to crawl. Hard cap: 500.\n\n- `pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image\'s position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean`\n When true, PDF pages are fetched and parsed. When false, PDF pages are skipped entirely (not included in results and not counted as failures).\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean`\n When true, waits briefly for CSS and transition animations to settle before extracting each crawled page. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `shortenBase64Images?: boolean`\n Truncate base64-encoded image data in the Markdown output\n\n- `stopAfterMs?: number`\n Soft time budget for the crawl in milliseconds. After each scrape, the crawler checks the elapsed time and, if exceeded, returns the pages collected so far instead of continuing. Min: 10000 (10s). Max: 110000 (110s). Default: 80000 (80s).\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `urlRegex?: string`\n Regex pattern. Only URLs matching this pattern will be followed and scraped.\n\n- `useMainContentOnly?: boolean`\n Extract only the main content, stripping headers, footers, sidebars, and navigation\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load for each crawled page. Min: 0. Max: 30000 (30 seconds). \n\n### Returns\n\n- `{ metadata: { maxCrawlDepth: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }; results: { markdown: string; metadata: { crawlDepth: number; finalUrl: string; sourceUrl: string; statusCode: number; success: boolean; title: string; url: string; additionalMeta?: object; alternates?: object[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; twitter?: object; }; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `metadata: { maxCrawlDepth: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }`\n - `results: { markdown: string; metadata: { crawlDepth: number; finalUrl: string; sourceUrl: string; statusCode: number; success: boolean; title: string; url: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; twitter?: object; }; }[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from \'context.dev\';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webCrawlMd({ url: \'https://example.com\' });\n\nconsole.log(response);\n```', + "## web_crawl_md\n\n`client.web.webCrawlMd(url: string, country?: string, excludeSelectors?: string[], followSubdomains?: boolean, includeFrames?: boolean, includeImages?: boolean, includeLinks?: boolean, includeSelectors?: string[], maxAgeMs?: number, maxDepth?: number, maxPages?: number, pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }, settleAnimations?: boolean, shortenBase64Images?: boolean, stopAfterMs?: number, tags?: string[], timeoutMS?: number, urlRegex?: string, useMainContentOnly?: boolean, waitForMs?: number, zdr?: 'enabled' | 'disabled'): { metadata: object; results: object[]; key_metadata?: object; }`\n\n**post** `/web/crawl`\n\nPerforms a crawl starting from a given URL, extracts page content as Markdown, and returns results for all crawled pages.\n\n### Parameters\n\n- `url: string`\n The starting URL for the crawl (must include http:// or https:// protocol)\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove before each crawled page is converted to Markdown. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: \"nav\", \"footer\", \".ad-banner\", \"[aria-hidden=true]\".\n\n- `followSubdomains?: boolean`\n When true, follow links on subdomains of the starting URL's domain (e.g. docs.example.com when starting from example.com). www and apex are always treated as equivalent.\n\n- `includeFrames?: boolean`\n When true, the contents of iframes are rendered to Markdown for each crawled page.\n\n- `includeImages?: boolean`\n Include image references in the Markdown output\n\n- `includeLinks?: boolean`\n Preserve hyperlinks in the Markdown output\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before each crawled page is converted to Markdown. When omitted, the entire document is kept. Examples: \"article.main\", \"#content\", \"[role=main]\".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `maxDepth?: number`\n Maximum link depth from the starting URL (0 = only the starting page)\n\n- `maxPages?: number`\n Maximum number of pages to crawl. Hard cap: 500.\n\n- `pdf?: { end?: number; ocr?: boolean; shouldParse?: boolean; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean`\n When true, PDF pages are fetched and parsed. When false, PDF pages are skipped entirely (not included in results and not counted as failures).\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean`\n When true, waits briefly for CSS and transition animations to settle before extracting each crawled page. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `shortenBase64Images?: boolean`\n Truncate base64-encoded image data in the Markdown output\n\n- `stopAfterMs?: number`\n Soft time budget for the crawl in milliseconds. After each scrape, the crawler checks the elapsed time and, if exceeded, returns the pages collected so far instead of continuing. Min: 10000 (10s). Max: 110000 (110s). Default: 80000 (80s).\n\n- `tags?: string[]`\n Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `urlRegex?: string`\n Regex pattern. Only URLs matching this pattern will be followed and scraped.\n\n- `useMainContentOnly?: boolean`\n Extract only the main content, stripping headers, footers, sidebars, and navigation\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load for each crawled page. Min: 0. Max: 30000 (30 seconds). \n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ metadata: { maxCrawlDepth: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }; results: { markdown: string; metadata: { crawlDepth: number; finalUrl: string; sourceUrl: string; statusCode: number; success: boolean; title: string; url: string; additionalMeta?: object; alternates?: object[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; twitter?: object; }; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `metadata: { maxCrawlDepth: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }`\n - `results: { markdown: string; metadata: { crawlDepth: number; finalUrl: string; sourceUrl: string; statusCode: number; success: boolean; title: string; url: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; twitter?: object; }; }[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webCrawlMd({ url: 'https://example.com' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.webCrawlMd', @@ -476,11 +495,11 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->webCrawlMd', example: - "web->webCrawlMd(\n url: 'https://example.com',\n country: 'de',\n excludeSelectors: ['string'],\n followSubdomains: true,\n includeFrames: true,\n includeImages: true,\n includeLinks: true,\n includeSelectors: ['string'],\n maxAgeMs: 0,\n maxDepth: 0,\n maxPages: 1,\n pdf: ['end' => 1, 'ocr' => true, 'shouldParse' => true, 'start' => 1],\n settleAnimations: true,\n shortenBase64Images: true,\n stopAfterMs: 10000,\n timeoutMs: 1000,\n urlRegex: '^https?://[^/]+/blog/',\n useMainContentOnly: true,\n waitForMs: 0,\n);\n\nvar_dump($response);", + "web->webCrawlMd(\n url: 'https://example.com',\n country: 'de',\n excludeSelectors: ['string'],\n followSubdomains: true,\n includeFrames: true,\n includeImages: true,\n includeLinks: true,\n includeSelectors: ['string'],\n maxAgeMs: 0,\n maxDepth: 0,\n maxPages: 1,\n pdf: ['end' => 1, 'ocr' => true, 'shouldParse' => true, 'start' => 1],\n settleAnimations: true,\n shortenBase64Images: true,\n stopAfterMs: 10000,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n urlRegex: '^https?://[^/]+/blog/',\n useMainContentOnly: true,\n waitForMs: 0,\n zdr: 'enabled',\n);\n\nvar_dump($response);", }, http: { example: - 'curl https://api.context.dev/v1/web/crawl \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "url": "https://example.com",\n "country": "de",\n "urlRegex": "^https?://[^/]+/blog/"\n }\'', + 'curl https://api.context.dev/v1/web/crawl \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "url": "https://example.com",\n "country": "de",\n "tags": [\n "production",\n "team-alpha"\n ],\n "urlRegex": "^https?://[^/]+/blog/"\n }\'', }, }, }, @@ -493,11 +512,17 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'Scrape font information from a website including font families, usage statistics, fallbacks, and element/word counts.', stainlessPath: '(resource) web > (method) extract_fonts', qualified: 'client.web.extractFonts', - params: ['directUrl?: string;', 'domain?: string;', 'maxAgeMs?: number;', 'timeoutMS?: number;'], + params: [ + 'directUrl?: string;', + 'domain?: string;', + 'maxAgeMs?: number;', + 'tags?: string[];', + 'timeoutMS?: number;', + ], response: '{ code: number; domain: string; fonts: { fallbacks: string[]; font: string; num_elements: number; num_words: number; percent_elements: number; percent_words: number; uses: string[]; }[]; status: string; fontLinks?: object; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - "## extract_fonts\n\n`client.web.extractFonts(directUrl?: string, domain?: string, maxAgeMs?: number, timeoutMS?: number): { code: number; domain: string; fonts: object[]; status: string; fontLinks?: object; key_metadata?: object; }`\n\n**get** `/web/fonts`\n\nScrape font information from a website including font families, usage statistics, fallbacks, and element/word counts.\n\n### Parameters\n\n- `directUrl?: string`\n A specific URL to fetch fonts from directly, bypassing domain resolution (e.g., 'https://example.com/design-system'). When provided, fonts are extracted from this exact URL. You must provide either 'domain' or 'directUrl', but not both.\n\n- `domain?: string`\n Domain name to extract fonts from (e.g., 'example.com', 'google.com'). The domain will be automatically normalized and validated. You must provide either 'domain' or 'directUrl', but not both.\n\n- `maxAgeMs?: number`\n Maximum age in milliseconds for cached data before the API performs a hard refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 year.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ code: number; domain: string; fonts: { fallbacks: string[]; font: string; num_elements: number; num_words: number; percent_elements: number; percent_words: number; uses: string[]; }[]; status: string; fontLinks?: object; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `code: number`\n - `domain: string`\n - `fonts: { fallbacks: string[]; font: string; num_elements: number; num_words: number; percent_elements: number; percent_words: number; uses: string[]; }[]`\n - `status: string`\n - `fontLinks?: object`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extractFonts();\n\nconsole.log(response);\n```", + "## extract_fonts\n\n`client.web.extractFonts(directUrl?: string, domain?: string, maxAgeMs?: number, tags?: string[], timeoutMS?: number): { code: number; domain: string; fonts: object[]; status: string; fontLinks?: object; key_metadata?: object; }`\n\n**get** `/web/fonts`\n\nScrape font information from a website including font families, usage statistics, fallbacks, and element/word counts.\n\n### Parameters\n\n- `directUrl?: string`\n A specific URL to fetch fonts from directly, bypassing domain resolution (e.g., 'https://example.com/design-system'). When provided, fonts are extracted from this exact URL. You must provide either 'domain' or 'directUrl', but not both.\n\n- `domain?: string`\n Domain name to extract fonts from (e.g., 'example.com', 'google.com'). The domain will be automatically normalized and validated. You must provide either 'domain' or 'directUrl', but not both.\n\n- `maxAgeMs?: number`\n Maximum age in milliseconds for cached brand data before the API performs a hard refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 year.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ code: number; domain: string; fonts: { fallbacks: string[]; font: string; num_elements: number; num_words: number; percent_elements: number; percent_words: number; uses: string[]; }[]; status: string; fontLinks?: object; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `code: number`\n - `domain: string`\n - `fonts: { fallbacks: string[]; font: string; num_elements: number; num_words: number; percent_elements: number; percent_words: number; uses: string[]; }[]`\n - `status: string`\n - `fontLinks?: object`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extractFonts();\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.extractFonts', @@ -526,7 +551,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->extractFonts', example: - "web->extractFonts(\n directURL: 'https://example.com',\n domain: 'domain',\n maxAgeMs: 86400000,\n timeoutMs: 1000,\n);\n\nvar_dump($response);", + "web->extractFonts(\n directURL: 'https://example.com',\n domain: 'xxx',\n maxAgeMs: 0,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: @@ -548,12 +573,13 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'directUrl?: string;', 'domain?: string;', 'maxAgeMs?: number;', + 'tags?: string[];', 'timeoutMS?: number;', ], response: "{ code?: number; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; styleguide?: { colors: { accent: string; background: string; text: string; }; components: { button: object; card?: object; }; elementSpacing: { lg: string; md: string; sm: string; xl: string; xs: string; }; fontLinks: object; mode: 'light' | 'dark'; shadows: { inner: string; lg: string; md: string; sm: string; xl: string; }; typography: { headings: object; p?: object; }; }; }", markdown: - "## extract_styleguide\n\n`client.web.extractStyleguide(colorScheme?: 'light' | 'dark', directUrl?: string, domain?: string, maxAgeMs?: number, timeoutMS?: number): { code?: number; domain?: string; key_metadata?: object; status?: string; styleguide?: object; }`\n\n**get** `/web/styleguide`\n\nExtract a comprehensive design system from a website including colors, typography, spacing, shadows, and UI components.\n\n### Parameters\n\n- `colorScheme?: 'light' | 'dark'`\n Optional browser color scheme to emulate for websites that respond to prefers-color-scheme. This value is part of the styleguide cache key.\n\n- `directUrl?: string`\n A specific URL to fetch the styleguide from directly, bypassing domain resolution (e.g., 'https://example.com/design-system'). When provided, the styleguide is extracted from this exact URL. You must provide either 'domain' or 'directUrl', but not both.\n\n- `domain?: string`\n Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The domain will be automatically normalized and validated. You must provide either 'domain' or 'directUrl', but not both.\n\n- `maxAgeMs?: number`\n Maximum age in milliseconds for cached data before the API performs a hard refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 year.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ code?: number; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; styleguide?: { colors: { accent: string; background: string; text: string; }; components: { button: object; card?: object; }; elementSpacing: { lg: string; md: string; sm: string; xl: string; xs: string; }; fontLinks: object; mode: 'light' | 'dark'; shadows: { inner: string; lg: string; md: string; sm: string; xl: string; }; typography: { headings: object; p?: object; }; }; }`\n\n - `code?: number`\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n - `styleguide?: { colors: { accent: string; background: string; text: string; }; components: { button: { link?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; color: string; css: string; fontSize: string; fontWeight: number; minHeight: string; minWidth: string; padding: string; textDecoration: string; fontFallbacks?: string[]; fontFamily?: string; textDecorationColor?: string; }; primary?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; color: string; css: string; fontSize: string; fontWeight: number; minHeight: string; minWidth: string; padding: string; textDecoration: string; fontFallbacks?: string[]; fontFamily?: string; textDecorationColor?: string; }; secondary?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; color: string; css: string; fontSize: string; fontWeight: number; minHeight: string; minWidth: string; padding: string; textDecoration: string; fontFallbacks?: string[]; fontFamily?: string; textDecorationColor?: string; }; }; card?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; css: string; padding: string; textColor: string; }; }; elementSpacing: { lg: string; md: string; sm: string; xl: string; xs: string; }; fontLinks: object; mode: 'light' | 'dark'; shadows: { inner: string; lg: string; md: string; sm: string; xl: string; }; typography: { headings: { h1?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; h2?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; h3?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; h4?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; }; p?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; }; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extractStyleguide();\n\nconsole.log(response);\n```", + "## extract_styleguide\n\n`client.web.extractStyleguide(colorScheme?: 'light' | 'dark', directUrl?: string, domain?: string, maxAgeMs?: number, tags?: string[], timeoutMS?: number): { code?: number; domain?: string; key_metadata?: object; status?: string; styleguide?: object; }`\n\n**get** `/web/styleguide`\n\nExtract a comprehensive design system from a website including colors, typography, spacing, shadows, and UI components.\n\n### Parameters\n\n- `colorScheme?: 'light' | 'dark'`\n Optional browser color scheme to emulate for websites that respond to prefers-color-scheme. This value is part of the styleguide cache key.\n\n- `directUrl?: string`\n A specific URL to fetch the styleguide from directly, bypassing domain resolution (e.g., 'https://example.com/design-system'). When provided, the styleguide is extracted from this exact URL. You must provide either 'domain' or 'directUrl', but not both.\n\n- `domain?: string`\n Domain name to extract styleguide from (e.g., 'example.com', 'google.com'). The domain will be automatically normalized and validated. You must provide either 'domain' or 'directUrl', but not both.\n\n- `maxAgeMs?: number`\n Maximum age in milliseconds for cached brand data before the API performs a hard refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 year.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ code?: number; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; styleguide?: { colors: { accent: string; background: string; text: string; }; components: { button: object; card?: object; }; elementSpacing: { lg: string; md: string; sm: string; xl: string; xs: string; }; fontLinks: object; mode: 'light' | 'dark'; shadows: { inner: string; lg: string; md: string; sm: string; xl: string; }; typography: { headings: object; p?: object; }; }; }`\n\n - `code?: number`\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n - `styleguide?: { colors: { accent: string; background: string; text: string; }; components: { button: { link?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; color: string; css: string; fontSize: string; fontWeight: number; minHeight: string; minWidth: string; padding: string; textDecoration: string; fontFallbacks?: string[]; fontFamily?: string; textDecorationColor?: string; }; primary?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; color: string; css: string; fontSize: string; fontWeight: number; minHeight: string; minWidth: string; padding: string; textDecoration: string; fontFallbacks?: string[]; fontFamily?: string; textDecorationColor?: string; }; secondary?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; color: string; css: string; fontSize: string; fontWeight: number; minHeight: string; minWidth: string; padding: string; textDecoration: string; fontFallbacks?: string[]; fontFamily?: string; textDecorationColor?: string; }; }; card?: { backgroundColor: string; borderColor: string; borderRadius: string; borderStyle: string; borderWidth: string; boxShadow: string; css: string; padding: string; textColor: string; }; }; elementSpacing: { lg: string; md: string; sm: string; xl: string; xs: string; }; fontLinks: object; mode: 'light' | 'dark'; shadows: { inner: string; lg: string; md: string; sm: string; xl: string; }; typography: { headings: { h1?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; h2?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; h3?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; h4?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; }; p?: { fontFallbacks: string[]; fontFamily: string; fontSize: string; fontWeight: number; letterSpacing: string; lineHeight: string; }; }; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extractStyleguide();\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.extractStyleguide', @@ -582,7 +608,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->extractStyleguide', example: - "web->extractStyleguide(\n colorScheme: 'light',\n directURL: 'https://example.com',\n domain: 'domain',\n maxAgeMs: 86400000,\n timeoutMs: 1000,\n);\n\nvar_dump($response);", + "web->extractStyleguide(\n colorScheme: 'light',\n directURL: 'https://example.com',\n domain: 'xxx',\n maxAgeMs: 0,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: @@ -607,12 +633,13 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'markdownOptions?: { enabled?: boolean; includeFrames?: boolean; includeImages?: boolean; includeLinks?: boolean; maxAgeMs?: number; pdf?: { end?: number; shouldParse?: boolean; start?: number; }; shortenBase64Images?: boolean; timeoutMS?: number; useMainContentOnly?: boolean; waitForMs?: number; };', 'numResults?: number;', 'queryFanout?: boolean;', + 'tags?: string[];', 'timeoutMS?: number;', ], response: "{ query: string; results: { description: string; markdown: { code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'WEBSITE_ACCESS_ERROR' | 'ERROR'; markdown: string; }; relevance: 'high' | 'medium' | 'low'; title: string; url: string; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", markdown: - "## search\n\n`client.web.search(query: string, country?: string, excludeDomains?: string[], freshness?: 'last_24_hours' | 'last_week' | 'last_month' | 'last_year', includeDomains?: string[], markdownOptions?: { enabled?: boolean; includeFrames?: boolean; includeImages?: boolean; includeLinks?: boolean; maxAgeMs?: number; pdf?: { end?: number; shouldParse?: boolean; start?: number; }; shortenBase64Images?: boolean; timeoutMS?: number; useMainContentOnly?: boolean; waitForMs?: number; }, numResults?: number, queryFanout?: boolean, timeoutMS?: number): { query: string; results: object[]; key_metadata?: object; }`\n\n**post** `/web/search`\n\nSearch the web and optionally scrape each result to Markdown in one round-trip.\n\n### Parameters\n\n- `query: string`\n Search query. Accepts natural language as well as Google-style search operators such as `site:`, `-site:`, `inurl:`, `intitle:`, quoted phrases, and `OR`.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code to localize results to a specific country (maps to Google's `gl` parameter). Example: \"us\", \"gb\", \"de\".\n\n- `excludeDomains?: string[]`\n Blocklist — drop results from these domains. Example: [\"pinterest.com\", \"reddit.com\"].\n\n- `freshness?: 'last_24_hours' | 'last_week' | 'last_month' | 'last_year'`\n Restrict results to content published within this window.\n\n- `includeDomains?: string[]`\n Allowlist — only return results from these domains. Example: [\"arxiv.org\", \"github.com\"].\n\n- `markdownOptions?: { enabled?: boolean; includeFrames?: boolean; includeImages?: boolean; includeLinks?: boolean; maxAgeMs?: number; pdf?: { end?: number; shouldParse?: boolean; start?: number; }; shortenBase64Images?: boolean; timeoutMS?: number; useMainContentOnly?: boolean; waitForMs?: number; }`\n Inline Markdown scraping for each result. Set `enabled: true` to activate.\n - `enabled?: boolean`\n Scrape each result to Markdown. Off by default to keep search cheap and fast.\n - `includeFrames?: boolean`\n Render iframe contents into the Markdown.\n - `includeImages?: boolean`\n Emit image references in the Markdown.\n - `includeLinks?: boolean`\n Keep hyperlinks in the Markdown.\n - `maxAgeMs?: number`\n Cache TTL in ms for scraped Markdown keyed by URL + options. Default 1 day, max 30 days. Set to 0 to force a fresh scrape.\n - `pdf?: { end?: number; shouldParse?: boolean; start?: number; }`\n PDF handling. Use start/end to bound text extraction and OCR to a page range.\n - `shortenBase64Images?: boolean`\n Truncate inline base64 image payloads to keep responses small.\n - `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n - `useMainContentOnly?: boolean`\n Strip nav, header, footer, and sidebar — keep only the primary article content.\n - `waitForMs?: number`\n Extra wait after page load before rendering, in ms (0–30000). Useful for JS-heavy pages.\n\n- `numResults?: number`\n Number of results to request and return (10–100). Defaults to 10.\n\n- `queryFanout?: boolean`\n Expand the query into multiple parallel variants for broader recall.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ query: string; results: { description: string; markdown: { code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'WEBSITE_ACCESS_ERROR' | 'ERROR'; markdown: string; }; relevance: 'high' | 'medium' | 'low'; title: string; url: string; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `query: string`\n - `results: { description: string; markdown: { code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'WEBSITE_ACCESS_ERROR' | 'ERROR'; markdown: string; }; relevance: 'high' | 'medium' | 'low'; title: string; url: string; }[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.search({ query: 'x' });\n\nconsole.log(response);\n```", + "## search\n\n`client.web.search(query: string, country?: string, excludeDomains?: string[], freshness?: 'last_24_hours' | 'last_week' | 'last_month' | 'last_year', includeDomains?: string[], markdownOptions?: { enabled?: boolean; includeFrames?: boolean; includeImages?: boolean; includeLinks?: boolean; maxAgeMs?: number; pdf?: { end?: number; shouldParse?: boolean; start?: number; }; shortenBase64Images?: boolean; timeoutMS?: number; useMainContentOnly?: boolean; waitForMs?: number; }, numResults?: number, queryFanout?: boolean, tags?: string[], timeoutMS?: number): { query: string; results: object[]; key_metadata?: object; }`\n\n**post** `/web/search`\n\nSearch the web and optionally scrape each result to Markdown in one round-trip.\n\n### Parameters\n\n- `query: string`\n Search query. Accepts natural language as well as Google-style search operators such as `site:`, `-site:`, `inurl:`, `intitle:`, quoted phrases, and `OR`.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code to localize results to a specific country (maps to Google's `gl` parameter). Example: \"us\", \"gb\", \"de\".\n\n- `excludeDomains?: string[]`\n Blocklist — drop results from these domains. Example: [\"pinterest.com\", \"reddit.com\"].\n\n- `freshness?: 'last_24_hours' | 'last_week' | 'last_month' | 'last_year'`\n Restrict results to content published within this window.\n\n- `includeDomains?: string[]`\n Allowlist — only return results from these domains. Example: [\"arxiv.org\", \"github.com\"].\n\n- `markdownOptions?: { enabled?: boolean; includeFrames?: boolean; includeImages?: boolean; includeLinks?: boolean; maxAgeMs?: number; pdf?: { end?: number; shouldParse?: boolean; start?: number; }; shortenBase64Images?: boolean; timeoutMS?: number; useMainContentOnly?: boolean; waitForMs?: number; }`\n Inline Markdown scraping for each result. Set `enabled: true` to activate.\n - `enabled?: boolean`\n Scrape each result to Markdown. Off by default to keep search cheap and fast.\n - `includeFrames?: boolean`\n Render iframe contents into the Markdown.\n - `includeImages?: boolean`\n Emit image references in the Markdown.\n - `includeLinks?: boolean`\n Keep hyperlinks in the Markdown.\n - `maxAgeMs?: number`\n Cache TTL in ms for scraped Markdown keyed by URL + options. Default 1 day, max 30 days. Set to 0 to force a fresh scrape.\n - `pdf?: { end?: number; shouldParse?: boolean; start?: number; }`\n PDF handling. Use start/end to bound text extraction and OCR to a page range.\n - `shortenBase64Images?: boolean`\n Truncate inline base64 image payloads to keep responses small.\n - `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n - `useMainContentOnly?: boolean`\n Strip nav, header, footer, and sidebar — keep only the primary article content.\n - `waitForMs?: number`\n Extra wait after page load before rendering, in ms (0–30000). Useful for JS-heavy pages.\n\n- `numResults?: number`\n Number of results to request and return (10–100). Defaults to 10.\n\n- `queryFanout?: boolean`\n Expand the query into multiple parallel variants for broader recall.\n\n- `tags?: string[]`\n Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ query: string; results: { description: string; markdown: { code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'WEBSITE_ACCESS_ERROR' | 'ERROR'; markdown: string; }; relevance: 'high' | 'medium' | 'low'; title: string; url: string; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `query: string`\n - `results: { description: string; markdown: { code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'WEBSITE_ACCESS_ERROR' | 'ERROR'; markdown: string; }; relevance: 'high' | 'medium' | 'low'; title: string; url: string; }[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.search({ query: 'x' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.search', @@ -641,11 +668,11 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->search', example: - "web->search(\n query: 'x',\n country: 'af',\n excludeDomains: ['string'],\n freshness: 'last_24_hours',\n includeDomains: ['string'],\n markdownOptions: [\n 'enabled' => true,\n 'includeFrames' => true,\n 'includeImages' => true,\n 'includeLinks' => true,\n 'maxAgeMs' => 0,\n 'pdf' => ['end' => 1, 'shouldParse' => true, 'start' => 1],\n 'shortenBase64Images' => true,\n 'timeoutMs' => 1000,\n 'useMainContentOnly' => true,\n 'waitForMs' => 0,\n ],\n numResults: 10,\n queryFanout: true,\n timeoutMs: 1000,\n);\n\nvar_dump($response);", + "web->search(\n query: 'x',\n country: 'af',\n excludeDomains: ['string'],\n freshness: 'last_24_hours',\n includeDomains: ['string'],\n markdownOptions: [\n 'enabled' => true,\n 'includeFrames' => true,\n 'includeImages' => true,\n 'includeLinks' => true,\n 'maxAgeMs' => 0,\n 'pdf' => ['end' => 1, 'shouldParse' => true, 'start' => 1],\n 'shortenBase64Images' => true,\n 'timeoutMs' => 1000,\n 'useMainContentOnly' => true,\n 'waitForMs' => 0,\n ],\n numResults: 10,\n queryFanout: true,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: - 'curl https://api.context.dev/v1/web/search \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "query": "x"\n }\'', + 'curl https://api.context.dev/v1/web/search \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "query": "x",\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', }, }, }, @@ -669,14 +696,16 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'maxDepth?: number;', 'maxPages?: number;', 'pdf?: { end?: number; shouldParse?: boolean; start?: number; };', + 'settleAnimations?: boolean;', 'stopAfterMs?: number;', + 'tags?: string[];', 'timeoutMS?: number;', 'waitForMs?: number;', ], response: '{ data: object; metadata: { maxCrawlDepth: number; numBlocked: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }; status: string; url: string; urls_analyzed: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - "## extract\n\n`client.web.extract(schema: object, url: string, factCheck?: boolean, followSubdomains?: boolean, includeFrames?: boolean, instructions?: string, maxAgeMs?: number, maxDepth?: number, maxPages?: number, pdf?: { end?: number; shouldParse?: boolean; start?: number; }, stopAfterMs?: number, timeoutMS?: number, waitForMs?: number): { data: object; metadata: object; status: string; url: string; urls_analyzed: string[]; key_metadata?: object; }`\n\n**post** `/web/extract`\n\nCrawl a website, use the provided JSON Schema and instructions to prioritize relevant internal links, and extract structured data from the selected pages.\n\n### Parameters\n\n- `schema: object`\n JSON Schema for the returned data object. TypeScript Zod users can pass a JSON Schema generated from a Zod object; Python users can pass the equivalent JSON Schema object.\n\n- `url: string`\n The starting website URL to crawl and extract from. Must include http:// or https://.\n\n- `factCheck?: boolean`\n When true, every returned value must be grounded in facts stated on the page; fields that cannot be supported by the page are returned as null/empty. When false (default), the model may make reasonable inferences and derivations from the page content (e.g. ideal customer, competitor analysis, recommendations) while keeping verifiable specifics (names, quotes, URLs, dates, metrics) faithful to the source.\n\n- `followSubdomains?: boolean`\n When true, follow links on subdomains of the starting URL's domain.\n\n- `includeFrames?: boolean`\n When true, iframe contents are included in Markdown before extraction.\n\n- `instructions?: string`\n Optional extraction guidance, such as which facts to prioritize or how to interpret fields in the schema.\n\n- `maxAgeMs?: number`\n Return cached scrape results if a prior scrape for the same parameters is younger than this many milliseconds. Defaults to 7 days (604800000 ms).\n\n- `maxDepth?: number`\n Optional maximum link depth from the starting URL (0 = only the starting page). If omitted, there is no crawl depth limit.\n\n- `maxPages?: number`\n Maximum number of pages to analyze for extraction. Hard cap: 50. Defaults to 5.\n\n- `pdf?: { end?: number; shouldParse?: boolean; start?: number; }`\n - `end?: number`\n Last 1-based PDF page to parse. Must be greater than or equal to start when both are provided.\n - `shouldParse?: boolean`\n When true, PDF pages are fetched and parsed. When false, PDF pages are skipped.\n - `start?: number`\n First 1-based PDF page to parse.\n\n- `stopAfterMs?: number`\n Soft time budget for the crawl in milliseconds. Min: 10000 (10s). Max: 110000 (110s). Default: 80000 (80s).\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load for each crawled page.\n\n### Returns\n\n- `{ data: object; metadata: { maxCrawlDepth: number; numBlocked: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }; status: string; url: string; urls_analyzed: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `data: object`\n - `metadata: { maxCrawlDepth: number; numBlocked: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }`\n - `status: string`\n - `url: string`\n - `urls_analyzed: string[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extract({\n schema: {\n type: 'bar',\n properties: 'bar',\n required: 'bar',\n additionalProperties: 'bar',\n},\n url: 'https://example.com',\n});\n\nconsole.log(response);\n```", + "## extract\n\n`client.web.extract(schema: object, url: string, factCheck?: boolean, followSubdomains?: boolean, includeFrames?: boolean, instructions?: string, maxAgeMs?: number, maxDepth?: number, maxPages?: number, pdf?: { end?: number; shouldParse?: boolean; start?: number; }, settleAnimations?: boolean, stopAfterMs?: number, tags?: string[], timeoutMS?: number, waitForMs?: number): { data: object; metadata: object; status: string; url: string; urls_analyzed: string[]; key_metadata?: object; }`\n\n**post** `/web/extract`\n\nCrawl a website, use the provided JSON Schema and instructions to prioritize relevant internal links, and extract structured data from the selected pages.\n\n### Parameters\n\n- `schema: object`\n JSON Schema for the returned data object. TypeScript Zod users can pass a JSON Schema generated from a Zod object; Python users can pass the equivalent JSON Schema object.\n\n- `url: string`\n The starting website URL to crawl and extract from. Must include http:// or https://.\n\n- `factCheck?: boolean`\n When true, every returned value must be grounded in facts stated on the page; fields that cannot be supported by the page are returned as null/empty. When false (default), the model may make reasonable inferences and derivations from the page content (e.g. ideal customer, competitor analysis, recommendations) while keeping verifiable specifics (names, quotes, URLs, dates, metrics) faithful to the source.\n\n- `followSubdomains?: boolean`\n When true, follow links on subdomains of the starting URL's domain.\n\n- `includeFrames?: boolean`\n When true, iframe contents are included in Markdown before extraction.\n\n- `instructions?: string`\n Optional extraction guidance, such as which facts to prioritize or how to interpret fields in the schema.\n\n- `maxAgeMs?: number`\n Return cached scrape results if a prior scrape for the same parameters is younger than this many milliseconds. Defaults to 7 days (604800000 ms).\n\n- `maxDepth?: number`\n Optional maximum link depth from the starting URL (0 = only the starting page). If omitted, there is no crawl depth limit.\n\n- `maxPages?: number`\n Maximum number of pages to analyze for extraction. Hard cap: 50. Defaults to 5.\n\n- `pdf?: { end?: number; shouldParse?: boolean; start?: number; }`\n - `end?: number`\n Last 1-based PDF page to parse. Must be greater than or equal to start when both are provided.\n - `shouldParse?: boolean`\n When true, PDF pages are fetched and parsed. When false, PDF pages are skipped.\n - `start?: number`\n First 1-based PDF page to parse.\n\n- `settleAnimations?: boolean`\n When true, waits briefly for CSS and transition animations to settle before extracting each crawled page. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `stopAfterMs?: number`\n Soft time budget for the crawl in milliseconds. Min: 10000 (10s). Max: 110000 (110s). Default: 80000 (80s).\n\n- `tags?: string[]`\n Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load for each crawled page.\n\n### Returns\n\n- `{ data: object; metadata: { maxCrawlDepth: number; numBlocked: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }; status: string; url: string; urls_analyzed: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `data: object`\n - `metadata: { maxCrawlDepth: number; numBlocked: number; numFailed: number; numSkipped: number; numSucceeded: number; numUrls: number; }`\n - `status: string`\n - `url: string`\n - `urls_analyzed: string[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extract({\n schema: {\n type: 'bar',\n properties: 'bar',\n required: 'bar',\n additionalProperties: 'bar',\n},\n url: 'https://example.com',\n});\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.extract', @@ -706,11 +735,11 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->extract', example: - "web->extract(\n schema: [\n 'type' => 'bar',\n 'properties' => 'bar',\n 'required' => 'bar',\n 'additionalProperties' => 'bar',\n ],\n url: 'https://example.com',\n factCheck: true,\n followSubdomains: true,\n includeFrames: true,\n instructions: 'instructions',\n maxAgeMs: 0,\n maxDepth: 0,\n maxPages: 1,\n pdf: ['end' => 1, 'shouldParse' => true, 'start' => 1],\n stopAfterMs: 10000,\n timeoutMs: 1000,\n waitForMs: 0,\n);\n\nvar_dump($response);", + "web->extract(\n schema: [\n 'type' => 'bar',\n 'properties' => 'bar',\n 'required' => 'bar',\n 'additionalProperties' => 'bar',\n ],\n url: 'https://example.com',\n factCheck: true,\n followSubdomains: true,\n includeFrames: true,\n instructions: 'instructions',\n maxAgeMs: 0,\n maxDepth: 0,\n maxPages: 1,\n pdf: ['end' => 1, 'shouldParse' => true, 'start' => 1],\n settleAnimations: true,\n stopAfterMs: 10000,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n waitForMs: 0,\n);\n\nvar_dump($response);", }, http: { example: - 'curl https://api.context.dev/v1/web/extract \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "schema": {\n "type": "bar",\n "properties": "bar",\n "required": "bar",\n "additionalProperties": "bar"\n },\n "url": "https://example.com"\n }\'', + 'curl https://api.context.dev/v1/web/extract \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "schema": {\n "type": "bar",\n "properties": "bar",\n "required": "bar",\n "additionalProperties": "bar"\n },\n "url": "https://example.com",\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', }, }, }, @@ -723,11 +752,11 @@ const EMBEDDED_METHODS: MethodEntry[] = [ "Analyze a company's landing page and web search evidence to return direct competitors for the same product or market.", stainlessPath: '(resource) web > (method) extract_competitors', qualified: 'client.web.extractCompetitors', - params: ['domain: string;', 'numCompetitors?: number;', 'timeoutMS?: number;'], + params: ['domain: string;', 'numCompetitors?: number;', 'tags?: string[];', 'timeoutMS?: number;'], response: "{ competitors: { confidence: 'high' | 'medium'; description: string; domain: string; name: string; sourceUrls: string[]; url: string; }[]; domain: string; status: 'ok'; target: { companyName: string; field: string; fieldDescription: string; websiteUrl: string; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", markdown: - "## extract_competitors\n\n`client.web.extractCompetitors(domain: string, numCompetitors?: number, timeoutMS?: number): { competitors: object[]; domain: string; status: 'ok'; target: object; key_metadata?: object; }`\n\n**get** `/web/competitors`\n\nAnalyze a company's landing page and web search evidence to return direct competitors for the same product or market.\n\n### Parameters\n\n- `domain: string`\n Company domain to analyze, such as `stripe.com`. Full http(s) URLs are accepted and normalized to their domain.\n\n- `numCompetitors?: number`\n Exact number of direct competitors to return. Defaults to 5.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ competitors: { confidence: 'high' | 'medium'; description: string; domain: string; name: string; sourceUrls: string[]; url: string; }[]; domain: string; status: 'ok'; target: { companyName: string; field: string; fieldDescription: string; websiteUrl: string; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `competitors: { confidence: 'high' | 'medium'; description: string; domain: string; name: string; sourceUrls: string[]; url: string; }[]`\n - `domain: string`\n - `status: 'ok'`\n - `target: { companyName: string; field: string; fieldDescription: string; websiteUrl: string; }`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extractCompetitors({ domain: 'xxx' });\n\nconsole.log(response);\n```", + "## extract_competitors\n\n`client.web.extractCompetitors(domain: string, numCompetitors?: number, tags?: string[], timeoutMS?: number): { competitors: object[]; domain: string; status: 'ok'; target: object; key_metadata?: object; }`\n\n**get** `/web/competitors`\n\nAnalyze a company's landing page and web search evidence to return direct competitors for the same product or market.\n\n### Parameters\n\n- `domain: string`\n Company domain to analyze, such as `stripe.com`. Full http(s) URLs are accepted and normalized to their domain.\n\n- `numCompetitors?: number`\n Exact number of direct competitors to return. Defaults to 5.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ competitors: { confidence: 'high' | 'medium'; description: string; domain: string; name: string; sourceUrls: string[]; url: string; }[]; domain: string; status: 'ok'; target: { companyName: string; field: string; fieldDescription: string; websiteUrl: string; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `competitors: { confidence: 'high' | 'medium'; description: string; domain: string; name: string; sourceUrls: string[]; url: string; }[]`\n - `domain: string`\n - `status: 'ok'`\n - `target: { companyName: string; field: string; fieldDescription: string; websiteUrl: string; }`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.extractCompetitors({ domain: 'xxx' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.web.extractCompetitors', @@ -756,7 +785,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->extractCompetitors', example: - "web->extractCompetitors(\n domain: 'xxx', numCompetitors: 1, timeoutMs: 1000\n);\n\nvar_dump($response);", + "web->extractCompetitors(\n domain: 'xxx',\n numCompetitors: 1,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: @@ -774,7 +803,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ stainlessPath: '(resource) ai > (method) extract_products', qualified: 'client.ai.extractProducts', params: [ - '{ domain: string; maxAgeMs?: number; maxProducts?: number; timeoutMS?: number; } | { directUrl: string; maxAgeMs?: number; maxProducts?: number; timeoutMS?: number; };', + '{ domain: string; maxAgeMs?: number; maxProducts?: number; tags?: string[]; timeoutMS?: number; } | { directUrl: string; maxAgeMs?: number; maxProducts?: number; tags?: string[]; timeoutMS?: number; };', ], response: "{ key_metadata?: { credits_consumed: number; credits_remaining: number; }; products?: { description: string; features: string[]; images: string[]; name: string; sku: string; tags: string[]; target_audience: string[]; billing_frequency?: 'monthly' | 'yearly' | 'one_time' | 'usage_based'; category?: string; currency?: string; image_url?: string; price?: number; pricing_model?: 'per_seat' | 'flat' | 'tiered' | 'freemium' | 'custom'; url?: string; }[]; }", @@ -807,11 +836,11 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'ai->extractProducts', example: - "ai->extractProducts(\n domain: 'domain',\n maxAgeMs: 0,\n maxProducts: 1,\n timeoutMs: 1000,\n directURL: 'https://example.com',\n);\n\nvar_dump($response);", + "ai->extractProducts(\n domain: 'domain',\n maxAgeMs: 0,\n maxProducts: 1,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n directURL: 'https://example.com',\n);\n\nvar_dump($response);", }, http: { example: - 'curl https://api.context.dev/v1/brand/ai/products \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "domain": "domain"\n }\'', + 'curl https://api.context.dev/v1/brand/ai/products \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "domain": "domain",\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', }, }, }, @@ -824,11 +853,11 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'Given a single URL, determines if it is a product page and extracts the product information.', stainlessPath: '(resource) ai > (method) extract_product', qualified: 'client.ai.extractProduct', - params: ['url: string;', 'maxAgeMs?: number;', 'timeoutMS?: number;'], + params: ['url: string;', 'maxAgeMs?: number;', 'tags?: string[];', 'timeoutMS?: number;'], response: "{ is_product_page?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; platform?: 'amazon' | 'tiktok_shop' | 'etsy' | 'generic'; product?: { description: string; features: string[]; images: string[]; name: string; sku: string; tags: string[]; target_audience: string[]; billing_frequency?: 'monthly' | 'yearly' | 'one_time' | 'usage_based'; category?: string; currency?: string; image_url?: string; price?: number; pricing_model?: 'per_seat' | 'flat' | 'tiered' | 'freemium' | 'custom'; url?: string; }; }", markdown: - "## extract_product\n\n`client.ai.extractProduct(url: string, maxAgeMs?: number, timeoutMS?: number): { is_product_page?: boolean; key_metadata?: object; platform?: 'amazon' | 'tiktok_shop' | 'etsy' | 'generic'; product?: object; }`\n\n**post** `/brand/ai/product`\n\nGiven a single URL, determines if it is a product page and extracts the product information.\n\n### Parameters\n\n- `url: string`\n The product page URL to extract product data from.\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 7 days (604800000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ is_product_page?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; platform?: 'amazon' | 'tiktok_shop' | 'etsy' | 'generic'; product?: { description: string; features: string[]; images: string[]; name: string; sku: string; tags: string[]; target_audience: string[]; billing_frequency?: 'monthly' | 'yearly' | 'one_time' | 'usage_based'; category?: string; currency?: string; image_url?: string; price?: number; pricing_model?: 'per_seat' | 'flat' | 'tiered' | 'freemium' | 'custom'; url?: string; }; }`\n\n - `is_product_page?: boolean`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `platform?: 'amazon' | 'tiktok_shop' | 'etsy' | 'generic'`\n - `product?: { description: string; features: string[]; images: string[]; name: string; sku: string; tags: string[]; target_audience: string[]; billing_frequency?: 'monthly' | 'yearly' | 'one_time' | 'usage_based'; category?: string; currency?: string; image_url?: string; price?: number; pricing_model?: 'per_seat' | 'flat' | 'tiered' | 'freemium' | 'custom'; url?: string; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.ai.extractProduct({ url: 'https://example.com' });\n\nconsole.log(response);\n```", + "## extract_product\n\n`client.ai.extractProduct(url: string, maxAgeMs?: number, tags?: string[], timeoutMS?: number): { is_product_page?: boolean; key_metadata?: object; platform?: 'amazon' | 'tiktok_shop' | 'etsy' | 'generic'; product?: object; }`\n\n**post** `/brand/ai/product`\n\nGiven a single URL, determines if it is a product page and extracts the product information.\n\n### Parameters\n\n- `url: string`\n The product page URL to extract product data from.\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 7 days (604800000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `tags?: string[]`\n Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ is_product_page?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; platform?: 'amazon' | 'tiktok_shop' | 'etsy' | 'generic'; product?: { description: string; features: string[]; images: string[]; name: string; sku: string; tags: string[]; target_audience: string[]; billing_frequency?: 'monthly' | 'yearly' | 'one_time' | 'usage_based'; category?: string; currency?: string; image_url?: string; price?: number; pricing_model?: 'per_seat' | 'flat' | 'tiered' | 'freemium' | 'custom'; url?: string; }; }`\n\n - `is_product_page?: boolean`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `platform?: 'amazon' | 'tiktok_shop' | 'etsy' | 'generic'`\n - `product?: { description: string; features: string[]; images: string[]; name: string; sku: string; tags: string[]; target_audience: string[]; billing_frequency?: 'monthly' | 'yearly' | 'one_time' | 'usage_based'; category?: string; currency?: string; image_url?: string; price?: number; pricing_model?: 'per_seat' | 'flat' | 'tiered' | 'freemium' | 'custom'; url?: string; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.ai.extractProduct({ url: 'https://example.com' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.ai.extractProduct', @@ -858,11 +887,11 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'ai->extractProduct', example: - "ai->extractProduct(\n url: 'https://example.com', maxAgeMs: 0, timeoutMs: 1000\n);\n\nvar_dump($response);", + "ai->extractProduct(\n url: 'https://example.com',\n maxAgeMs: 0,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: - 'curl https://api.context.dev/v1/brand/ai/product \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "url": "https://example.com"\n }\'', + 'curl https://api.context.dev/v1/brand/ai/product \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "url": "https://example.com",\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', }, }, }, @@ -876,7 +905,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ stainlessPath: '(resource) brand > (method) retrieve', qualified: 'client.brand.retrieve', params: [ - "{ domain: string; type: 'by_domain'; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; timeoutMS?: number; } | { name: string; type: 'by_name'; country_gl?: string; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; timeoutMS?: number; } | { email: string; type: 'by_email'; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; timeoutMS?: number; } | { ticker: string; type: 'by_ticker'; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; ticker_exchange?: string; timeoutMS?: number; } | { direct_url: string; type: 'by_direct_url'; timeoutMS?: number; } | { transaction_info: string; type: 'by_transaction'; city?: string; country_gl?: string; force_language?: string; high_confidence_only?: boolean; maxSpeed?: boolean; mcc?: number; phone?: number; timeoutMS?: number; };", + "{ domain: string; type: 'by_domain'; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; tags?: string[]; timeoutMS?: number; } | { name: string; type: 'by_name'; country_gl?: string; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; tags?: string[]; timeoutMS?: number; } | { email: string; type: 'by_email'; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; tags?: string[]; timeoutMS?: number; } | { ticker: string; type: 'by_ticker'; force_language?: string; maxAgeMs?: number; maxSpeed?: boolean; tags?: string[]; ticker_exchange?: string; timeoutMS?: number; } | { direct_url: string; type: 'by_direct_url'; tags?: string[]; timeoutMS?: number; } | { transaction_info: string; type: 'by_transaction'; city?: string; country_gl?: string; force_language?: string; high_confidence_only?: boolean; maxSpeed?: boolean; mcc?: string | number; phone?: string | number; tags?: string[]; timeoutMS?: number; };", ], response: "{ brand?: { address?: { city?: string; country?: string; country_code?: string; postal_code?: string; state_code?: string; state_province?: string; street?: string; }; backdrops?: { colors?: object[]; resolution?: object; url?: string; }[]; colors?: { hex?: string; name?: string; }[]; description?: string; domain?: string; email?: string; industries?: { eic?: object[]; }; is_nsfw?: boolean; links?: { blog?: string; careers?: string; contact?: string; pricing?: string; privacy?: string; terms?: string; }; logos?: { colors?: object[]; mode?: 'light' | 'dark' | 'has_opaque_background'; resolution?: object; type?: 'icon' | 'logo'; url?: string; }[]; phone?: string; primary_language?: string; slogan?: string; socials?: { type?: string; url?: string; }[]; stock?: { exchange?: string; ticker?: string; }; title?: string; }; code?: number; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; }", @@ -904,16 +933,16 @@ const EMBEDDED_METHODS: MethodEntry[] = [ cli: { method: 'brand retrieve', example: - "context-dev brand retrieve \\\n --api-key 'My API Key' \\\n --domain domain \\\n --type by_domain \\\n --name xxx \\\n --email dev@stainless.com \\\n --ticker ticker \\\n --direct-url https://example.com \\\n --transaction-info xxx", + "context-dev brand retrieve \\\n --api-key 'My API Key' \\\n --domain xxx \\\n --type by_domain \\\n --name xxx \\\n --email dev@stainless.com \\\n --ticker ticker \\\n --direct-url https://example.com \\\n --transaction-info xxx", }, php: { method: 'brand->retrieve', example: - "brand->retrieve(\n domain: 'domain',\n type: 'by_transaction',\n forceLanguage: 'afrikaans',\n maxAgeMs: 0,\n maxSpeed: true,\n timeoutMs: 1000,\n name: 'xxx',\n countryGl: 'country_gl',\n email: 'dev@stainless.com',\n ticker: 'ticker',\n tickerExchange: 'ticker_exchange',\n directURL: 'https://example.com',\n transactionInfo: 'xxx',\n city: 'city',\n highConfidenceOnly: true,\n mcc: 0,\n phone: 0,\n);\n\nvar_dump($brand);", + "brand->retrieve(\n domain: 'xxx',\n type: 'by_transaction',\n forceLanguage: 'afrikaans',\n maxAgeMs: 0,\n maxSpeed: true,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n name: 'xxx',\n countryGl: 'country_gl',\n email: 'dev@stainless.com',\n ticker: 'ticker',\n tickerExchange: 'ticker_exchange',\n directURL: 'https://example.com',\n transactionInfo: 'xxx',\n city: 'city',\n highConfidenceOnly: true,\n mcc: 'string',\n phone: 'string',\n);\n\nvar_dump($brand);", }, http: { example: - 'curl https://api.context.dev/v1/brand/retrieve \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "domain": "domain",\n "type": "by_domain"\n }\'', + 'curl https://api.context.dev/v1/brand/retrieve \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "domain": "xxx",\n "type": "by_domain",\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', }, }, }, @@ -926,40 +955,46 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'Returns a simplified version of brand data containing only essential information: domain, title, colors, logos, and backdrops. Optimized for faster responses and reduced data transfer.', stainlessPath: '(resource) brand > (method) retrieve_simplified', qualified: 'client.brand.retrieveSimplified', - params: ['domain: string;', 'maxAgeMs?: number;', 'timeoutMS?: number;'], + params: [ + 'domain: string;', + 'maxAgeMs?: number;', + 'tags?: string[];', + "theme?: 'light' | 'dark';", + 'timeoutMS?: number;', + ], response: "{ brand?: { backdrops?: { colors?: object[]; resolution?: object; url?: string; }[]; colors?: { hex?: string; name?: string; }[]; domain?: string; logos?: { colors?: object[]; mode?: 'light' | 'dark' | 'has_opaque_background'; resolution?: object; type?: 'icon' | 'logo'; url?: string; }[]; title?: string; }; code?: number; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; }", markdown: - "## retrieve_simplified\n\n`client.brand.retrieveSimplified(domain: string, maxAgeMs?: number, timeoutMS?: number): { brand?: object; code?: number; key_metadata?: object; status?: string; }`\n\n**get** `/brand/retrieve-simplified`\n\nReturns a simplified version of brand data containing only essential information: domain, title, colors, logos, and backdrops. Optimized for faster responses and reduced data transfer.\n\n### Parameters\n\n- `domain: string`\n Domain name to retrieve simplified brand data for\n\n- `maxAgeMs?: number`\n Maximum age in milliseconds for cached brand data before the API performs a hard refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 year.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ brand?: { backdrops?: { colors?: object[]; resolution?: object; url?: string; }[]; colors?: { hex?: string; name?: string; }[]; domain?: string; logos?: { colors?: object[]; mode?: 'light' | 'dark' | 'has_opaque_background'; resolution?: object; type?: 'icon' | 'logo'; url?: string; }[]; title?: string; }; code?: number; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; }`\n\n - `brand?: { backdrops?: { colors?: { hex?: string; name?: string; }[]; resolution?: { aspect_ratio?: number; height?: number; width?: number; }; url?: string; }[]; colors?: { hex?: string; name?: string; }[]; domain?: string; logos?: { colors?: { hex?: string; name?: string; }[]; mode?: 'light' | 'dark' | 'has_opaque_background'; resolution?: { aspect_ratio?: number; height?: number; width?: number; }; type?: 'icon' | 'logo'; url?: string; }[]; title?: string; }`\n - `code?: number`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.brand.retrieveSimplified({ domain: 'domain' });\n\nconsole.log(response);\n```", + "## retrieve_simplified\n\n`client.brand.retrieveSimplified(domain: string, maxAgeMs?: number, tags?: string[], theme?: 'light' | 'dark', timeoutMS?: number): { brand?: object; code?: number; key_metadata?: object; status?: string; }`\n\n**get** `/brand/retrieve-simplified`\n\nReturns a simplified version of brand data containing only essential information: domain, title, colors, logos, and backdrops. Optimized for faster responses and reduced data transfer.\n\n### Parameters\n\n- `domain: string`\n Domain name to retrieve simplified brand data for\n\n- `maxAgeMs?: number`\n Maximum age in milliseconds for cached brand data before the API performs a hard refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 year.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `theme?: 'light' | 'dark'`\n Optional theme preference used when selecting brand assets.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ brand?: { backdrops?: { colors?: object[]; resolution?: object; url?: string; }[]; colors?: { hex?: string; name?: string; }[]; domain?: string; logos?: { colors?: object[]; mode?: 'light' | 'dark' | 'has_opaque_background'; resolution?: object; type?: 'icon' | 'logo'; url?: string; }[]; title?: string; }; code?: number; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; }`\n\n - `brand?: { backdrops?: { colors?: { hex?: string; name?: string; }[]; resolution?: { aspect_ratio?: number; height?: number; width?: number; }; url?: string; }[]; colors?: { hex?: string; name?: string; }[]; domain?: string; logos?: { colors?: { hex?: string; name?: string; }[]; mode?: 'light' | 'dark' | 'has_opaque_background'; resolution?: { aspect_ratio?: number; height?: number; width?: number; }; type?: 'icon' | 'logo'; url?: string; }[]; title?: string; }`\n - `code?: number`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.brand.retrieveSimplified({ domain: 'xxx' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.brand.retrieveSimplified', example: - "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.brand.retrieveSimplified({ domain: 'domain' });\n\nconsole.log(response.brand);", + "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.brand.retrieveSimplified({ domain: 'xxx' });\n\nconsole.log(response.brand);", }, python: { method: 'brand.retrieve_simplified', example: - 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.brand.retrieve_simplified(\n domain="domain",\n)\nprint(response.brand)', + 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.brand.retrieve_simplified(\n domain="xxx",\n)\nprint(response.brand)', }, go: { method: 'client.Brand.GetSimplified', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Brand.GetSimplified(context.TODO(), contextdev.BrandGetSimplifiedParams{\n\t\tDomain: "domain",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Brand)\n}\n', + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Brand.GetSimplified(context.TODO(), contextdev.BrandGetSimplifiedParams{\n\t\tDomain: "xxx",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Brand)\n}\n', }, ruby: { method: 'brand.retrieve_simplified', example: - 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.brand.retrieve_simplified(domain: "domain")\n\nputs(response)', + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.brand.retrieve_simplified(domain: "xxx")\n\nputs(response)', }, cli: { method: 'brand retrieve_simplified', - example: "context-dev brand retrieve-simplified \\\n --api-key 'My API Key' \\\n --domain domain", + example: "context-dev brand retrieve-simplified \\\n --api-key 'My API Key' \\\n --domain xxx", }, php: { method: 'brand->retrieveSimplified', example: - "brand->retrieveSimplified(\n domain: 'domain', maxAgeMs: 86400000, timeoutMs: 1000\n);\n\nvar_dump($response);", + "brand->retrieveSimplified(\n domain: 'xxx',\n maxAgeMs: 0,\n tags: ['production', 'team-alpha'],\n theme: 'light',\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: @@ -975,40 +1010,46 @@ const EMBEDDED_METHODS: MethodEntry[] = [ description: 'Classify any brand into 2022 NAICS industry codes from its domain or name.', stainlessPath: '(resource) industry > (method) retrieve_naics', qualified: 'client.industry.retrieveNaics', - params: ['input: string;', 'maxResults?: number;', 'minResults?: number;', 'timeoutMS?: number;'], + params: [ + 'input: string;', + 'maxResults?: number;', + 'minResults?: number;', + 'tags?: string[];', + 'timeoutMS?: number;', + ], response: "{ codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; }[]; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; type?: string; }", markdown: - "## retrieve_naics\n\n`client.industry.retrieveNaics(input: string, maxResults?: number, minResults?: number, timeoutMS?: number): { codes?: object[]; domain?: string; key_metadata?: object; status?: string; type?: string; }`\n\n**get** `/web/naics`\n\nClassify any brand into 2022 NAICS industry codes from its domain or name.\n\n### Parameters\n\n- `input: string`\n Brand domain or title to retrieve NAICS code for. If a valid domain is provided, it will be used for classification, otherwise, we will search for the brand using the provided title.\n\n- `maxResults?: number`\n Maximum number of NAICS codes to return. Must be between 1 and 10. Defaults to 5.\n\n- `minResults?: number`\n Minimum number of NAICS codes to return. Must be at least 1. Defaults to 1.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; }[]; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; type?: string; }`\n\n - `codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; }[]`\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.industry.retrieveNaics({ input: 'input' });\n\nconsole.log(response);\n```", + "## retrieve_naics\n\n`client.industry.retrieveNaics(input: string, maxResults?: number, minResults?: number, tags?: string[], timeoutMS?: number): { codes?: object[]; domain?: string; key_metadata?: object; status?: string; type?: string; }`\n\n**get** `/web/naics`\n\nClassify any brand into 2022 NAICS industry codes from its domain or name.\n\n### Parameters\n\n- `input: string`\n Brand domain or title to retrieve NAICS code for. If a valid domain is provided, it will be used for classification, otherwise, we will search for the brand using the provided title.\n\n- `maxResults?: number`\n Maximum number of NAICS codes to return. Must be between 1 and 10. Defaults to 5.\n\n- `minResults?: number`\n Minimum number of NAICS codes to return. Must be at least 1. Defaults to 1.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; }[]; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; type?: string; }`\n\n - `codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; }[]`\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.industry.retrieveNaics({ input: 'xxxx' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.industry.retrieveNaics', example: - "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.industry.retrieveNaics({ input: 'input' });\n\nconsole.log(response.codes);", + "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.industry.retrieveNaics({ input: 'xxxx' });\n\nconsole.log(response.codes);", }, python: { method: 'industry.retrieve_naics', example: - 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.industry.retrieve_naics(\n input="input",\n)\nprint(response.codes)', + 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.industry.retrieve_naics(\n input="xxxx",\n)\nprint(response.codes)', }, go: { method: 'client.Industry.GetNaics', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Industry.GetNaics(context.TODO(), contextdev.IndustryGetNaicsParams{\n\t\tInput: "input",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Codes)\n}\n', + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Industry.GetNaics(context.TODO(), contextdev.IndustryGetNaicsParams{\n\t\tInput: "xxxx",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Codes)\n}\n', }, ruby: { method: 'industry.retrieve_naics', example: - 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.industry.retrieve_naics(input: "input")\n\nputs(response)', + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.industry.retrieve_naics(input: "xxxx")\n\nputs(response)', }, cli: { method: 'industry retrieve_naics', - example: "context-dev industry retrieve-naics \\\n --api-key 'My API Key' \\\n --input input", + example: "context-dev industry retrieve-naics \\\n --api-key 'My API Key' \\\n --input xxxx", }, php: { method: 'industry->retrieveNaics', example: - "industry->retrieveNaics(\n input: 'input', maxResults: 1, minResults: 1, timeoutMs: 1000\n);\n\nvar_dump($response);", + "industry->retrieveNaics(\n input: 'xxxx',\n maxResults: 1,\n minResults: 1,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: @@ -1029,42 +1070,43 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'input: string;', 'maxResults?: number;', 'minResults?: number;', + 'tags?: string[];', 'timeoutMS?: number;', "type?: 'original_sic' | 'latest_sec';", ], response: "{ classification?: 'original_sic' | 'latest_sec'; codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; majorGroup?: string; majorGroupName?: string; office?: string; }[]; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; type?: string; }", markdown: - "## retrieve_sic\n\n`client.industry.retrieveSic(input: string, maxResults?: number, minResults?: number, timeoutMS?: number, type?: 'original_sic' | 'latest_sec'): { classification?: 'original_sic' | 'latest_sec'; codes?: object[]; domain?: string; key_metadata?: object; status?: string; type?: string; }`\n\n**get** `/web/sic`\n\nClassify any brand into Standard Industrial Classification (SIC) codes from its domain or name. Choose between the original SIC system (`original_sic`) or the latest SIC list maintained by the SEC (`latest_sec`).\n\n### Parameters\n\n- `input: string`\n Brand domain or title to retrieve SIC code for. If a valid domain is provided, it will be used for classification, otherwise, we will search for the brand using the provided title.\n\n- `maxResults?: number`\n Maximum number of SIC codes to return. Must be between 1 and 10. Defaults to 5.\n\n- `minResults?: number`\n Minimum number of SIC codes to return. Must be at least 1. Defaults to 1.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `type?: 'original_sic' | 'latest_sec'`\n Which SIC dataset to classify against. `original_sic` uses the 1987 Standard Industrial Classification system; `latest_sec` uses the current SIC list as published by the SEC. Defaults to `original_sic`.\n\n### Returns\n\n- `{ classification?: 'original_sic' | 'latest_sec'; codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; majorGroup?: string; majorGroupName?: string; office?: string; }[]; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; type?: string; }`\n\n - `classification?: 'original_sic' | 'latest_sec'`\n - `codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; majorGroup?: string; majorGroupName?: string; office?: string; }[]`\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.industry.retrieveSic({ input: 'input' });\n\nconsole.log(response);\n```", + "## retrieve_sic\n\n`client.industry.retrieveSic(input: string, maxResults?: number, minResults?: number, tags?: string[], timeoutMS?: number, type?: 'original_sic' | 'latest_sec'): { classification?: 'original_sic' | 'latest_sec'; codes?: object[]; domain?: string; key_metadata?: object; status?: string; type?: string; }`\n\n**get** `/web/sic`\n\nClassify any brand into Standard Industrial Classification (SIC) codes from its domain or name. Choose between the original SIC system (`original_sic`) or the latest SIC list maintained by the SEC (`latest_sec`).\n\n### Parameters\n\n- `input: string`\n Brand domain or title to retrieve SIC code for. If a valid domain is provided, it will be used for classification, otherwise, we will search for the brand using the provided title.\n\n- `maxResults?: number`\n Maximum number of SIC codes to return. Must be between 1 and 10. Defaults to 5.\n\n- `minResults?: number`\n Minimum number of SIC codes to return. Must be at least 1. Defaults to 1.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `type?: 'original_sic' | 'latest_sec'`\n Which SIC dataset to classify against. `original_sic` uses the 1987 Standard Industrial Classification system; `latest_sec` uses the current SIC list as published by the SEC. Defaults to `original_sic`.\n\n### Returns\n\n- `{ classification?: 'original_sic' | 'latest_sec'; codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; majorGroup?: string; majorGroupName?: string; office?: string; }[]; domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; status?: string; type?: string; }`\n\n - `classification?: 'original_sic' | 'latest_sec'`\n - `codes?: { code: string; confidence: 'high' | 'medium' | 'low'; name: string; majorGroup?: string; majorGroupName?: string; office?: string; }[]`\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `status?: string`\n - `type?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.industry.retrieveSic({ input: 'xxxx' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.industry.retrieveSic', example: - "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.industry.retrieveSic({ input: 'input' });\n\nconsole.log(response.classification);", + "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.industry.retrieveSic({ input: 'xxxx' });\n\nconsole.log(response.classification);", }, python: { method: 'industry.retrieve_sic', example: - 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.industry.retrieve_sic(\n input="input",\n)\nprint(response.classification)', + 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.industry.retrieve_sic(\n input="xxxx",\n)\nprint(response.classification)', }, go: { method: 'client.Industry.GetSic', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Industry.GetSic(context.TODO(), contextdev.IndustryGetSicParams{\n\t\tInput: "input",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Classification)\n}\n', + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Industry.GetSic(context.TODO(), contextdev.IndustryGetSicParams{\n\t\tInput: "xxxx",\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Classification)\n}\n', }, ruby: { method: 'industry.retrieve_sic', example: - 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.industry.retrieve_sic(input: "input")\n\nputs(response)', + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.industry.retrieve_sic(input: "xxxx")\n\nputs(response)', }, cli: { method: 'industry retrieve_sic', - example: "context-dev industry retrieve-sic \\\n --api-key 'My API Key' \\\n --input input", + example: "context-dev industry retrieve-sic \\\n --api-key 'My API Key' \\\n --input xxxx", }, php: { method: 'industry->retrieveSic', example: - "industry->retrieveSic(\n input: 'input',\n maxResults: 1,\n minResults: 1,\n timeoutMs: 1000,\n type: 'original_sic',\n);\n\nvar_dump($response);", + "industry->retrieveSic(\n input: 'xxxx',\n maxResults: 1,\n minResults: 1,\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n type: 'original_sic',\n);\n\nvar_dump($response);", }, http: { example: @@ -1084,46 +1126,47 @@ const EMBEDDED_METHODS: MethodEntry[] = [ params: [ 'identifier: { domain: string; } | { email: string; };', "type: 'brand';", + 'tags?: string[];', 'timeoutMS?: number;', ], response: "{ domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; message?: string; status?: string; type?: 'brand'; }", markdown: - "## prefetch\n\n`client.utility.prefetch(identifier: { domain: string; } | { email: string; }, type: 'brand', timeoutMS?: number): { domain?: string; key_metadata?: object; message?: string; status?: string; type?: 'brand'; }`\n\n**post** `/utility/prefetch`\n\nSignal that you may fetch brand data soon to improve latency. The type field selects what to prefetch (currently only 'brand') and identifier carries exactly one lookup key: a domain, or an email whose domain is extracted and validated (free email providers and disposable email addresses are not allowed).\n\n### Parameters\n\n- `identifier: { domain: string; } | { email: string; }`\n Identifier of the brand to prefetch. Provide exactly one of domain or email.\n\n- `type: 'brand'`\n What to prefetch. Currently only 'brand' is supported.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; message?: string; status?: string; type?: 'brand'; }`\n\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `message?: string`\n - `status?: string`\n - `type?: 'brand'`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.utility.prefetch({\n identifier: { domain: 'domain' },\n type: 'brand',\n});\n\nconsole.log(response);\n```", + "## prefetch\n\n`client.utility.prefetch(identifier: { domain: string; } | { email: string; }, type: 'brand', tags?: string[], timeoutMS?: number): { domain?: string; key_metadata?: object; message?: string; status?: string; type?: 'brand'; }`\n\n**post** `/utility/prefetch`\n\nSignal that you may fetch brand data soon to improve latency. The type field selects what to prefetch (currently only 'brand') and identifier carries exactly one lookup key: a domain, or an email whose domain is extracted and validated (free email providers and disposable email addresses are not allowed).\n\n### Parameters\n\n- `identifier: { domain: string; } | { email: string; }`\n Identifier of the brand to prefetch. Provide exactly one of domain or email.\n\n- `type: 'brand'`\n What to prefetch. Currently only 'brand' is supported.\n\n- `tags?: string[]`\n Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n### Returns\n\n- `{ domain?: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; message?: string; status?: string; type?: 'brand'; }`\n\n - `domain?: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `message?: string`\n - `status?: string`\n - `type?: 'brand'`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.utility.prefetch({\n identifier: { domain: 'xxx' },\n type: 'brand',\n});\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.utility.prefetch', example: - "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.utility.prefetch({\n identifier: { domain: 'domain' },\n type: 'brand',\n});\n\nconsole.log(response.domain);", + "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.utility.prefetch({\n identifier: { domain: 'xxx' },\n type: 'brand',\n});\n\nconsole.log(response.domain);", }, python: { method: 'utility.prefetch', example: - 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.utility.prefetch(\n identifier={\n "domain": "domain"\n },\n type="brand",\n)\nprint(response.domain)', + 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.utility.prefetch(\n identifier={\n "domain": "xxx"\n },\n type="brand",\n)\nprint(response.domain)', }, go: { method: 'client.Utility.Prefetch', example: - 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Utility.Prefetch(context.TODO(), contextdev.UtilityPrefetchParams{\n\t\tIdentifier: contextdev.UtilityPrefetchParamsIdentifierUnion{\n\t\t\tOfByDomain: &contextdev.UtilityPrefetchParamsIdentifierByDomain{\n\t\t\t\tDomain: "domain",\n\t\t\t},\n\t\t},\n\t\tType: contextdev.UtilityPrefetchParamsTypeBrand,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Domain)\n}\n', + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Utility.Prefetch(context.TODO(), contextdev.UtilityPrefetchParams{\n\t\tIdentifier: contextdev.UtilityPrefetchParamsIdentifierUnion{\n\t\t\tOfByDomain: &contextdev.UtilityPrefetchParamsIdentifierByDomain{\n\t\t\t\tDomain: "xxx",\n\t\t\t},\n\t\t},\n\t\tType: contextdev.UtilityPrefetchParamsTypeBrand,\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Domain)\n}\n', }, ruby: { method: 'utility.prefetch', example: - 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.utility.prefetch(identifier: {domain: "domain"}, type: :brand)\n\nputs(response)', + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.utility.prefetch(identifier: {domain: "xxx"}, type: :brand)\n\nputs(response)', }, cli: { method: 'utility prefetch', example: - "context-dev utility prefetch \\\n --api-key 'My API Key' \\\n --identifier '{domain: domain}' \\\n --type brand", + "context-dev utility prefetch \\\n --api-key 'My API Key' \\\n --identifier '{domain: xxx}' \\\n --type brand", }, php: { method: 'utility->prefetch', example: - "utility->prefetch(\n identifier: ['domain' => 'domain'], type: 'brand', timeoutMs: 1000\n);\n\nvar_dump($response);", + "utility->prefetch(\n identifier: ['domain' => 'xxx'],\n type: 'brand',\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", }, http: { example: - 'curl https://api.context.dev/v1/utility/prefetch \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "identifier": {\n "domain": "domain"\n },\n "type": "brand"\n }\'', + 'curl https://api.context.dev/v1/utility/prefetch \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "identifier": {\n "domain": "xxx"\n },\n "type": "brand",\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', }, }, }, @@ -1148,7 +1191,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: "{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }", markdown: - "## create\n\n`client.monitors.create(change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, name: string, schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, mode?: 'web', tags?: string[], webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**post** `/monitors`\n\nCreates a monitor. The request body is a union of the supported target/change detection combinations. The monitor runs immediately after creation to create its initial baseline.\n\n### Parameters\n\n- `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `name: string`\n\n- `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `mode?: 'web'`\n Top-level monitor category. Always `web` today; the concrete behavior is described by `target` and `change_detection`.\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.create({\n change_detection: { type: 'exact' },\n name: 'Acme pricing page',\n schedule: {\n frequency: 6,\n type: 'interval',\n unit: 'hours',\n},\n target: { type: 'page', url: 'https://acme.com/pricing' },\n});\n\nconsole.log(monitor);\n```", + "## create\n\n`client.monitors.create(change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, name: string, schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, mode?: 'web', tags?: string[], webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**post** `/monitors`\n\nCreates a monitor. The request body is a union of the supported target/change detection combinations. The monitor runs immediately after creation to create its initial baseline.\n\n### Parameters\n\n- `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `name: string`\n\n- `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `mode?: 'web'`\n Top-level monitor category. Always `web` today; the concrete behavior is described by `target` and `change_detection`.\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes. Duplicates are removed.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.create({\n change_detection: { type: 'exact' },\n name: 'Acme pricing page',\n schedule: {\n frequency: 6,\n type: 'interval',\n unit: 'hours',\n},\n target: { type: 'page', url: 'https://acme.com/pricing' },\n});\n\nconsole.log(monitor);\n```", perLanguage: { typescript: { method: 'client.monitors.create', @@ -1210,7 +1253,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: "{ data: { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }[]; has_more: boolean; next_cursor: string; }", markdown: - "## list\n\n`client.monitors.list(change_detection_type?: 'exact' | 'semantic', cursor?: string, limit?: number, q?: string, search_by?: 'name' | 'url' | 'instructions' | 'tags'[], search_type?: 'exact' | 'prefix', status?: 'active' | 'paused' | 'failed', tag?: string, tags?: string[], target_type?: 'page' | 'sitemap' | 'extract'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors`\n\nLists monitors for the authenticated organization. Supports free-text search (`q` over `search_by` fields, `prefix` or `exact` via `search_type`) plus status/type/tag filters. Results are paginated via the opaque `cursor`.\n\n### Parameters\n\n- `change_detection_type?: 'exact' | 'semantic'`\n\n- `cursor?: string`\n\n- `limit?: number`\n\n- `q?: string`\n Free-text search term, matched against the fields named in `search_by`.\n\n- `search_by?: 'name' | 'url' | 'instructions' | 'tags'[]`\n Comma-separated fields to search with `q`. Defaults to all of them. Note `instructions` only exists on extract monitors.\n\n- `search_type?: 'exact' | 'prefix'`\n `prefix` for as-you-type prefix matching (default), `exact` for full-token matching.\n\n- `status?: 'active' | 'paused' | 'failed'`\n Monitor lifecycle status. `failed` means the most recent run failed (see the monitor's `last_error`); failed monitors keep running on schedule and flip back to `active` on the next successful run. Monitors are auto-`paused` after repeated consecutive failures or insufficient-credit skips; resume by PATCHing status to `active`.\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `tags?: string[]`\n Comma-separated list of tags to filter by (matches monitors having any of them).\n\n- `target_type?: 'page' | 'sitemap' | 'extract'`\n\n### Returns\n\n- `{ data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitors = await client.monitors.list();\n\nconsole.log(monitors);\n```", + "## list\n\n`client.monitors.list(change_detection_type?: 'exact' | 'semantic', cursor?: string, limit?: number, q?: string, search_by?: 'name' | 'url' | 'instructions' | 'tags'[], search_type?: 'exact' | 'prefix', status?: 'active' | 'paused' | 'failed', tag?: string, tags?: string[], target_type?: 'page' | 'sitemap' | 'extract'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors`\n\nLists monitors for the authenticated organization. Supports free-text search (`q` over `search_by` fields, `prefix` or `exact` via `search_type`) plus status/type/tag filters. Results are paginated via the opaque `cursor`.\n\n### Parameters\n\n- `change_detection_type?: 'exact' | 'semantic'`\n Filter by change detection type.\n\n- `cursor?: string`\n Opaque pagination cursor from a previous response.\n\n- `limit?: number`\n Maximum number of items to return per page (1-100). Defaults to 25.\n\n- `q?: string`\n Free-text search term, matched against the fields named in `search_by`.\n\n- `search_by?: 'name' | 'url' | 'instructions' | 'tags'[]`\n Comma-separated fields to search with `q`. Defaults to all of them. Note `instructions` only exists on extract monitors.\n\n- `search_type?: 'exact' | 'prefix'`\n `prefix` for as-you-type prefix matching (default), `exact` for full-token matching.\n\n- `status?: 'active' | 'paused' | 'failed'`\n Filter monitors by lifecycle status.\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `tags?: string[]`\n Comma-separated list of tags to filter by (matches monitors having any of them).\n\n- `target_type?: 'page' | 'sitemap' | 'extract'`\n Filter by target type.\n\n### Returns\n\n- `{ data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitors = await client.monitors.list();\n\nconsole.log(monitors);\n```", perLanguage: { typescript: { method: 'client.monitors.list', @@ -1239,7 +1282,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'monitors->list', example: - "monitors->list(\n changeDetectionType: 'exact',\n cursor: 'cursor',\n limit: 1,\n q: 'q',\n searchBy: ['name'],\n searchType: 'exact',\n status: 'active',\n tag: 'tag',\n tags: ['string'],\n targetType: 'page',\n);\n\nvar_dump($monitors);", + "monitors->list(\n changeDetectionType: 'exact',\n cursor: 'cursor',\n limit: 1,\n q: 'pricing',\n searchBy: ['name'],\n searchType: 'exact',\n status: 'active',\n tag: 'pricing',\n tags: ['x'],\n targetType: 'page',\n);\n\nvar_dump($monitors);", }, http: { example: @@ -1318,7 +1361,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: "{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }", markdown: - "## update\n\n`client.monitors.update(monitor_id: string, change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, name?: string, schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, status?: 'active' | 'paused', tags?: string[], target?: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**patch** `/monitors/{monitor_id}`\n\nUpdates a monitor. If `target` or `change_detection` changes, the monitor creates a new baseline. Unsupported target/change detection combinations are rejected.\n\n### Parameters\n\n- `monitor_id: string`\n\n- `change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `name?: string`\n\n- `schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `status?: 'active' | 'paused'`\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes.\n\n- `target?: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n Set to null to remove the webhook.\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.update('mon_123');\n\nconsole.log(monitor);\n```", + "## update\n\n`client.monitors.update(monitor_id: string, change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, name?: string, schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, status?: 'active' | 'paused', tags?: string[], target?: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**patch** `/monitors/{monitor_id}`\n\nUpdates a monitor. If `target` or `change_detection` changes, the monitor creates a new baseline. Unsupported target/change detection combinations are rejected.\n\n### Parameters\n\n- `monitor_id: string`\n\n- `change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `name?: string`\n\n- `schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `status?: 'active' | 'paused'`\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes. Duplicates are removed.\n\n- `target?: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n Set to null to remove the webhook.\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.update('mon_123');\n\nconsole.log(monitor);\n```", perLanguage: { typescript: { method: 'client.monitors.update', @@ -1469,7 +1512,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: "{ data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: object[]; webhook_delivery?: object; }[]; has_more: boolean; next_cursor: string; }", markdown: - "## list_runs\n\n`client.monitors.listRuns(monitor_id: string, cursor?: string, limit?: number, status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/{monitor_id}/runs`\n\nList monitor runs\n\n### Parameters\n\n- `monitor_id: string`\n\n- `cursor?: string`\n\n- `limit?: number`\n\n- `status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'`\n Lifecycle status of a run. `skipped` runs never executed — see `skip_reason` (insufficient credits, monitor paused, or superseded by a concurrent run).\n\n### Returns\n\n- `{ data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: object[]; webhook_delivery?: object; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }[]; webhook_delivery?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listRuns('mon_123');\n\nconsole.log(response);\n```", + "## list_runs\n\n`client.monitors.listRuns(monitor_id: string, cursor?: string, limit?: number, status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/{monitor_id}/runs`\n\nList monitor runs\n\n### Parameters\n\n- `monitor_id: string`\n\n- `cursor?: string`\n Opaque pagination cursor from a previous response.\n\n- `limit?: number`\n Maximum number of items to return per page (1-100). Defaults to 25.\n\n- `status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'`\n Filter runs by lifecycle status.\n\n### Returns\n\n- `{ data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: object[]; webhook_delivery?: object; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }[]; webhook_delivery?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listRuns('mon_123');\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.monitors.listRuns', @@ -1525,7 +1568,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: "{ data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]; has_more: boolean; next_cursor: string; }", markdown: - "## list_changes\n\n`client.monitors.listChanges(monitor_id: string, cursor?: string, limit?: number, since?: string, tag?: string, until?: string): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/{monitor_id}/changes`\n\nList changes for a monitor\n\n### Parameters\n\n- `monitor_id: string`\n\n- `cursor?: string`\n\n- `limit?: number`\n\n- `since?: string`\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `until?: string`\n\n### Returns\n\n- `{ data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listChanges('mon_123');\n\nconsole.log(response);\n```", + "## list_changes\n\n`client.monitors.listChanges(monitor_id: string, cursor?: string, limit?: number, since?: string, tag?: string, until?: string): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/{monitor_id}/changes`\n\nList changes for a monitor\n\n### Parameters\n\n- `monitor_id: string`\n\n- `cursor?: string`\n Opaque pagination cursor from a previous response.\n\n- `limit?: number`\n Maximum number of items to return per page (1-100). Defaults to 25.\n\n- `since?: string`\n Only include items at or after this ISO 8601 timestamp.\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `until?: string`\n Only include items before this ISO 8601 timestamp.\n\n### Returns\n\n- `{ data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listChanges('mon_123');\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.monitors.listChanges', @@ -1554,7 +1597,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'monitors->listChanges', example: - "monitors->listChanges(\n 'mon_123',\n cursor: 'cursor',\n limit: 1,\n since: new \\DateTimeImmutable('2019-12-27T18:11:19.117Z'),\n tag: 'tag',\n until: new \\DateTimeImmutable('2019-12-27T18:11:19.117Z'),\n);\n\nvar_dump($response);", + "monitors->listChanges(\n 'mon_123',\n cursor: 'cursor',\n limit: 1,\n since: new \\DateTimeImmutable('2026-06-01T00:00:00Z'),\n tag: 'pricing',\n until: new \\DateTimeImmutable('2026-06-28T00:00:00Z'),\n);\n\nvar_dump($response);", }, http: { example: @@ -1578,7 +1621,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: "{ data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: object[]; webhook_delivery?: object; }[]; has_more: boolean; next_cursor: string; }", markdown: - "## list_account_runs\n\n`client.monitors.listAccountRuns(cursor?: string, limit?: number, status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/runs`\n\nReturns an account-wide feed of monitor runs across all monitors.\n\n### Parameters\n\n- `cursor?: string`\n\n- `limit?: number`\n\n- `status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'`\n Lifecycle status of a run. `skipped` runs never executed — see `skip_reason` (insufficient credits, monitor paused, or superseded by a concurrent run).\n\n### Returns\n\n- `{ data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: object[]; webhook_delivery?: object; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }[]; webhook_delivery?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listAccountRuns();\n\nconsole.log(response);\n```", + "## list_account_runs\n\n`client.monitors.listAccountRuns(cursor?: string, limit?: number, status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/runs`\n\nReturns an account-wide feed of monitor runs across all monitors.\n\n### Parameters\n\n- `cursor?: string`\n Opaque pagination cursor from a previous response.\n\n- `limit?: number`\n Maximum number of items to return per page (1-100). Defaults to 25.\n\n- `status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'`\n Filter runs by lifecycle status.\n\n### Returns\n\n- `{ data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: object[]; webhook_delivery?: object; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; baseline_created: boolean; change_detected: boolean; change_detection_type: 'exact' | 'semantic'; credits_charged: number; monitor_id: string; run_type: 'baseline' | 'scheduled'; status: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; target_type: 'page' | 'sitemap' | 'extract'; change_id?: string; completed_at?: string; error?: { code: string; message: string; }; skip_reason?: 'insufficient_credits' | 'monitor_paused' | 'superseded'; started_at?: string; webhook_deliveries?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }[]; webhook_delivery?: { attempted_at: string; error: { code: string; message: string; }; event: 'change.detected' | 'run.completed'; event_id: string; http_status: number; status: 'delivered' | 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listAccountRuns();\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.monitors.listAccountRuns', @@ -1636,7 +1679,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: "{ data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]; has_more: boolean; next_cursor: string; }", markdown: - "## list_account_changes\n\n`client.monitors.listAccountChanges(change_detection_type?: 'exact' | 'semantic', cursor?: string, limit?: number, monitor_id?: string, since?: string, tag?: string, target_type?: 'page' | 'sitemap' | 'extract', until?: string): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/changes`\n\nReturns an account-wide feed of detected changes across monitors.\n\n### Parameters\n\n- `change_detection_type?: 'exact' | 'semantic'`\n\n- `cursor?: string`\n\n- `limit?: number`\n\n- `monitor_id?: string`\n\n- `since?: string`\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `target_type?: 'page' | 'sitemap' | 'extract'`\n\n- `until?: string`\n\n### Returns\n\n- `{ data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listAccountChanges();\n\nconsole.log(response);\n```", + "## list_account_changes\n\n`client.monitors.listAccountChanges(change_detection_type?: 'exact' | 'semantic', cursor?: string, limit?: number, monitor_id?: string, since?: string, tag?: string, target_type?: 'page' | 'sitemap' | 'extract', until?: string): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors/changes`\n\nReturns an account-wide feed of detected changes across monitors.\n\n### Parameters\n\n- `change_detection_type?: 'exact' | 'semantic'`\n Filter by change detection type.\n\n- `cursor?: string`\n Opaque pagination cursor from a previous response.\n\n- `limit?: number`\n Maximum number of items to return per page (1-100). Defaults to 25.\n\n- `monitor_id?: string`\n Filter changes to a single monitor.\n\n- `since?: string`\n Only include items at or after this ISO 8601 timestamp.\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `target_type?: 'page' | 'sitemap' | 'extract'`\n Filter by target type.\n\n- `until?: string`\n Only include items before this ISO 8601 timestamp.\n\n### Returns\n\n- `{ data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection_type: 'exact' | 'semantic'; detected_at: string; mode: 'web'; monitor_id: string; summary: string; target_type: 'page' | 'sitemap' | 'extract'; title: string; url: string; added_url_count?: number; confidence?: number; importance?: 'low' | 'medium' | 'high'; matched_url_count?: number; removed_url_count?: number; tags?: string[]; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.listAccountChanges();\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.monitors.listAccountChanges', @@ -1665,7 +1708,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'monitors->listAccountChanges', example: - "monitors->listAccountChanges(\n changeDetectionType: 'exact',\n cursor: 'cursor',\n limit: 1,\n monitorID: 'monitor_id',\n since: new \\DateTimeImmutable('2019-12-27T18:11:19.117Z'),\n tag: 'tag',\n targetType: 'page',\n until: new \\DateTimeImmutable('2019-12-27T18:11:19.117Z'),\n);\n\nvar_dump($response);", + "monitors->listAccountChanges(\n changeDetectionType: 'exact',\n cursor: 'cursor',\n limit: 1,\n monitorID: 'mon_123',\n since: new \\DateTimeImmutable('2026-06-01T00:00:00Z'),\n tag: 'pricing',\n targetType: 'page',\n until: new \\DateTimeImmutable('2026-06-28T00:00:00Z'),\n);\n\nvar_dump($response);", }, http: { example: @@ -1723,6 +1766,104 @@ const EMBEDDED_METHODS: MethodEntry[] = [ }, }, }, + { + name: 'get_credit_usage', + endpoint: '/monitors/credit-usage', + httpMethod: 'get', + summary: 'Monitor credit usage', + description: + 'Returns credits charged per monitor over an optional [since, until] window, newest spenders first.', + stainlessPath: '(resource) monitors > (method) get_credit_usage', + qualified: 'client.monitors.getCreditUsage', + params: ['since?: string;', 'until?: string;'], + response: + '{ data: { credits: number; monitor_id: string; name: string; runs: number; }[]; total_credits: number; }', + markdown: + "## get_credit_usage\n\n`client.monitors.getCreditUsage(since?: string, until?: string): { data: object[]; total_credits: number; }`\n\n**get** `/monitors/credit-usage`\n\nReturns credits charged per monitor over an optional [since, until] window, newest spenders first.\n\n### Parameters\n\n- `since?: string`\n Only include items at or after this ISO 8601 timestamp.\n\n- `until?: string`\n Only include items before this ISO 8601 timestamp.\n\n### Returns\n\n- `{ data: { credits: number; monitor_id: string; name: string; runs: number; }[]; total_credits: number; }`\n\n - `data: { credits: number; monitor_id: string; name: string; runs: number; }[]`\n - `total_credits: number`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.getCreditUsage();\n\nconsole.log(response);\n```", + perLanguage: { + typescript: { + method: 'client.monitors.getCreditUsage', + example: + "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.monitors.getCreditUsage();\n\nconsole.log(response.data);", + }, + python: { + method: 'monitors.get_credit_usage', + example: + 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.monitors.get_credit_usage()\nprint(response.data)', + }, + go: { + method: 'client.Monitors.GetCreditUsage', + example: + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Monitors.GetCreditUsage(context.TODO(), contextdev.MonitorGetCreditUsageParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Data)\n}\n', + }, + ruby: { + method: 'monitors.get_credit_usage', + example: + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.monitors.get_credit_usage\n\nputs(response)', + }, + cli: { + method: 'monitors get_credit_usage', + example: "context-dev monitors get-credit-usage \\\n --api-key 'My API Key'", + }, + php: { + method: 'monitors->getCreditUsage', + example: + "monitors->getCreditUsage(\n since: new \\DateTimeImmutable('2026-06-01T00:00:00Z'),\n until: new \\DateTimeImmutable('2026-06-28T00:00:00Z'),\n);\n\nvar_dump($response);", + }, + http: { + example: + 'curl https://api.context.dev/v1/monitors/credit-usage \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY"', + }, + }, + }, + { + name: 'get_limits', + endpoint: '/monitors/limits', + httpMethod: 'get', + summary: 'Monitor limits', + description: 'Returns how many monitors the account has and the maximum it allows.', + stainlessPath: '(resource) monitors > (method) get_limits', + qualified: 'client.monitors.getLimits', + response: + "{ monitors_limit: number; monitors_used: number; plan: 'free' | 'starter' | 'pro' | 'scale'; }", + markdown: + "## get_limits\n\n`client.monitors.getLimits(): { monitors_limit: number; monitors_used: number; plan: 'free' | 'starter' | 'pro' | 'scale'; }`\n\n**get** `/monitors/limits`\n\nReturns how many monitors the account has and the maximum it allows.\n\n### Returns\n\n- `{ monitors_limit: number; monitors_used: number; plan: 'free' | 'starter' | 'pro' | 'scale'; }`\n\n - `monitors_limit: number`\n - `monitors_used: number`\n - `plan: 'free' | 'starter' | 'pro' | 'scale'`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.monitors.getLimits();\n\nconsole.log(response);\n```", + perLanguage: { + typescript: { + method: 'client.monitors.getLimits', + example: + "import ContextDev from 'context.dev';\n\nconst client = new ContextDev({\n apiKey: process.env['CONTEXT_DEV_API_KEY'], // This is the default and can be omitted\n});\n\nconst response = await client.monitors.getLimits();\n\nconsole.log(response.monitors_limit);", + }, + python: { + method: 'monitors.get_limits', + example: + 'import os\nfrom context.dev import ContextDev\n\nclient = ContextDev(\n api_key=os.environ.get("CONTEXT_DEV_API_KEY"), # This is the default and can be omitted\n)\nresponse = client.monitors.get_limits()\nprint(response.monitors_limit)', + }, + go: { + method: 'client.Monitors.GetLimits', + example: + 'package main\n\nimport (\n\t"context"\n\t"fmt"\n\n\t"github.com/context-dot-dev/context-go-sdk"\n\t"github.com/context-dot-dev/context-go-sdk/option"\n)\n\nfunc main() {\n\tclient := contextdev.NewClient(\n\t\toption.WithAPIKey("My API Key"),\n\t)\n\tresponse, err := client.Monitors.GetLimits(context.TODO())\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.MonitorsLimit)\n}\n', + }, + ruby: { + method: 'monitors.get_limits', + example: + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.monitors.get_limits\n\nputs(response)', + }, + cli: { + method: 'monitors get_limits', + example: "context-dev monitors get-limits \\\n --api-key 'My API Key'", + }, + php: { + method: 'monitors->getLimits', + example: + "monitors->getLimits();\n\nvar_dump($response);", + }, + http: { + example: + 'curl https://api.context.dev/v1/monitors/limits \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY"', + }, + }, + }, ]; const EMBEDDED_READMES: { language: string; content: string }[] = [ diff --git a/packages/mcp-server/src/methods.ts b/packages/mcp-server/src/methods.ts index 79946be..2099187 100644 --- a/packages/mcp-server/src/methods.ts +++ b/packages/mcp-server/src/methods.ts @@ -154,6 +154,18 @@ export const sdkMethods: SdkMethod[] = [ httpMethod: 'delete', httpPath: '/monitors/{monitor_id}', }, + { + clientCallName: 'client.monitors.getCreditUsage', + fullyQualifiedName: 'monitors.getCreditUsage', + httpMethod: 'get', + httpPath: '/monitors/credit-usage', + }, + { + clientCallName: 'client.monitors.getLimits', + fullyQualifiedName: 'monitors.getLimits', + httpMethod: 'get', + httpPath: '/monitors/limits', + }, { clientCallName: 'client.monitors.listAccountChanges', fullyQualifiedName: 'monitors.listAccountChanges', diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index 0aeaf26..a954c9b 100644 --- a/packages/mcp-server/src/server.ts +++ b/packages/mcp-server/src/server.ts @@ -28,7 +28,7 @@ export const newMcpServer = async ({ new McpServer( { name: 'context_dev_api', - version: '2.5.0', + version: '2.6.0', }, { instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }), diff --git a/src/client.ts b/src/client.ts index 142e080..14f5c7e 100644 --- a/src/client.ts +++ b/src/client.ts @@ -42,6 +42,9 @@ import { MonitorCreateParams, MonitorCreateResponse, MonitorDeleteResponse, + MonitorGetCreditUsageParams, + MonitorGetCreditUsageResponse, + MonitorGetLimitsResponse, MonitorListAccountChangesParams, MonitorListAccountChangesResponse, MonitorListAccountRunsParams, @@ -897,6 +900,8 @@ export declare namespace ContextDev { type MonitorUpdateResponse as MonitorUpdateResponse, type MonitorListResponse as MonitorListResponse, type MonitorDeleteResponse as MonitorDeleteResponse, + type MonitorGetCreditUsageResponse as MonitorGetCreditUsageResponse, + type MonitorGetLimitsResponse as MonitorGetLimitsResponse, type MonitorListAccountChangesResponse as MonitorListAccountChangesResponse, type MonitorListAccountRunsResponse as MonitorListAccountRunsResponse, type MonitorListChangesResponse as MonitorListChangesResponse, @@ -906,6 +911,7 @@ export declare namespace ContextDev { type MonitorCreateParams as MonitorCreateParams, type MonitorUpdateParams as MonitorUpdateParams, type MonitorListParams as MonitorListParams, + type MonitorGetCreditUsageParams as MonitorGetCreditUsageParams, type MonitorListAccountChangesParams as MonitorListAccountChangesParams, type MonitorListAccountRunsParams as MonitorListAccountRunsParams, type MonitorListChangesParams as MonitorListChangesParams, diff --git a/src/resources/ai.ts b/src/resources/ai.ts index e14b6da..f8d03b1 100644 --- a/src/resources/ai.ts +++ b/src/resources/ai.ts @@ -8,6 +8,13 @@ export class AI extends APIResource { /** * Given a single URL, determines if it is a product page and extracts the product * information. + * + * @example + * ```ts + * const response = await client.ai.extractProduct({ + * url: 'https://example.com', + * }); + * ``` */ extractProduct( body: AIExtractProductParams, @@ -20,6 +27,13 @@ export class AI extends APIResource { * Extract product information from a brand's website. We will analyze the website * and return a list of products with details such as name, description, image, * pricing, features, and more. + * + * @example + * ```ts + * const response = await client.ai.extractProducts({ + * domain: 'domain', + * }); + * ``` */ extractProducts( body: AIExtractProductsParams, @@ -261,6 +275,11 @@ export interface AIExtractProductParams { */ maxAgeMs?: number; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -290,6 +309,11 @@ export declare namespace AIExtractProductsParams { */ maxProducts?: number; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -317,6 +341,11 @@ export declare namespace AIExtractProductsParams { */ maxProducts?: number; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed diff --git a/src/resources/brand.ts b/src/resources/brand.ts index 6a95ddc..c27b7ba 100644 --- a/src/resources/brand.ts +++ b/src/resources/brand.ts @@ -32,7 +32,7 @@ export class Brand extends APIResource { * @example * ```ts * const response = await client.brand.retrieveSimplified({ - * domain: 'domain', + * domain: 'xxx', * }); * ``` */ @@ -128,8 +128,7 @@ export namespace BrandRetrieveResponse { phone?: string; /** - * The primary language of the brand's website content. Detected from the HTML lang - * tag, page content analysis, or social media descriptions. + * Language to force for the retrieved brand data. */ primary_language?: | 'afrikaans' @@ -475,7 +474,6 @@ export namespace BrandRetrieveResponse { | 'Streaming Platforms (Video, Music, Audio)' | 'Gaming & Interactive Entertainment' | 'Creator Economy & Influencer Platforms' - | 'Advertising, Adtech & Media Buying' | 'Film, TV & Production Studios' | 'Events, Venues & Live Entertainment' | 'Virtual Worlds & Metaverse Experiences' @@ -536,6 +534,7 @@ export namespace BrandRetrieveResponse { | 'Streetwear & Emerging Luxury' | 'Couture & Made-to-Measure' | 'News Publishing & Journalism' + | 'Advertising, Adtech & Media Buying' | 'Digital Media & Content Platforms' | 'Broadcasting (TV & Radio)' | 'Podcasting & Audio Media' @@ -1162,7 +1161,8 @@ export declare namespace BrandRetrieveParams { | 'xhosa' | 'yiddish' | 'yoruba' - | 'zulu'; + | 'zulu' + | null; /** * Maximum age in milliseconds for cached brand data before the API performs a hard @@ -1179,6 +1179,11 @@ export declare namespace BrandRetrieveParams { */ maxSpeed?: boolean; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -1324,7 +1329,8 @@ export declare namespace BrandRetrieveParams { | 'xhosa' | 'yiddish' | 'yoruba' - | 'zulu'; + | 'zulu' + | null; /** * Maximum age in milliseconds for cached brand data before the API performs a hard @@ -1341,6 +1347,11 @@ export declare namespace BrandRetrieveParams { */ maxSpeed?: boolean; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -1480,7 +1491,8 @@ export declare namespace BrandRetrieveParams { | 'xhosa' | 'yiddish' | 'yoruba' - | 'zulu'; + | 'zulu' + | null; /** * Maximum age in milliseconds for cached brand data before the API performs a hard @@ -1497,6 +1509,11 @@ export declare namespace BrandRetrieveParams { */ maxSpeed?: boolean; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -1636,7 +1653,8 @@ export declare namespace BrandRetrieveParams { | 'xhosa' | 'yiddish' | 'yoruba' - | 'zulu'; + | 'zulu' + | null; /** * Maximum age in milliseconds for cached brand data before the API performs a hard @@ -1653,6 +1671,11 @@ export declare namespace BrandRetrieveParams { */ maxSpeed?: boolean; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional stock exchange for the ticker. Defaults to NASDAQ if not specified. */ @@ -1679,6 +1702,11 @@ export declare namespace BrandRetrieveParams { */ type: 'by_direct_url'; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -1829,7 +1857,8 @@ export declare namespace BrandRetrieveParams { | 'xhosa' | 'yiddish' | 'yoruba' - | 'zulu'; + | 'zulu' + | null; /** * When set to true, the API performs additional verification to ensure the @@ -1848,12 +1877,17 @@ export declare namespace BrandRetrieveParams { * Optional Merchant Category Code (MCC) to help identify the business category or * industry. */ - mcc?: number; + mcc?: string | number; /** * Optional phone number from the transaction to help verify brand match. */ - phone?: number; + phone?: string | number; + + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; /** * Optional timeout in milliseconds for the request. If the request takes longer @@ -1876,7 +1910,19 @@ export interface BrandRetrieveSimplifiedParams { * are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 * year. */ - maxAgeMs?: number; + maxAgeMs?: number | null; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; + + /** + * Optional theme preference used when selecting brand assets. + */ + theme?: 'light' | 'dark'; /** * Optional timeout in milliseconds for the request. If the request takes longer diff --git a/src/resources/index.ts b/src/resources/index.ts index 9da6825..fe1b275 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -29,6 +29,8 @@ export { type MonitorUpdateResponse, type MonitorListResponse, type MonitorDeleteResponse, + type MonitorGetCreditUsageResponse, + type MonitorGetLimitsResponse, type MonitorListAccountChangesResponse, type MonitorListAccountRunsResponse, type MonitorListChangesResponse, @@ -38,6 +40,7 @@ export { type MonitorCreateParams, type MonitorUpdateParams, type MonitorListParams, + type MonitorGetCreditUsageParams, type MonitorListAccountChangesParams, type MonitorListAccountRunsParams, type MonitorListChangesParams, diff --git a/src/resources/industry.ts b/src/resources/industry.ts index 199e3e7..278a6fe 100644 --- a/src/resources/industry.ts +++ b/src/resources/industry.ts @@ -198,6 +198,13 @@ export interface IndustryRetrieveNaicsParams { */ minResults?: number; + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -224,6 +231,13 @@ export interface IndustryRetrieveSicParams { */ minResults?: number; + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed diff --git a/src/resources/monitors.ts b/src/resources/monitors.ts index d87a6b8..9d8d990 100644 --- a/src/resources/monitors.ts +++ b/src/resources/monitors.ts @@ -103,6 +103,34 @@ export class Monitors extends APIResource { return this._client.delete(path`/monitors/${monitorID}`, options); } + /** + * Returns credits charged per monitor over an optional [since, until] window, + * newest spenders first. + * + * @example + * ```ts + * const response = await client.monitors.getCreditUsage(); + * ``` + */ + getCreditUsage( + query: MonitorGetCreditUsageParams | null | undefined = {}, + options?: RequestOptions, + ): APIPromise { + return this._client.get('/monitors/credit-usage', { query, ...options }); + } + + /** + * Returns how many monitors the account has and the maximum it allows. + * + * @example + * ```ts + * const response = await client.monitors.getLimits(); + * ``` + */ + getLimits(options?: RequestOptions): APIPromise { + return this._client.get('/monitors/limits', options); + } + /** * Returns an account-wide feed of detected changes across monitors. * @@ -311,6 +339,7 @@ export interface MonitorCreateResponse { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; @@ -392,12 +421,12 @@ export namespace MonitorCreateResponse { url: string; /** - * URL path patterns to exclude. + * URL path patterns to exclude (max 50). */ exclude?: Array; /** - * URL path patterns to include. + * URL path patterns to include (max 50). */ include?: Array; @@ -651,6 +680,7 @@ export interface MonitorRetrieveResponse { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; @@ -732,12 +762,12 @@ export namespace MonitorRetrieveResponse { url: string; /** - * URL path patterns to exclude. + * URL path patterns to exclude (max 50). */ exclude?: Array; /** - * URL path patterns to include. + * URL path patterns to include (max 50). */ include?: Array; @@ -991,6 +1021,7 @@ export interface MonitorUpdateResponse { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; @@ -1072,12 +1103,12 @@ export namespace MonitorUpdateResponse { url: string; /** - * URL path patterns to exclude. + * URL path patterns to exclude (max 50). */ exclude?: Array; /** - * URL path patterns to include. + * URL path patterns to include (max 50). */ include?: Array; @@ -1331,6 +1362,7 @@ export namespace MonitorListResponse { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; @@ -1412,12 +1444,12 @@ export namespace MonitorListResponse { url: string; /** - * URL path patterns to exclude. + * URL path patterns to exclude (max 50). */ exclude?: Array; /** - * URL path patterns to include. + * URL path patterns to include (max 50). */ include?: Array; @@ -1600,6 +1632,54 @@ export interface MonitorDeleteResponse { deleted: boolean; } +export interface MonitorGetCreditUsageResponse { + data: Array; + + /** + * Sum of credits across all monitors in the window. + */ + total_credits: number; +} + +export namespace MonitorGetCreditUsageResponse { + export interface Data { + /** + * Credits charged to this monitor over the window. + */ + credits: number; + + monitor_id: string; + + /** + * Monitor name (falls back to the id when the monitor was deleted). + */ + name: string; + + /** + * Number of billed runs over the window. + */ + runs: number; + } +} + +export interface MonitorGetLimitsResponse { + /** + * Maximum number of monitors allowed for the account. Defaults to the plan + * allowance unless a custom limit is set for the organization. + */ + monitors_limit: number; + + /** + * Number of monitors the account currently has. + */ + monitors_used: number; + + /** + * The plan tier the limit was resolved from. + */ + plan: 'free' | 'starter' | 'pro' | 'scale'; +} + export interface MonitorListAccountChangesResponse { data: Array; @@ -1651,6 +1731,7 @@ export namespace MonitorListAccountChangesResponse { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; } @@ -1786,6 +1867,7 @@ export namespace MonitorListChangesResponse { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; } @@ -1901,6 +1983,7 @@ export interface MonitorRetrieveChangeResponse { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags: Array; @@ -2011,6 +2094,7 @@ export interface MonitorCreateParams { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; @@ -2085,12 +2169,12 @@ export namespace MonitorCreateParams { url: string; /** - * URL path patterns to exclude. + * URL path patterns to exclude (max 50). */ exclude?: Array; /** - * URL path patterns to include. + * URL path patterns to include (max 50). */ include?: Array; @@ -2183,6 +2267,7 @@ export interface MonitorUpdateParams { /** * User-defined tags for grouping and filtering monitors and their changes. + * Duplicates are removed. */ tags?: Array; @@ -2268,12 +2353,12 @@ export namespace MonitorUpdateParams { url: string; /** - * URL path patterns to exclude. + * URL path patterns to exclude (max 50). */ exclude?: Array; /** - * URL path patterns to include. + * URL path patterns to include (max 50). */ include?: Array; @@ -2349,10 +2434,19 @@ export namespace MonitorUpdateParams { } export interface MonitorListParams { + /** + * Filter by change detection type. + */ change_detection_type?: 'exact' | 'semantic'; + /** + * Opaque pagination cursor from a previous response. + */ cursor?: string; + /** + * Maximum number of items to return per page (1-100). Defaults to 25. + */ limit?: number; /** @@ -2364,7 +2458,7 @@ export interface MonitorListParams { * Comma-separated fields to search with `q`. Defaults to all of them. Note * `instructions` only exists on extract monitors. */ - search_by?: Array<'name' | 'url' | 'instructions' | 'tags'>; + search_by?: Array<'name' | 'url' | 'instructions' | 'tags'> | null; /** * `prefix` for as-you-type prefix matching (default), `exact` for full-token @@ -2373,11 +2467,7 @@ export interface MonitorListParams { search_type?: 'exact' | 'prefix'; /** - * Monitor lifecycle status. `failed` means the most recent run failed (see the - * monitor's `last_error`); failed monitors keep running on schedule and flip back - * to `active` on the next successful run. Monitors are auto-`paused` after - * repeated consecutive failures or insufficient-credit skips; resume by PATCHing - * status to `active`. + * Filter monitors by lifecycle status. */ status?: 'active' | 'paused' | 'failed'; @@ -2389,20 +2479,50 @@ export interface MonitorListParams { /** * Comma-separated list of tags to filter by (matches monitors having any of them). */ - tags?: Array; + tags?: Array | null; + /** + * Filter by target type. + */ target_type?: 'page' | 'sitemap' | 'extract'; } +export interface MonitorGetCreditUsageParams { + /** + * Only include items at or after this ISO 8601 timestamp. + */ + since?: string; + + /** + * Only include items before this ISO 8601 timestamp. + */ + until?: string; +} + export interface MonitorListAccountChangesParams { + /** + * Filter by change detection type. + */ change_detection_type?: 'exact' | 'semantic'; + /** + * Opaque pagination cursor from a previous response. + */ cursor?: string; + /** + * Maximum number of items to return per page (1-100). Defaults to 25. + */ limit?: number; + /** + * Filter changes to a single monitor. + */ monitor_id?: string; + /** + * Only include items at or after this ISO 8601 timestamp. + */ since?: string; /** @@ -2410,28 +2530,48 @@ export interface MonitorListAccountChangesParams { */ tag?: string; + /** + * Filter by target type. + */ target_type?: 'page' | 'sitemap' | 'extract'; + /** + * Only include items before this ISO 8601 timestamp. + */ until?: string; } export interface MonitorListAccountRunsParams { + /** + * Opaque pagination cursor from a previous response. + */ cursor?: string; + /** + * Maximum number of items to return per page (1-100). Defaults to 25. + */ limit?: number; /** - * Lifecycle status of a run. `skipped` runs never executed — see `skip_reason` - * (insufficient credits, monitor paused, or superseded by a concurrent run). + * Filter runs by lifecycle status. */ status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; } export interface MonitorListChangesParams { + /** + * Opaque pagination cursor from a previous response. + */ cursor?: string; + /** + * Maximum number of items to return per page (1-100). Defaults to 25. + */ limit?: number; + /** + * Only include items at or after this ISO 8601 timestamp. + */ since?: string; /** @@ -2439,17 +2579,25 @@ export interface MonitorListChangesParams { */ tag?: string; + /** + * Only include items before this ISO 8601 timestamp. + */ until?: string; } export interface MonitorListRunsParams { + /** + * Opaque pagination cursor from a previous response. + */ cursor?: string; + /** + * Maximum number of items to return per page (1-100). Defaults to 25. + */ limit?: number; /** - * Lifecycle status of a run. `skipped` runs never executed — see `skip_reason` - * (insufficient credits, monitor paused, or superseded by a concurrent run). + * Filter runs by lifecycle status. */ status?: 'queued' | 'running' | 'completed' | 'failed' | 'skipped'; } @@ -2462,6 +2610,8 @@ export declare namespace Monitors { type MonitorUpdateResponse as MonitorUpdateResponse, type MonitorListResponse as MonitorListResponse, type MonitorDeleteResponse as MonitorDeleteResponse, + type MonitorGetCreditUsageResponse as MonitorGetCreditUsageResponse, + type MonitorGetLimitsResponse as MonitorGetLimitsResponse, type MonitorListAccountChangesResponse as MonitorListAccountChangesResponse, type MonitorListAccountRunsResponse as MonitorListAccountRunsResponse, type MonitorListChangesResponse as MonitorListChangesResponse, @@ -2471,6 +2621,7 @@ export declare namespace Monitors { type MonitorCreateParams as MonitorCreateParams, type MonitorUpdateParams as MonitorUpdateParams, type MonitorListParams as MonitorListParams, + type MonitorGetCreditUsageParams as MonitorGetCreditUsageParams, type MonitorListAccountChangesParams as MonitorListAccountChangesParams, type MonitorListAccountRunsParams as MonitorListAccountRunsParams, type MonitorListChangesParams as MonitorListChangesParams, diff --git a/src/resources/parse.ts b/src/resources/parse.ts index b2ac506..efcfc65 100644 --- a/src/resources/parse.ts +++ b/src/resources/parse.ts @@ -9,20 +9,39 @@ import { RequestOptions } from '../internal/request-options'; export class Parse extends APIResource { /** * Converts raw text, source code, web/data, PDF, Microsoft Office, and image bytes - * into LLM-usable Markdown. The base request costs 1 credit. When OCR runs - * (requires ocr=true), the entire call costs 5 credits; ocr=true requests where no - * OCR ends up running still cost 1 credit. + * into LLM-usable Markdown. */ handle( body: Uploadable, params: ParseHandleParams, options?: RequestOptions, ): APIPromise { - const { extension, includeImages, includeLinks, ocr, pdf, shortenBase64Images, useMainContentOnly } = - params; + const { + client, + extension, + includeImages, + includeLinks, + ocr, + pdf, + shortenBase64Images, + tags, + useMainContentOnly, + zdr, + } = params; return this._client.post('/parse', { body: body, - query: { extension, includeImages, includeLinks, ocr, pdf, shortenBase64Images, useMainContentOnly }, + query: { + client, + extension, + includeImages, + includeLinks, + ocr, + pdf, + shortenBase64Images, + tags, + useMainContentOnly, + zdr, + }, ...options, headers: buildHeaders([{ 'Content-Type': 'application/octet-stream' }, options?.headers]), }); @@ -113,8 +132,13 @@ export namespace ParseHandleResponse { export interface ParseHandleParams { /** - * Query param: Optional file extension hint. Case-insensitive; a leading dot is - * accepted (e.g. ".pdf"). + * Query param: Optional client identifier used for usage attribution. + */ + client?: string; + + /** + * Query param: Optional file extension hint, such as pdf, docx, xlsx, pptx, html, + * json, csv, md, py, rtf, jpg, png, or txt. */ extension?: | 'txt' @@ -191,45 +215,58 @@ export interface ParseHandleParams { /** * Query param: Include image references in Markdown output */ - includeImages?: boolean; + includeImages?: boolean | 'true' | 'false'; /** * Query param: Preserve hyperlinks in Markdown output */ - includeLinks?: boolean; + includeLinks?: boolean | 'true' | 'false'; /** - * Query param: Gates all OCR. When true, PDFs get embedded-image OCR (recognized - * text inserted at each image's position in page reading order, preserving the - * text layer; pdf.start/pdf.end limit the page range), scanned PDFs with no text - * layer get full-document OCR, and raster images get their visible text - * transcribed. When false, no OCR runs: scanned PDFs may yield no content and - * images return only format/dimension metadata. Calls where OCR actually runs cost - * 5 credits instead of 1. + * Query param: When true for PDF inputs, detect and OCR images embedded in the + * selected pages, inserting recognized text at each image's position in page + * reading order while preserving the PDF text layer. pdf.start/pdf.end limit the + * inclusive page range. When false, all OCR is disabled, including the automatic + * scanned-PDF fallback. */ - ocr?: boolean; + ocr?: boolean | 'true' | 'false'; /** - * Query param: PDF page-range controls. Use start/end to limit parsing (and OCR - * when ocr=true) to an inclusive 1-based page range. + * Query param: PDF page-range options as a JSON object, e.g. {"start": 2, "end": + * 5}. */ pdf?: ParseHandleParams.Pdf; /** * Query param: Shorten base64-encoded image data in the Markdown output */ - shortenBase64Images?: boolean; + shortenBase64Images?: boolean | 'true' | 'false'; + + /** + * Query param: Optional comma-separated caller-defined tags for tracking this + * request. Tags are recorded on the request's usage log and can be used to filter + * usage on the dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; /** * Query param: Extract only the main content from HTML-like inputs */ - useMainContentOnly?: boolean; + useMainContentOnly?: boolean | 'true' | 'false'; + + /** + * Query param: Set to enabled to bypass shared caches and omit request and + * response content from retained usage logs. Requires zero data retention to be + * enabled for your organization (contact support@context.dev), otherwise the + * request fails with ZDR_NOT_ENABLED. Successful ZDR responses include + * X-Context-ZDR: true. + */ + zdr?: 'enabled' | 'disabled'; } export namespace ParseHandleParams { /** - * PDF page-range controls. Use start/end to limit parsing (and OCR when ocr=true) - * to an inclusive 1-based page range. + * PDF page-range options as a JSON object, e.g. {"start": 2, "end": 5}. */ export interface Pdf { /** diff --git a/src/resources/utility.ts b/src/resources/utility.ts index a40f670..e2efd7a 100644 --- a/src/resources/utility.ts +++ b/src/resources/utility.ts @@ -10,6 +10,14 @@ export class Utility extends APIResource { * selects what to prefetch (currently only 'brand') and identifier carries exactly * one lookup key: a domain, or an email whose domain is extracted and validated * (free email providers and disposable email addresses are not allowed). + * + * @example + * ```ts + * const response = await client.utility.prefetch({ + * identifier: { domain: 'xxx' }, + * type: 'brand', + * }); + * ``` */ prefetch(body: UtilityPrefetchParams, options?: RequestOptions): APIPromise { return this._client.post('/utility/prefetch', { body, ...options }); @@ -76,6 +84,11 @@ export interface UtilityPrefetchParams { */ type: 'brand'; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed diff --git a/src/resources/web.ts b/src/resources/web.ts index 561ee67..bd89fcc 100644 --- a/src/resources/web.ts +++ b/src/resources/web.ts @@ -119,7 +119,8 @@ export class Web extends APIResource { } /** - * Scrapes the given URL and returns the raw HTML content of the page. + * Scrapes the given URL and returns the raw HTML content of the page. The base + * request costs 1 credit; requests with browser actions cost 2 credits. * * @example * ```ts @@ -138,8 +139,9 @@ export class Web extends APIResource { /** * Extract image assets from a web page, including standard URLs, inline SVGs, data * URIs, responsive image sources, metadata, CSS backgrounds, video posters, and - * embeds. The base request costs 1 credit. When enrichment is enabled, the entire - * call costs 5 credits. + * embeds. The base request costs 1 credit, or 2 credits with browser actions. When + * enrichment is enabled, the entire call costs 5 credits, including requests that + * also use actions. * * @example * ```ts @@ -162,16 +164,16 @@ export class Web extends APIResource { * * ### Billing & errors * - * | HTTP status | Billed? | Meaning | - * | ----------- | -------------- | ---------------------------------------------------------------------------------------- | - * | 200 | Yes — 1 credit | Successful scrape, including a zero-length result when includeSelectors matched nothing | - * | 400 | No | Invalid input, skipped PDF, or the page could not be scraped | - * | 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code | - * | 404 | No | Target page returned or fingerprinted as not found | - * | 408 | No | Request timed out | - * | 415 | No | Unsupported content type | - * | 429 | No | Per-minute rate limit exceeded; honor Retry-After | - * | 500 | No | Internal error | + * | HTTP status | Billed? | Meaning | + * | ----------- | ----------------------------------------- | ---------------------------------------------------------------------------------------- | + * | 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing | + * | 400 | No | Invalid input, skipped PDF, or the page could not be scraped | + * | 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code | + * | 404 | No | Target page returned or fingerprinted as not found | + * | 408 | No | Request timed out | + * | 415 | No | Unsupported content type | + * | 429 | No | Per-minute rate limit exceeded; honor Retry-After | + * | 500 | No | Internal error | * * @example * ```ts @@ -190,7 +192,7 @@ export class Web extends APIResource { * @example * ```ts * const response = await client.web.webScrapeSitemap({ - * domain: 'domain', + * domain: 'xxx', * }); * ``` */ @@ -1042,7 +1044,8 @@ export interface WebScreenshotResponse { key_metadata?: WebScreenshotResponse.KeyMetadata; /** - * Public URL of the uploaded screenshot image + * Public image URL for standard requests, or an in-memory data URL when ZDR is + * enabled. */ screenshot?: string; @@ -1972,12 +1975,24 @@ export interface WebExtractParams { pdf?: WebExtractParams.Pdf; + /** + * When true, waits briefly for CSS and transition animations to settle before + * extracting each crawled page. Defaults to false. This adds a bit of latency in + * exchange for more stable output on animated pages. + */ + settleAnimations?: boolean; + /** * Soft time budget for the crawl in milliseconds. Min: 10000 (10s). Max: 110000 * (110s). Default: 80000 (80s). */ stopAfterMs?: number; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -2024,6 +2039,13 @@ export interface WebExtractCompetitorsParams { */ numCompetitors?: number; + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -2048,12 +2070,19 @@ export interface WebExtractFontsParams { domain?: string; /** - * Maximum age in milliseconds for cached data before the API performs a hard + * Maximum age in milliseconds for cached brand data before the API performs a hard * refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) * are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 * year. */ - maxAgeMs?: number; + maxAgeMs?: number | null; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; /** * Optional timeout in milliseconds for the request. If the request takes longer @@ -2086,12 +2115,19 @@ export interface WebExtractStyleguideParams { domain?: string; /** - * Maximum age in milliseconds for cached data before the API performs a hard + * Maximum age in milliseconds for cached brand data before the API performs a hard * refresh. Defaults to 3 months (7776000000 ms). Values below 1 day (86400000 ms) * are clamped to 1 day; values above 1 year (31536000000 ms) are clamped to 1 * year. */ - maxAgeMs?: number; + maxAgeMs?: number | null; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; /** * Optional timeout in milliseconds for the request. If the request takes longer @@ -2109,8 +2145,9 @@ export interface WebScreenshotParams { colorScheme?: 'light' | 'dark'; /** - * Two-letter ISO 3166-1 alpha-2 country code for the website request location. - * When provided, Context.dev fetches the target page from that country. + * Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev + * residential proxy exit location. Must be one of Context.dev's supported + * countries. When provided, Context.dev fetches the target page from that country. */ country?: | 'ad' @@ -2344,14 +2381,14 @@ export interface WebScreenshotParams { * dismiss cookie banner before capture. If 'false' or not provided, captures the * page without that step. */ - handleCookiePopup?: 'true' | 'false'; + handleCookiePopup?: boolean | 'true' | 'false'; /** * Return a cached screenshot if a prior screenshot for the same parameters exists * and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when * omitted. Max is 30 days (2592000000 ms). Set to 0 to always capture fresh. */ - maxAgeMs?: number; + maxAgeMs?: number | null; /** * Optional parameter to specify which page type to screenshot. If provided, the @@ -2370,7 +2407,14 @@ export interface WebScreenshotParams { * top to bottom). The final slice may be shorter than the viewport height. Takes * precedence over fullScreenshot. Max: 100000. */ - scrollOffset?: number; + scrollOffset?: number | null; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; /** * Optional timeout in milliseconds for the request. If the request takes longer @@ -2389,7 +2433,15 @@ export interface WebScreenshotParams { * the screenshot. Min: 0. Max: 30000 (30 seconds). Defaults to 3000 ms when * omitted. */ - waitForMs?: number; + waitForMs?: number | null; + + /** + * Set to enabled to bypass shared caches and omit request and response content + * from retained usage logs. Requires zero data retention to be enabled for your + * organization (contact support@context.dev), otherwise the request fails with + * ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true. + */ + zdr?: 'enabled' | 'disabled'; } export namespace WebScreenshotParams { @@ -2693,6 +2745,11 @@ export interface WebSearchParams { */ queryFanout?: boolean; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -3083,6 +3140,11 @@ export interface WebWebCrawlMdParams { */ stopAfterMs?: number; + /** + * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -3106,6 +3168,14 @@ export interface WebWebCrawlMdParams { * crawled page. Min: 0. Max: 30000 (30 seconds). */ waitForMs?: number; + + /** + * Set to enabled to bypass shared caches and omit request and response content + * from retained usage logs. Requires zero data retention to be enabled for your + * organization (contact support@context.dev), otherwise the request fails with + * ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true. + */ + zdr?: 'enabled' | 'disabled'; } export namespace WebWebCrawlMdParams { @@ -3147,8 +3217,18 @@ export interface WebWebScrapeHTMLParams { url: string; /** - * Two-letter ISO 3166-1 alpha-2 country code for the website request location. - * When provided, Context.dev fetches the target page from that country. + * Optional browser actions executed in array order after the page loads and before + * content is captured. Requires a paid plan. Send a JSON array in the query + * parameter. Maximum: 5 actions. + */ + actions?: Array< + WebWebScrapeHTMLParams.WebScrapeWaitAction | WebWebScrapeHTMLParams.WebScrapePerformAction + > | null; + + /** + * Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev + * residential proxy exit location. Must be one of Context.dev's supported + * countries. When provided, Context.dev fetches the target page from that country. */ country?: | 'ad' @@ -3361,7 +3441,7 @@ export interface WebWebScrapeHTMLParams { * Exclusion takes precedence: an element matching both is removed. Examples: * "nav", "footer", ".ad-banner", "[aria-hidden=true]". */ - excludeSelectors?: Array; + excludeSelectors?: Array | null; /** * Optional outbound HTTP headers forwarded only to the target URL, sent as @@ -3373,21 +3453,21 @@ export interface WebWebScrapeHTMLParams { /** * When true, iframes are rendered inline into the returned HTML. */ - includeFrames?: boolean; + includeFrames?: boolean | 'true' | 'false'; /** * CSS selectors. When provided, only matching subtrees (and their descendants) are * kept and everything else is dropped. When omitted, the entire document is kept. * Examples: "article.main", "#content", "[role=main]". */ - includeSelectors?: Array; + includeSelectors?: Array | null; /** * Return a cached result if a prior scrape for the same parameters exists and is * younger than this many milliseconds. Defaults to 1 day (86400000 ms) when * omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh. */ - maxAgeMs?: number; + maxAgeMs?: number | null; /** * PDF parsing controls. Use start/end to limit text extraction and embedded-image @@ -3400,7 +3480,14 @@ export interface WebWebScrapeHTMLParams { * extracting HTML. Defaults to false. This adds a bit of latency in exchange for * more stable output on animated pages. */ - settleAnimations?: boolean; + settleAnimations?: boolean | 'true' | 'false'; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; /** * Optional timeout in milliseconds for the request. If the request takes longer @@ -3413,16 +3500,42 @@ export interface WebWebScrapeHTMLParams { * When true, return only the page's main content in the HTML response, excluding * headers, footers, sidebars, and navigation when detectable. */ - useMainContentOnly?: boolean; + useMainContentOnly?: boolean | 'true' | 'false'; /** * Optional browser wait time in milliseconds after initial page load. Min: 0. Max: * 30000 (30 seconds). */ - waitForMs?: number; + waitForMs?: number | null; + + /** + * Set to enabled to bypass shared caches and omit request and response content + * from retained usage logs. Requires zero data retention to be enabled for your + * organization (contact support@context.dev), otherwise the request fails with + * ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true. + */ + zdr?: 'enabled' | 'disabled'; } export namespace WebWebScrapeHTMLParams { + /** + * Pause for a fixed number of milliseconds before continuing to the next action. + */ + export interface WebScrapeWaitAction { + do: 'wait'; + + timeMs: number; + } + + /** + * Resolve and perform one natural-language browser action. + */ + export interface WebScrapePerformAction { + action: string; + + do: 'perform'; + } + /** * PDF parsing controls. Use start/end to limit text extraction and embedded-image * detection/OCR to an inclusive 1-based page range. @@ -3439,13 +3552,13 @@ export namespace WebWebScrapeHTMLParams { * recognized text at each image's position in page reading order while preserving * the PDF text layer. This is separate from automatic scanned-PDF OCR fallback. */ - ocr?: boolean; + ocr?: boolean | 'true' | 'false'; /** * When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and * a 400 WEBSITE_ACCESS_ERROR is returned. */ - shouldParse?: boolean; + shouldParse?: boolean | 'true' | 'false'; /** * First 1-based PDF page to parse. When omitted, parsing starts at the first page. @@ -3460,19 +3573,28 @@ export interface WebWebScrapeImagesParams { */ url: string; + /** + * Optional browser actions executed in array order after the page loads and before + * content is captured. Requires a paid plan. Send a JSON array in the query + * parameter. Maximum: 5 actions. + */ + actions?: Array< + WebWebScrapeImagesParams.WebScrapeWaitAction | WebWebScrapeImagesParams.WebScrapePerformAction + > | null; + /** * When true, visually duplicate images are removed: every image is loaded and * perceptually hashed, and only the highest-resolution copy of each duplicate * group is kept. Images that cannot be downloaded or hashed are kept. Default: * false. */ - dedupe?: boolean; + dedupe?: boolean | 'true' | 'false'; /** * Optional per-image processing, sent as deep-object query params such as * enrichment[resolution]=true. */ - enrichment?: WebWebScrapeImagesParams.Enrichment; + enrichment?: WebWebScrapeImagesParams.Enrichment | null; /** * Optional outbound HTTP headers forwarded only to the target URL, sent as @@ -3485,7 +3607,14 @@ export interface WebWebScrapeImagesParams { * Reuse a cached result this many milliseconds old or newer. Default: 86400000 (1 * day). Set to 0 to bypass cache. Maximum: 2592000000 (30 days). */ - maxAgeMs?: number; + maxAgeMs?: number | null; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; /** * Optional timeout in milliseconds for the request. If the request takes longer @@ -3498,10 +3627,28 @@ export interface WebWebScrapeImagesParams { * Optional browser wait time in milliseconds after initial page load before * collecting images. Min: 0. Max: 30000 (30 seconds). */ - waitForMs?: number; + waitForMs?: number | null; } export namespace WebWebScrapeImagesParams { + /** + * Pause for a fixed number of milliseconds before continuing to the next action. + */ + export interface WebScrapeWaitAction { + do: 'wait'; + + timeMs: number; + } + + /** + * Resolve and perform one natural-language browser action. + */ + export interface WebScrapePerformAction { + action: string; + + do: 'perform'; + } + /** * Optional per-image processing, sent as deep-object query params such as * enrichment[resolution]=true. @@ -3510,13 +3657,13 @@ export namespace WebWebScrapeImagesParams { /** * Classify each image by visual asset type. */ - classification?: boolean; + classification?: boolean | 'true' | 'false'; /** * Host materializable images on the Brand.dev CDN and return their URL and MIME * type. */ - hostedUrl?: boolean; + hostedUrl?: boolean | 'true' | 'false'; /** * Per-image enrichment timeout in milliseconds. Default: 30000. Maximum: 60000. @@ -3526,7 +3673,7 @@ export namespace WebWebScrapeImagesParams { /** * Measure image width and height when possible. */ - resolution?: boolean; + resolution?: boolean | 'true' | 'false'; } } @@ -3538,8 +3685,18 @@ export interface WebWebScrapeMdParams { url: string; /** - * Two-letter ISO 3166-1 alpha-2 country code for the website request location. - * When provided, Context.dev fetches the target page from that country. + * Optional browser actions executed in array order after the page loads and before + * content is captured. Requires a paid plan. Send a JSON array in the query + * parameter. Maximum: 5 actions. + */ + actions?: Array< + WebWebScrapeMdParams.WebScrapeWaitAction | WebWebScrapeMdParams.WebScrapePerformAction + > | null; + + /** + * Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev + * residential proxy exit location. Must be one of Context.dev's supported + * countries. When provided, Context.dev fetches the target page from that country. */ country?: | 'ad' @@ -3752,7 +3909,7 @@ export interface WebWebScrapeMdParams { * includeSelectors. Exclusion takes precedence: an element matching both is * removed. Examples: "nav", "footer", ".ad-banner", "[aria-hidden=true]". */ - excludeSelectors?: Array; + excludeSelectors?: Array | null; /** * Optional outbound HTTP headers forwarded only to the target URL, sent as @@ -3764,31 +3921,31 @@ export interface WebWebScrapeMdParams { /** * When true, the contents of iframes are rendered to Markdown. */ - includeFrames?: boolean; + includeFrames?: boolean | 'true' | 'false'; /** * Include image references in Markdown output */ - includeImages?: boolean; + includeImages?: boolean | 'true' | 'false'; /** * Preserve hyperlinks in Markdown output */ - includeLinks?: boolean; + includeLinks?: boolean | 'true' | 'false'; /** * CSS selectors. When provided, only matching HTML subtrees (and their * descendants) are kept before conversion to Markdown. When omitted, the entire * document is kept. Examples: "article.main", "#content", "[role=main]". */ - includeSelectors?: Array; + includeSelectors?: Array | null; /** * Return a cached result if a prior scrape for the same parameters exists and is * younger than this many milliseconds. Defaults to 1 day (86400000 ms) when * omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh. */ - maxAgeMs?: number; + maxAgeMs?: number | null; /** * PDF parsing controls. Use start/end to limit text extraction and embedded-image @@ -3801,12 +3958,19 @@ export interface WebWebScrapeMdParams { * converting to Markdown. Defaults to false. This adds a bit of latency in * exchange for more stable output on animated pages. */ - settleAnimations?: boolean; + settleAnimations?: boolean | 'true' | 'false'; /** * Shorten base64-encoded image data in the Markdown output */ - shortenBase64Images?: boolean; + shortenBase64Images?: boolean | 'true' | 'false'; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; /** * Optional timeout in milliseconds for the request. If the request takes longer @@ -3819,16 +3983,42 @@ export interface WebWebScrapeMdParams { * Extract only the main content of the page, excluding headers, footers, sidebars, * and navigation */ - useMainContentOnly?: boolean; + useMainContentOnly?: boolean | 'true' | 'false'; /** * Optional browser wait time in milliseconds after initial page load before * converting the page to Markdown. Min: 0. Max: 30000 (30 seconds). */ - waitForMs?: number; + waitForMs?: number | null; + + /** + * Set to enabled to bypass shared caches and omit request and response content + * from retained usage logs. Requires zero data retention to be enabled for your + * organization (contact support@context.dev), otherwise the request fails with + * ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true. + */ + zdr?: 'enabled' | 'disabled'; } export namespace WebWebScrapeMdParams { + /** + * Pause for a fixed number of milliseconds before continuing to the next action. + */ + export interface WebScrapeWaitAction { + do: 'wait'; + + timeMs: number; + } + + /** + * Resolve and perform one natural-language browser action. + */ + export interface WebScrapePerformAction { + action: string; + + do: 'perform'; + } + /** * PDF parsing controls. Use start/end to limit text extraction and embedded-image * detection/OCR to an inclusive 1-based page range. @@ -3845,13 +4035,13 @@ export namespace WebWebScrapeMdParams { * recognized text at each image's position in page reading order while preserving * the PDF text layer. This is separate from automatic scanned-PDF OCR fallback. */ - ocr?: boolean; + ocr?: boolean | 'true' | 'false'; /** * When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and * a 400 WEBSITE_ACCESS_ERROR is returned. */ - shouldParse?: boolean; + shouldParse?: boolean | 'true' | 'false'; /** * First 1-based PDF page to parse. When omitted, parsing starts at the first page. @@ -3879,6 +4069,19 @@ export interface WebWebScrapeSitemapParams { */ maxLinks?: number; + /** + * Optional explicit sitemap URL. When provided, exactly this sitemap is crawled + * instead of discovering the domain's sitemaps. + */ + sitemapUrl?: string; + + /** + * Optional comma-separated caller-defined tags for tracking this request. Tags are + * recorded on the request's usage log and can be used to filter usage on the + * dashboard usage page. Up to 20 tags, each 1-50 characters. + */ + tags?: Array; + /** * Optional timeout in milliseconds for the request. If the request takes longer * than this value, it will be aborted with a 408 status code. Maximum allowed @@ -3891,6 +4094,14 @@ export interface WebWebScrapeSitemapParams { * returned and counted against maxLinks. */ urlRegex?: string; + + /** + * Set to enabled to bypass shared caches and omit request and response content + * from retained usage logs. Requires zero data retention to be enabled for your + * organization (contact support@context.dev), otherwise the request fails with + * ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true. + */ + zdr?: 'enabled' | 'disabled'; } export declare namespace Web { diff --git a/src/version.ts b/src/version.ts index 38ceab2..cc6e4a8 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '2.5.0'; // x-release-please-version +export const VERSION = '2.6.0'; // x-release-please-version diff --git a/tests/api-resources/ai.test.ts b/tests/api-resources/ai.test.ts index 4a5e444..72464aa 100644 --- a/tests/api-resources/ai.test.ts +++ b/tests/api-resources/ai.test.ts @@ -25,6 +25,7 @@ describe('resource ai', () => { const response = await client.ai.extractProduct({ url: 'https://example.com', maxAgeMs: 0, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }); }); @@ -47,6 +48,7 @@ describe('resource ai', () => { domain: 'domain', maxAgeMs: 0, maxProducts: 1, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }); }); diff --git a/tests/api-resources/brand.test.ts b/tests/api-resources/brand.test.ts index 0921e36..d504b5a 100644 --- a/tests/api-resources/brand.test.ts +++ b/tests/api-resources/brand.test.ts @@ -10,7 +10,7 @@ const client = new ContextDev({ describe('resource brand', () => { // Mock server tests are disabled test.skip('retrieve: only required params', async () => { - const responsePromise = client.brand.retrieve({ domain: 'domain', type: 'by_domain' }); + const responsePromise = client.brand.retrieve({ domain: 'xxx', type: 'by_domain' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,18 +23,19 @@ describe('resource brand', () => { // Mock server tests are disabled test.skip('retrieve: required and optional params', async () => { const response = await client.brand.retrieve({ - domain: 'domain', + domain: 'xxx', type: 'by_domain', force_language: 'afrikaans', maxAgeMs: 0, maxSpeed: true, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }); }); // Mock server tests are disabled test.skip('retrieveSimplified: only required params', async () => { - const responsePromise = client.brand.retrieveSimplified({ domain: 'domain' }); + const responsePromise = client.brand.retrieveSimplified({ domain: 'xxx' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -47,8 +48,10 @@ describe('resource brand', () => { // Mock server tests are disabled test.skip('retrieveSimplified: required and optional params', async () => { const response = await client.brand.retrieveSimplified({ - domain: 'domain', - maxAgeMs: 86400000, + domain: 'xxx', + maxAgeMs: 0, + tags: ['production', 'team-alpha'], + theme: 'light', timeoutMS: 1000, }); }); diff --git a/tests/api-resources/industry.test.ts b/tests/api-resources/industry.test.ts index cd70fdf..6d0a4a3 100644 --- a/tests/api-resources/industry.test.ts +++ b/tests/api-resources/industry.test.ts @@ -10,7 +10,7 @@ const client = new ContextDev({ describe('resource industry', () => { // Mock server tests are disabled test.skip('retrieveNaics: only required params', async () => { - const responsePromise = client.industry.retrieveNaics({ input: 'input' }); + const responsePromise = client.industry.retrieveNaics({ input: 'xxxx' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -23,16 +23,17 @@ describe('resource industry', () => { // Mock server tests are disabled test.skip('retrieveNaics: required and optional params', async () => { const response = await client.industry.retrieveNaics({ - input: 'input', + input: 'xxxx', maxResults: 1, minResults: 1, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }); }); // Mock server tests are disabled test.skip('retrieveSic: only required params', async () => { - const responsePromise = client.industry.retrieveSic({ input: 'input' }); + const responsePromise = client.industry.retrieveSic({ input: 'xxxx' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -45,9 +46,10 @@ describe('resource industry', () => { // Mock server tests are disabled test.skip('retrieveSic: required and optional params', async () => { const response = await client.industry.retrieveSic({ - input: 'input', + input: 'xxxx', maxResults: 1, minResults: 1, + tags: ['production', 'team-alpha'], timeoutMS: 1000, type: 'original_sic', }); diff --git a/tests/api-resources/monitors.test.ts b/tests/api-resources/monitors.test.ts index 9f35315..26a89f3 100644 --- a/tests/api-resources/monitors.test.ts +++ b/tests/api-resources/monitors.test.ts @@ -95,12 +95,12 @@ describe('resource monitors', () => { change_detection_type: 'exact', cursor: 'cursor', limit: 1, - q: 'q', + q: 'pricing', search_by: ['name'], search_type: 'exact', status: 'active', - tag: 'tag', - tags: ['string'], + tag: 'pricing', + tags: ['x'], target_type: 'page', }, { path: '/_stainless_unknown_path' }, @@ -120,6 +120,41 @@ describe('resource monitors', () => { expect(dataAndResponse.response).toBe(rawResponse); }); + // Mock server tests are disabled + test.skip('getCreditUsage', async () => { + const responsePromise = client.monitors.getCreditUsage(); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + + // Mock server tests are disabled + test.skip('getCreditUsage: request options and params are passed correctly', async () => { + // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error + await expect( + client.monitors.getCreditUsage( + { since: '2026-06-01T00:00:00Z', until: '2026-06-28T00:00:00Z' }, + { path: '/_stainless_unknown_path' }, + ), + ).rejects.toThrow(ContextDev.NotFoundError); + }); + + // Mock server tests are disabled + test.skip('getLimits', async () => { + const responsePromise = client.monitors.getLimits(); + const rawResponse = await responsePromise.asResponse(); + expect(rawResponse).toBeInstanceOf(Response); + const response = await responsePromise; + expect(response).not.toBeInstanceOf(Response); + const dataAndResponse = await responsePromise.withResponse(); + expect(dataAndResponse.data).toBe(response); + expect(dataAndResponse.response).toBe(rawResponse); + }); + // Mock server tests are disabled test.skip('listAccountChanges', async () => { const responsePromise = client.monitors.listAccountChanges(); @@ -141,11 +176,11 @@ describe('resource monitors', () => { change_detection_type: 'exact', cursor: 'cursor', limit: 1, - monitor_id: 'monitor_id', - since: '2019-12-27T18:11:19.117Z', - tag: 'tag', + monitor_id: 'mon_123', + since: '2026-06-01T00:00:00Z', + tag: 'pricing', target_type: 'page', - until: '2019-12-27T18:11:19.117Z', + until: '2026-06-28T00:00:00Z', }, { path: '/_stainless_unknown_path' }, ), @@ -200,9 +235,9 @@ describe('resource monitors', () => { { cursor: 'cursor', limit: 1, - since: '2019-12-27T18:11:19.117Z', - tag: 'tag', - until: '2019-12-27T18:11:19.117Z', + since: '2026-06-01T00:00:00Z', + tag: 'pricing', + until: '2026-06-28T00:00:00Z', }, { path: '/_stainless_unknown_path' }, ), diff --git a/tests/api-resources/utility.test.ts b/tests/api-resources/utility.test.ts index 9a0d0f9..63476b0 100644 --- a/tests/api-resources/utility.test.ts +++ b/tests/api-resources/utility.test.ts @@ -11,7 +11,7 @@ describe('resource utility', () => { // Mock server tests are disabled test.skip('prefetch: only required params', async () => { const responsePromise = client.utility.prefetch({ - identifier: { domain: 'domain' }, + identifier: { domain: 'xxx' }, type: 'brand', }); const rawResponse = await responsePromise.asResponse(); @@ -26,8 +26,9 @@ describe('resource utility', () => { // Mock server tests are disabled test.skip('prefetch: required and optional params', async () => { const response = await client.utility.prefetch({ - identifier: { domain: 'domain' }, + identifier: { domain: 'xxx' }, type: 'brand', + tags: ['production', 'team-alpha'], timeoutMS: 1000, }); }); diff --git a/tests/api-resources/web.test.ts b/tests/api-resources/web.test.ts index d866a4c..d92ae8d 100644 --- a/tests/api-resources/web.test.ts +++ b/tests/api-resources/web.test.ts @@ -50,7 +50,9 @@ describe('resource web', () => { shouldParse: true, start: 1, }, + settleAnimations: true, stopAfterMs: 10000, + tags: ['production', 'team-alpha'], timeoutMS: 1000, waitForMs: 0, }); @@ -73,6 +75,7 @@ describe('resource web', () => { const response = await client.web.extractCompetitors({ domain: 'xxx', numCompetitors: 1, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }); }); @@ -96,8 +99,9 @@ describe('resource web', () => { client.web.extractFonts( { directUrl: 'https://example.com', - domain: 'domain', - maxAgeMs: 86400000, + domain: 'xxx', + maxAgeMs: 0, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }, { path: '/_stainless_unknown_path' }, @@ -125,8 +129,9 @@ describe('resource web', () => { { colorScheme: 'light', directUrl: 'https://example.com', - domain: 'domain', - maxAgeMs: 86400000, + domain: 'xxx', + maxAgeMs: 0, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }, { path: '/_stainless_unknown_path' }, @@ -155,15 +160,17 @@ describe('resource web', () => { colorScheme: 'light', country: 'de', directUrl: 'https://example.com', - domain: 'domain', + domain: 'xxx', fullScreenshot: 'true', handleCookiePopup: 'true', maxAgeMs: 0, page: 'login', scrollOffset: 0, - timeoutMS: 1000, + tags: ['production', 'team-alpha'], + timeoutMS: 1, viewport: { height: 240, width: 240 }, waitForMs: 0, + zdr: 'enabled', }, { path: '/_stainless_unknown_path' }, ), @@ -208,6 +215,7 @@ describe('resource web', () => { }, numResults: 10, queryFanout: true, + tags: ['production', 'team-alpha'], timeoutMS: 1000, }); }); @@ -247,10 +255,12 @@ describe('resource web', () => { settleAnimations: true, shortenBase64Images: true, stopAfterMs: 10000, + tags: ['production', 'team-alpha'], timeoutMS: 1000, urlRegex: '^https?://[^/]+/blog/', useMainContentOnly: true, waitForMs: 0, + zdr: 'enabled', }); }); @@ -270,22 +280,25 @@ describe('resource web', () => { test.skip('webScrapeHTML: required and optional params', async () => { const response = await client.web.webScrapeHTML({ url: 'https://example.com', + actions: [{ do: 'wait', timeMs: 0 }], country: 'de', - excludeSelectors: ['string'], + excludeSelectors: ['x'], headers: { foo: 'J!' }, - includeFrames: true, - includeSelectors: ['string'], + includeFrames: 'true', + includeSelectors: ['x'], maxAgeMs: 0, pdf: { end: 1, - ocr: true, - shouldParse: true, + ocr: 'true', + shouldParse: 'true', start: 1, }, - settleAnimations: true, - timeoutMS: 1000, - useMainContentOnly: true, + settleAnimations: 'true', + tags: ['production', 'team-alpha'], + timeoutMS: 1, + useMainContentOnly: 'true', waitForMs: 0, + zdr: 'enabled', }); }); @@ -305,16 +318,18 @@ describe('resource web', () => { test.skip('webScrapeImages: required and optional params', async () => { const response = await client.web.webScrapeImages({ url: 'https://example.com', - dedupe: true, + actions: [{ do: 'wait', timeMs: 0 }], + dedupe: 'true', enrichment: { - classification: true, - hostedUrl: true, + classification: 'true', + hostedUrl: 'true', maxTimePerMs: 1, - resolution: true, + resolution: 'true', }, headers: { foo: 'J!' }, maxAgeMs: 0, - timeoutMS: 1000, + tags: ['production', 'team-alpha'], + timeoutMS: 1, waitForMs: 0, }); }); @@ -335,31 +350,34 @@ describe('resource web', () => { test.skip('webScrapeMd: required and optional params', async () => { const response = await client.web.webScrapeMd({ url: 'https://example.com', + actions: [{ do: 'wait', timeMs: 0 }], country: 'de', - excludeSelectors: ['string'], + excludeSelectors: ['x'], headers: { foo: 'J!' }, - includeFrames: true, - includeImages: true, - includeLinks: true, - includeSelectors: ['string'], + includeFrames: 'true', + includeImages: 'true', + includeLinks: 'true', + includeSelectors: ['x'], maxAgeMs: 0, pdf: { end: 1, - ocr: true, - shouldParse: true, + ocr: 'true', + shouldParse: 'true', start: 1, }, - settleAnimations: true, - shortenBase64Images: true, - timeoutMS: 1000, - useMainContentOnly: true, + settleAnimations: 'true', + shortenBase64Images: 'true', + tags: ['production', 'team-alpha'], + timeoutMS: 1, + useMainContentOnly: 'true', waitForMs: 0, + zdr: 'enabled', }); }); // Mock server tests are disabled test.skip('webScrapeSitemap: only required params', async () => { - const responsePromise = client.web.webScrapeSitemap({ domain: 'domain' }); + const responsePromise = client.web.webScrapeSitemap({ domain: 'xxx' }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -372,11 +390,14 @@ describe('resource web', () => { // Mock server tests are disabled test.skip('webScrapeSitemap: required and optional params', async () => { const response = await client.web.webScrapeSitemap({ - domain: 'domain', + domain: 'xxx', headers: { foo: 'J!' }, maxLinks: 1, - timeoutMS: 1000, + sitemapUrl: 'https://example.com', + tags: ['production', 'team-alpha'], + timeoutMS: 1, urlRegex: '^https?://[^/]+/blog/', + zdr: 'enabled', }); }); });