diff --git a/.release-please-manifest.json b/.release-please-manifest.json index a3906fc..f393718 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "2.9.0" + ".": "2.10.0" } diff --git a/.stats.yml b/.stats.yml index 74e73bc..97db86d 100644 --- a/.stats.yml +++ b/.stats.yml @@ -1,4 +1,4 @@ -configured_endpoints: 38 -openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-155e4761d62255841349c0f8a01b0a9c463ea1d1f2d6c4fd8d1a75c8bef6f226.yml -openapi_spec_hash: ab91f77e7c9d992400cbc7fc8a9e76c1 -config_hash: bff282047fafdad771fb7ec685f56944 +configured_endpoints: 40 +openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-a0dda03bbb600917cfb9add468cc4c8c84351a8dbbf61644dbc353263ca1748f.yml +openapi_spec_hash: c24264f32a46d9317aac5af9d6a396f7 +config_hash: 920678668dd2da6f8966fbf1b8fde4e2 diff --git a/CHANGELOG.md b/CHANGELOG.md index 51d6cc0..3fd653c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 2.10.0 (2026-08-07) + +Full Changelog: [v2.9.0...v2.10.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v2.9.0...v2.10.0) + +### Features + +* **api:** api update ([2ccf412](https://github.com/context-dot-dev/context-typescript-sdk/commit/2ccf412ff26bf695c25e1b1202a42c7f4ab6421f)) +* **api:** api update ([3baa8e2](https://github.com/context-dot-dev/context-typescript-sdk/commit/3baa8e25511876ecf0648928ef55787b94c7fffd)) +* **api:** api update ([86ef735](https://github.com/context-dot-dev/context-typescript-sdk/commit/86ef735d675b348ebbbed6aa391162b450a4cc27)) +* **api:** api update ([21cab16](https://github.com/context-dot-dev/context-typescript-sdk/commit/21cab16a097d178c4eeae4494121a3ff916af5fd)) +* **api:** api update ([8189242](https://github.com/context-dot-dev/context-typescript-sdk/commit/81892426571cb9676d8b8e04e2c2f2e9fc0b5b3a)) +* **api:** api update ([7d20482](https://github.com/context-dot-dev/context-typescript-sdk/commit/7d20482b2067563e536e5afd6d0e020a46f2daf4)) +* **api:** api update ([38a76ed](https://github.com/context-dot-dev/context-typescript-sdk/commit/38a76ed4ba43440692353175b92e2047a0b4ab73)) +* **api:** manual updates ([4a208a8](https://github.com/context-dot-dev/context-typescript-sdk/commit/4a208a8eb3f3903cc5a9b0d68857775f24f0c6c1)) + ## 2.9.0 (2026-08-05) Full Changelog: [v2.8.0...v2.9.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v2.8.0...v2.9.0) diff --git a/api.md b/api.md index 1e30ea7..e49a298 100644 --- a/api.md +++ b/api.md @@ -131,6 +131,7 @@ Types: - Intake - BatchRetrieveResponse - BatchListResponse +- BatchDeleteResponse - BatchCancelResponse - BatchGetResultsResponse - BatchSubmitResponse @@ -139,6 +140,17 @@ Methods: - client.batch.retrieve(batchID) -> BatchRetrieveResponse - client.batch.list({ ...params }) -> BatchListResponse +- client.batch.delete(batchID) -> BatchDeleteResponse - client.batch.cancel(batchID) -> BatchCancelResponse - client.batch.getResults(batchID, { ...params }) -> BatchGetResultsResponse -- client.batch.submit({ ...params }) -> BatchSubmitResponse +- client.batch.submit({ ...params }) -> BatchSubmitResponse + +# People + +Types: + +- PersonEnrichResponse + +Methods: + +- client.people.enrich({ ...params }) -> PersonEnrichResponse diff --git a/package.json b/package.json index 3b0ac17..c02fc2e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "context.dev", - "version": "2.9.0", + "version": "2.10.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 00d23ca..f35389b 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.9.0", + "version": "2.10.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 bc11f7d..189a44b 100644 --- a/packages/mcp-server/package.json +++ b/packages/mcp-server/package.json @@ -1,6 +1,6 @@ { "name": "context.dev-mcp", - "version": "2.9.0", + "version": "2.10.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 0d76562..1474f2c 100644 --- a/packages/mcp-server/src/code-tool-worker.ts +++ b/packages/mcp-server/src/code-tool-worker.ts @@ -142,10 +142,12 @@ const fuse = new Fuse( 'client.monitors.run', 'client.monitors.update', 'client.batch.cancel', + 'client.batch.delete', 'client.batch.getResults', 'client.batch.list', 'client.batch.retrieve', 'client.batch.submit', + 'client.people.enrich', ], { threshold: 1, shouldSort: true }, ); diff --git a/packages/mcp-server/src/local-docs-search.ts b/packages/mcp-server/src/local-docs-search.ts index 58a577d..8035e0b 100644 --- a/packages/mcp-server/src/local-docs-search.ts +++ b/packages/mcp-server/src/local-docs-search.ts @@ -75,7 +75,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ response: '{ markdown: string; success: true; type: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - "## 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```", + "## 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, OCR the selected pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real text layer keep it. pdf.start/pdf.end limit the inclusive page range. Billed at 1 credit per page OCR actually recovered, on top of the base request cost. When false, no OCR runs.\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', @@ -141,7 +141,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 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; actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]; actionsHtmlStale?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", markdown: - "## 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; actionsApplied?: object[]; actionsHtmlStale?: boolean; 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 Fetch the target page through a residential proxy in this country (ISO 3166-1 alpha-2).\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; actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]; actionsHtmlStale?: boolean; 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 - `actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]`\n - `actionsHtmlStale?: boolean`\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; actionsApplied?: object[]; actionsHtmlStale?: boolean; 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 Fetch the target page through a residential proxy in this country (ISO 3166-1 alpha-2).\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, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real text layer keep it. Billed at 1 credit per page OCR actually recovered, on top of the base request cost. When false, no OCR runs.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED 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; actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]; actionsHtmlStale?: boolean; 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 - `actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]`\n - `actionsHtmlStale?: boolean`\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', @@ -185,7 +185,7 @@ 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, 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 |', + '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### YouTube\n\nYouTube URLs return the video or channel itself rather than the surrounding player and navigation chrome. A URL addressing a single video (`/watch`, `youtu.be`, `/shorts`, `/embed`, `/live`) returns its title, channel, duration, view count, keywords, full description, and the transcript when the video has captions that can be retrieved; videos without captions return everything except the transcript. A channel URL (`/channel/UC…`, `/@handle`, `/c/…`, `/user/…`) returns its name, handle, subscriber count, video count, and full description. When `includeImages=true`, video responses also include the thumbnail and channel responses include the avatar. Costs the same as any other scrape.\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| 413 | No | Target content exceeds the maximum supported size (20 MB) |\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: [ @@ -211,7 +211,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 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; actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]; actionsHtmlStale?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", markdown: - "## 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; actionsApplied?: object[]; actionsHtmlStale?: boolean; 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 Fetch the target page through a residential proxy in this country (ISO 3166-1 alpha-2).\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; actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]; actionsHtmlStale?: boolean; 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 - `actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]`\n - `actionsHtmlStale?: boolean`\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; actionsApplied?: object[]; actionsHtmlStale?: boolean; 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### YouTube\n\nYouTube URLs return the video or channel itself rather than the surrounding player and navigation chrome. A URL addressing a single video (`/watch`, `youtu.be`, `/shorts`, `/embed`, `/live`) returns its title, channel, duration, view count, keywords, full description, and the transcript when the video has captions that can be retrieved; videos without captions return everything except the transcript. A channel URL (`/channel/UC…`, `/@handle`, `/c/…`, `/user/…`) returns its name, handle, subscriber count, video count, and full description. When `includeImages=true`, video responses also include the thumbnail and channel responses include the avatar. Costs the same as any other scrape.\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| 413 | No | Target content exceeds the maximum supported size (20 MB) |\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 Fetch the target page through a residential proxy in this country (ISO 3166-1 alpha-2).\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, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page's text with the OCR result while pages with a real text layer keep it. Billed at 1 credit per page OCR actually recovered, on top of the base request cost. When false, no OCR runs.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 PDF_SKIPPED 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; actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]; actionsHtmlStale?: boolean; 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 - `actionsApplied?: { instruction: string; status: 'applied' | 'failed' | 'skipped'; completionEvidence?: string; durationMs?: number; error?: string; method?: string; targetDescription?: string; }[]`\n - `actionsHtmlStale?: boolean`\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', @@ -314,13 +314,15 @@ const EMBEDDED_METHODS: MethodEntry[] = [ endpoint: '/web/scrape/sitemap', httpMethod: 'get', summary: 'Crawl Sitemap', - description: "Crawl an entire website's sitemap and return all discovered page URLs.", + description: + "Crawl an entire website's sitemap and return all discovered page URLs. Pass `search` to have the crawled sitemap filtered down to the pages about a phrase (for example `pricing and plans` or `api authentication docs`), most relevant first — a searched crawl scans the whole sitemap and costs 2 credits instead of 1.", stainlessPath: '(resource) web > (method) web_scrape_sitemap', qualified: 'client.web.webScrapeSitemap', params: [ 'domain: string;', 'headers?: object;', 'maxLinks?: number;', + 'search?: string;', 'sitemapUrl?: string;', 'tags?: string[];', 'timeoutMS?: number;', @@ -330,7 +332,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 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, 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```", + "## web_scrape_sitemap\n\n`client.web.webScrapeSitemap(domain: string, headers?: object, maxLinks?: number, search?: string, 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. Pass `search` to have the crawled sitemap filtered down to the pages about a phrase (for example `pricing and plans` or `api authentication docs`), most relevant first — a searched crawl scans the whole sitemap and costs 2 credits instead of 1.\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- `search?: string`\n Optional search phrase. When provided, the crawled sitemap is filtered to the pages whose URLs are about that phrase, most relevant first, and the request costs 2 credits instead of 1.\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', @@ -359,7 +361,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ php: { method: 'web->webScrapeSitemap', example: - "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);", + "web->webScrapeSitemap(\n domain: 'xxx',\n headers: ['foo' => 'J!'],\n maxLinks: 1,\n search: 'help center and troubleshooting articles',\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: @@ -466,7 +468,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 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, 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 Fetch the target page through a residential proxy in this country (ISO 3166-1 alpha-2).\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```', + '## 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 Fetch the target page through a residential proxy in this country (ISO 3166-1 alpha-2).\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, OCR the selected PDF pages that have no usable text layer (scans), replacing each recovered page\'s text with the OCR result while pages with a real text layer keep it. Billed at 1 credit per page OCR actually recovered, on top of the base request cost.\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', @@ -637,9 +639,9 @@ const EMBEDDED_METHODS: MethodEntry[] = [ '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; }; }", + "{ query: string; results: { description: string; markdown: { code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'CONTENT_TOO_LARGE' | '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, 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```", + "## 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' | 'CONTENT_TOO_LARGE' | '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' | 'CONTENT_TOO_LARGE' | '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', @@ -908,7 +910,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [ "{ 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; }", + "{ 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; employees?: { exact?: number; range?: 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; }", perLanguage: { typescript: { method: 'client.brand.retrieve', @@ -952,14 +954,14 @@ const EMBEDDED_METHODS: MethodEntry[] = [ httpMethod: 'get', summary: 'Brand Search', description: - 'Search brands by name or domain and get back up to 10 lightweight matches (domain, name, logo), most popular first: by Tranco rank, then market cap for brands outside the Tranco list, with text relevance breaking ties. Matching is prefix-based with no typo tolerance, so it is suited to autocomplete. Only brands already in the Context.dev index are returned — use /brand/retrieve to fetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit per request on the Free and Starter plans.', + 'Search brands by name or domain and get back up to 10 lightweight matches (domain, name, logo). Name matches rank ahead of domain matches; within each group the most popular brands come first: by Tranco rank, then market cap for brands outside the Tranco list, with text relevance breaking ties. Matching is prefix-based with no typo tolerance, so it is suited to autocomplete. Only brands already in the Context.dev index are returned — use /brand/retrieve to fetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit per request on the Free and Starter plans.', stainlessPath: '(resource) brand > (method) search', qualified: 'client.brand.search', params: ['query: string;', 'tags?: string[];'], response: '{ results: { domain: string; logo: string; name: string; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', markdown: - "## search\n\n`client.brand.search(query: string, tags?: string[]): { results: object[]; key_metadata?: object; }`\n\n**get** `/brand/search`\n\nSearch brands by name or domain and get back up to 10 lightweight matches (domain, name, logo), most popular first: by Tranco rank, then market cap for brands outside the Tranco list, with text relevance breaking ties. Matching is prefix-based with no typo tolerance, so it is suited to autocomplete. Only brands already in the Context.dev index are returned — use /brand/retrieve to fetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit per request on the Free and Starter plans.\n\n### Parameters\n\n- `query: string`\n Search term, matched against brand names and domains by prefix (e.g. 'nike', 'nike.com', 'nik').\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### Returns\n\n- `{ results: { domain: string; logo: string; name: string; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `results: { domain: string; logo: string; name: 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.brand.search({ query: 'x' });\n\nconsole.log(response);\n```", + "## search\n\n`client.brand.search(query: string, tags?: string[]): { results: object[]; key_metadata?: object; }`\n\n**get** `/brand/search`\n\nSearch brands by name or domain and get back up to 10 lightweight matches (domain, name, logo). Name matches rank ahead of domain matches; within each group the most popular brands come first: by Tranco rank, then market cap for brands outside the Tranco list, with text relevance breaking ties. Matching is prefix-based with no typo tolerance, so it is suited to autocomplete. Only brands already in the Context.dev index are returned — use /brand/retrieve to fetch (and index) a specific domain. Free on Pro and Scale plans; costs 1 credit per request on the Free and Starter plans.\n\n### Parameters\n\n- `query: string`\n Search term, matched against brand names and domains by prefix (e.g. 'nike', 'nike.com', 'nik').\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### Returns\n\n- `{ results: { domain: string; logo: string; name: string; }[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `results: { domain: string; logo: string; name: 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.brand.search({ query: 'x' });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.brand.search', @@ -1916,50 +1918,56 @@ const EMBEDDED_METHODS: MethodEntry[] = [ }, { name: 'submit', - endpoint: '/people/retrieve', + endpoint: '/batch/submit', httpMethod: 'post', - summary: 'Retrieve Person', - description: 'Retrieve and normalize a person profile from identifiers.', + summary: 'Submit a batch', + description: 'Scrape 25K URLs or crawl large websites asynchronously. ', stainlessPath: '(resource) batch > (method) submit', qualified: 'client.batch.submit', - params: ['identifiers: { linkedinUrl?: string; };', 'tags?: string[];', 'timeoutMS?: number;'], + params: [ + "input: { data: { format: 'markdown'; urls: { url: string; itemId?: string; meta?: object; }[]; options?: { country?: string; excludeSelectors?: string[]; includeImages?: boolean; includeLinks?: boolean; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; shortenBase64Images?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; } | { format: 'html'; urls: { url: string; itemId?: string; meta?: object; }[]; options?: { country?: string; excludeSelectors?: string[]; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; }; mode: 'scrape'; } | { data: { format: 'markdown'; source: { type: 'start_url'; url: string; controls?: { followSubdomains?: boolean; maxDepth?: number; maxUrls?: number; regex?: string; }; } | { domain: string; type: 'sitemap'; controls?: { maxUrls?: number; regex?: string; }; }; options?: { country?: string; excludeSelectors?: string[]; includeImages?: boolean; includeLinks?: boolean; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; shortenBase64Images?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; } | { format: 'html'; source: { type: 'start_url'; url: string; controls?: { followSubdomains?: boolean; maxDepth?: number; maxUrls?: number; regex?: string; }; } | { domain: string; type: 'sitemap'; controls?: { maxUrls?: number; regex?: string; }; }; options?: { country?: string; excludeSelectors?: string[]; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; }; mode: 'crawl'; };", + 'tags?: string[];', + 'webhookUrl?: string;', + 'Idempotency-Key?: string;', + ], response: - "{ code: 200; metadata: { identifiers: { linkedinUrl?: string; }; sourcesAttempted: 'linkedin' | 'cv' | 'manual' | 'github' | 'other'[]; sourcesSucceeded: 'linkedin' | 'cv' | 'manual' | 'github' | 'other'[]; urlsAnalyzed: string[]; personalWebsiteUrl?: string; }; person: { education: { institution: object; dates?: object; description?: string; fieldOfStudy?: string; qualification?: string; }[]; experience: { company: object; title: string; dates?: object; description?: string; }[]; profile: { fullName?: string; headline?: string; location?: string; profilePictureUrl?: string; summary?: string; }; skills: { name: string; normalized?: string; proficiency?: string; }[]; }; status: 'ok'; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", + "{ id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: object | object; url_pattern: string; }; created_at: string; credits: { reserved: number; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; status: 'queued'; tags: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; webhook_secret?: string; }", markdown: - "## submit\n\n`client.batch.submit(identifiers: { linkedinUrl?: string; }, tags?: string[], timeoutMS?: number): { code: 200; metadata: object; person: object; status: 'ok'; key_metadata?: object; }`\n\n**post** `/people/retrieve`\n\nRetrieve and normalize a person profile from identifiers.\n\n### Parameters\n\n- `identifiers: { linkedinUrl?: string; }`\n Known identifiers for the person. At least one identifier is required.\n - `linkedinUrl?: string`\n LinkedIn profile URL, e.g. https://www.linkedin.com/in/yahia-bakour/.\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- `{ code: 200; metadata: { identifiers: { linkedinUrl?: string; }; sourcesAttempted: 'linkedin' | 'cv' | 'manual' | 'github' | 'other'[]; sourcesSucceeded: 'linkedin' | 'cv' | 'manual' | 'github' | 'other'[]; urlsAnalyzed: string[]; personalWebsiteUrl?: string; }; person: { education: { institution: object; dates?: object; description?: string; fieldOfStudy?: string; qualification?: string; }[]; experience: { company: object; title: string; dates?: object; description?: string; }[]; profile: { fullName?: string; headline?: string; location?: string; profilePictureUrl?: string; summary?: string; }; skills: { name: string; normalized?: string; proficiency?: string; }[]; }; status: 'ok'; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `code: 200`\n - `metadata: { identifiers: { linkedinUrl?: string; }; sourcesAttempted: 'linkedin' | 'cv' | 'manual' | 'github' | 'other'[]; sourcesSucceeded: 'linkedin' | 'cv' | 'manual' | 'github' | 'other'[]; urlsAnalyzed: string[]; personalWebsiteUrl?: string; }`\n - `person: { education: { institution: { display: string; normalized?: string; }; dates?: { endDate?: { year: number; day?: number; month?: number; }; isCurrent?: boolean; startDate?: { year: number; day?: number; month?: number; }; }; description?: string; fieldOfStudy?: string; qualification?: string; }[]; experience: { company: { display: string; normalized?: string; }; title: string; dates?: { endDate?: { year: number; day?: number; month?: number; }; isCurrent?: boolean; startDate?: { year: number; day?: number; month?: number; }; }; description?: string; }[]; profile: { fullName?: string; headline?: string; location?: string; profilePictureUrl?: string; summary?: string; }; skills: { name: string; normalized?: string; proficiency?: string; }[]; }`\n - `status: 'ok'`\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.batch.submit({ identifiers: {} });\n\nconsole.log(response);\n```", + "## submit\n\n`client.batch.submit(input: { data: { format: 'markdown'; urls: object[]; options?: object; } | { format: 'html'; urls: object[]; options?: object; }; mode: 'scrape'; } | { data: { format: 'markdown'; source: object | object; options?: object; } | { format: 'html'; source: object | object; options?: object; }; mode: 'crawl'; }, tags?: string[], webhookUrl?: string, Idempotency-Key?: string): { id: string; crawl: crawl_controls; created_at: string; credits: object; format: 'markdown' | 'html'; input: intake; invalid_urls: object[]; mode: 'scrape' | 'crawl'; status: 'queued'; tags: string[]; key_metadata?: object; webhook_secret?: string; }`\n\n**post** `/batch/submit`\n\nScrape 25K URLs or crawl large websites asynchronously. \n\n### Parameters\n\n- `input: { data: { format: 'markdown'; urls: { url: string; itemId?: string; meta?: object; }[]; options?: { country?: string; excludeSelectors?: string[]; includeImages?: boolean; includeLinks?: boolean; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; shortenBase64Images?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; } | { format: 'html'; urls: { url: string; itemId?: string; meta?: object; }[]; options?: { country?: string; excludeSelectors?: string[]; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; }; mode: 'scrape'; } | { data: { format: 'markdown'; source: { type: 'start_url'; url: string; controls?: { followSubdomains?: boolean; maxDepth?: number; maxUrls?: number; regex?: string; }; } | { domain: string; type: 'sitemap'; controls?: { maxUrls?: number; regex?: string; }; }; options?: { country?: string; excludeSelectors?: string[]; includeImages?: boolean; includeLinks?: boolean; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; shortenBase64Images?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; } | { format: 'html'; source: { type: 'start_url'; url: string; controls?: { followSubdomains?: boolean; maxDepth?: number; maxUrls?: number; regex?: string; }; } | { domain: string; type: 'sitemap'; controls?: { maxUrls?: number; regex?: string; }; }; options?: { country?: string; excludeSelectors?: string[]; includeSelectors?: string[]; maxAgeMs?: number; pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }; settleAnimations?: boolean; useMainContentOnly?: boolean; waitForMs?: number; }; }; mode: 'crawl'; }`\n Choose a URL list or a site crawl.\n\n- `tags?: string[]`\n Tags stored on the batch. Filter the batch list by them later.\n\n- `webhookUrl?: string`\n URL notified when the batch finishes.\n\n- `Idempotency-Key?: string`\n Any string unique to this submission. Retries with the same key return the original batch.\n\n### Returns\n\n- `{ id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: object | object; url_pattern: string; }; created_at: string; credits: { reserved: number; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; status: 'queued'; tags: string[]; key_metadata?: { credits_consumed: number; credits_remaining: number; }; webhook_secret?: string; }`\n\n - `id: string`\n - `crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: { type: 'start_url'; url: string; } | { domain: string; type: 'sitemap'; }; url_pattern: string; }`\n - `created_at: string`\n - `credits: { reserved: number; }`\n - `format: 'markdown' | 'html'`\n - `input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }`\n - `invalid_urls: { reason: string; url: string; }[]`\n - `mode: 'scrape' | 'crawl'`\n - `status: 'queued'`\n - `tags: string[]`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `webhook_secret?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.batch.submit({ input: {\n data: { format: 'markdown', urls: [{ url: 'https://example.com/products/anvil' }, { url: 'https://example.com/products/hammer' }] },\n mode: 'scrape',\n} });\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.batch.submit', 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.batch.submit({\n identifiers: { linkedinUrl: 'https://www.linkedin.com/in/yahia-bakour/' },\n});\n\nconsole.log(response.code);", + "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.batch.submit({\n input: {\n data: {\n urls: [\n {\n url: 'https://example.com/products/anvil',\n itemId: 'sku-1',\n meta: { category: 'tools' },\n },\n { url: 'https://example.com/products/hammer', itemId: 'sku-2' },\n ],\n options: { useMainContentOnly: true },\n },\n },\n});\n\nconsole.log(response.id);", }, python: { method: 'batch.submit', 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.batch.submit(\n identifiers={\n "linkedin_url": "https://www.linkedin.com/in/yahia-bakour/"\n },\n)\nprint(response.code)', + '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.batch.submit(\n input={\n "data": {\n "urls": [{\n "url": "https://example.com/products/anvil",\n "item_id": "sku-1",\n "meta": {\n "category": "tools"\n },\n }, {\n "url": "https://example.com/products/hammer",\n "item_id": "sku-2",\n }],\n "options": {\n "use_main_content_only": True\n },\n }\n },\n)\nprint(response.id)', }, go: { method: 'client.Batch.Submit', 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.Batch.Submit(context.TODO(), contextdev.BatchSubmitParams{\n\t\tIdentifiers: contextdev.BatchSubmitParamsIdentifiers{\n\t\t\tLinkedinURL: contextdev.String("https://www.linkedin.com/in/yahia-bakour/"),\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Code)\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.Batch.Submit(context.TODO(), contextdev.BatchSubmitParams{\n\t\tInput: contextdev.BatchSubmitParamsInputUnion{\n\t\t\tOfScrape: &contextdev.BatchSubmitParamsInputScrape{\n\t\t\t\tData: contextdev.BatchSubmitParamsInputScrapeDataUnion{\n\t\t\t\t\tOfMarkdown: &contextdev.BatchSubmitParamsInputScrapeDataMarkdown{\n\t\t\t\t\t\tURLs: []contextdev.BatchSubmitParamsInputScrapeDataMarkdownURL{{\n\t\t\t\t\t\t\tURL: "https://example.com/products/anvil",\n\t\t\t\t\t\t\tItemID: contextdev.String("sku-1"),\n\t\t\t\t\t\t\tMeta: map[string]any{\n\t\t\t\t\t\t\t\t"category": "tools",\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}, {\n\t\t\t\t\t\t\tURL: "https://example.com/products/hammer",\n\t\t\t\t\t\t\tItemID: contextdev.String("sku-2"),\n\t\t\t\t\t\t}},\n\t\t\t\t\t\tOptions: contextdev.BatchSubmitParamsInputScrapeDataMarkdownOptions{\n\t\t\t\t\t\t\tUseMainContentOnly: contextdev.Bool(true),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.ID)\n}\n', }, ruby: { method: 'batch.submit', example: - 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.batch.submit(identifiers: {})\n\nputs(response)', + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.batch.submit(\n input: {\n data: {\n format: :markdown,\n urls: [{url: "https://example.com/products/anvil"}, {url: "https://example.com/products/hammer"}]\n },\n mode: :scrape\n }\n)\n\nputs(response)', }, cli: { method: 'batch submit', - example: "context-dev batch submit \\\n --api-key 'My API Key' \\\n --identifiers '{}'", + example: + "context-dev batch submit \\\n --api-key 'My API Key' \\\n --input '{data: {format: markdown, urls: [{url: https://example.com/products/anvil}, {url: https://example.com/products/hammer}]}, mode: scrape}'", }, php: { method: 'batch->submit', example: - "batch->submit(\n identifiers: ['linkedinURL' => 'https://www.linkedin.com/in/yahia-bakour/'],\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", + "batch->submit(\n input: [\n 'data' => [\n 'format' => 'markdown',\n 'urls' => [\n [\n 'url' => 'https://example.com/products/anvil',\n 'itemID' => 'sku-1',\n 'meta' => ['category' => 'bar'],\n ],\n [\n 'url' => 'https://example.com/products/hammer',\n 'itemID' => 'sku-2',\n 'meta' => ['foo' => 'bar'],\n ],\n ],\n 'options' => [\n 'country' => 'de',\n 'excludeSelectors' => ['x'],\n 'includeImages' => true,\n 'includeLinks' => true,\n 'includeSelectors' => ['x'],\n 'maxAgeMs' => 0,\n 'pdf' => [\n 'end' => 1, 'ocr' => 'true', 'shouldParse' => 'true', 'start' => 1\n ],\n 'settleAnimations' => true,\n 'shortenBase64Images' => true,\n 'useMainContentOnly' => true,\n 'waitForMs' => 0,\n ],\n ],\n 'mode' => 'scrape',\n ],\n tags: ['docs', 'competitor'],\n webhookURL: 'webhookUrl',\n idempotencyKey: 'Idempotency-Key',\n);\n\nvar_dump($response);", }, http: { example: - 'curl https://api.context.dev/v1/people/retrieve \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "identifiers": {\n "linkedinUrl": "https://www.linkedin.com/in/yahia-bakour/"\n },\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', + 'curl https://api.context.dev/v1/batch/submit \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "input": {\n "data": {\n "format": "markdown",\n "urls": [\n {\n "url": "https://example.com/products/anvil",\n "itemId": "sku-1",\n "meta": {\n "category": "bar"\n }\n },\n {\n "url": "https://example.com/products/hammer",\n "itemId": "sku-2"\n }\n ],\n "options": {\n "useMainContentOnly": true\n }\n },\n "mode": "scrape"\n },\n "tags": [\n "docs",\n "competitor"\n ]\n }\'', }, }, }, @@ -1980,9 +1988,9 @@ const EMBEDDED_METHODS: MethodEntry[] = [ 'tags?: string;', ], response: - "{ data?: { id: string; crawl: object; credits: { net: number; refunded: number; reserved: number; }; failure: object; format: 'markdown' | 'html'; input: object; mode: 'scrape' | 'crawl'; page_errors: object[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: object[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }", + "{ data?: { id: string; crawl: object; credits: { net: number; ocr_charged: number; refunded: number; reserved: number; }; failure: object; format: 'markdown' | 'html'; input: object; mode: 'scrape' | 'crawl'; page_errors: object[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: object[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }", markdown: - "## list\n\n`client.batch.list(cursor?: string, limit?: number, q?: string, search_type?: 'exact' | 'prefix', status?: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed', tags?: string): { data?: object[]; has_more?: boolean; key_metadata?: object; next_cursor?: string; }`\n\n**get** `/batch/list`\n\nList your batches from newest to oldest. Filter by status or continue with a cursor.\n\n### Parameters\n\n- `cursor?: string`\n Cursor from the previous page.\n\n- `limit?: number`\n Batches per page. Defaults to 25.\n\n- `q?: string`\n Free-text search term, matched against the batch id, crawl source (start URL or sitemap domain), and tags.\n\n- `search_type?: 'exact' | 'prefix'`\n `prefix` for as-you-type prefix matching (default), `exact` for full-token matching.\n\n- `status?: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'`\n Filter by status.\n\n- `tags?: string`\n Comma-separated list of tags to filter by (matches batches having any of them).\n\n### Returns\n\n- `{ data?: { id: string; crawl: object; credits: { net: number; refunded: number; reserved: number; }; failure: object; format: 'markdown' | 'html'; input: object; mode: 'scrape' | 'crawl'; page_errors: object[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: object[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }`\n\n - `data?: { id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: { type: 'start_url'; url: string; } | { domain: string; type: 'sitemap'; }; url_pattern: string; }; credits: { net: number; refunded: number; reserved: number; }; failure: { code: string; message: string; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; mode: 'scrape' | 'crawl'; page_errors: { code: string; count: number; }[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; }[]`\n - `has_more?: boolean`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `next_cursor?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst batches = await client.batch.list();\n\nconsole.log(batches);\n```", + "## list\n\n`client.batch.list(cursor?: string, limit?: number, q?: string, search_type?: 'exact' | 'prefix', status?: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed', tags?: string): { data?: object[]; has_more?: boolean; key_metadata?: object; next_cursor?: string; }`\n\n**get** `/batch/list`\n\nList your batches from newest to oldest. Filter by status or continue with a cursor.\n\n### Parameters\n\n- `cursor?: string`\n Cursor from the previous page.\n\n- `limit?: number`\n Batches per page. Defaults to 25.\n\n- `q?: string`\n Free-text search term, matched against the batch id, crawl source (start URL or sitemap domain), and tags.\n\n- `search_type?: 'exact' | 'prefix'`\n `prefix` for as-you-type prefix matching (default), `exact` for full-token matching.\n\n- `status?: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'`\n Filter by status.\n\n- `tags?: string`\n Comma-separated list of tags to filter by (matches batches having any of them).\n\n### Returns\n\n- `{ data?: { id: string; crawl: object; credits: { net: number; ocr_charged: number; refunded: number; reserved: number; }; failure: object; format: 'markdown' | 'html'; input: object; mode: 'scrape' | 'crawl'; page_errors: object[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: object[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }`\n\n - `data?: { id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: { type: 'start_url'; url: string; } | { domain: string; type: 'sitemap'; }; url_pattern: string; }; credits: { net: number; ocr_charged: number; refunded: number; reserved: number; }; failure: { code: string; message: string; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; mode: 'scrape' | 'crawl'; page_errors: { code: string; count: number; }[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; }[]`\n - `has_more?: boolean`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n - `next_cursor?: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst batches = await client.batch.list();\n\nconsole.log(batches);\n```", perLanguage: { typescript: { method: 'client.batch.list', @@ -2029,9 +2037,9 @@ const EMBEDDED_METHODS: MethodEntry[] = [ qualified: 'client.batch.retrieve', params: ['batch_id: string;'], response: - "{ id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: object | object; url_pattern: string; }; credits: { net: number; refunded: number; reserved: number; }; failure: { code: string; message: string; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; page_errors: { code: string; count: number; }[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", + "{ id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: object | object; url_pattern: string; }; credits: { net: number; ocr_charged: number; refunded: number; reserved: number; }; failure: { code: string; message: string; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; page_errors: { code: string; count: number; }[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", markdown: - "## retrieve\n\n`client.batch.retrieve(batch_id: string): { id: string; crawl: crawl_controls; credits: object; failure: failure; format: 'markdown' | 'html'; input: intake; invalid_urls: object[]; mode: 'scrape' | 'crawl'; page_errors: page_error_count[]; progress: object; results: object; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: object; key_metadata?: object; }`\n\n**get** `/batch/{batch_id}`\n\nCheck progress, and get download links once the batch finishes.\n\n### Parameters\n\n- `batch_id: string`\n ID of the batch to retrieve or cancel.\n\n### Returns\n\n- `{ id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: object | object; url_pattern: string; }; credits: { net: number; refunded: number; reserved: number; }; failure: { code: string; message: string; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; page_errors: { code: string; count: number; }[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `id: string`\n - `crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: { type: 'start_url'; url: string; } | { domain: string; type: 'sitemap'; }; url_pattern: string; }`\n - `credits: { net: number; refunded: number; reserved: number; }`\n - `failure: { code: string; message: string; }`\n - `format: 'markdown' | 'html'`\n - `input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }`\n - `invalid_urls: { reason: string; url: string; }[]`\n - `mode: 'scrape' | 'crawl'`\n - `page_errors: { code: string; count: number; }[]`\n - `progress: { failed: number; pending: number; succeeded: number; }`\n - `results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }`\n - `status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'`\n - `tags: string[]`\n - `timing: { completed_at: string; created_at: string; started_at: 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 batch = await client.batch.retrieve('batch_9f2c8a');\n\nconsole.log(batch);\n```", + "## retrieve\n\n`client.batch.retrieve(batch_id: string): { id: string; crawl: crawl_controls; credits: object; failure: failure; format: 'markdown' | 'html'; input: intake; invalid_urls: object[]; mode: 'scrape' | 'crawl'; page_errors: page_error_count[]; progress: object; results: object; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: object; key_metadata?: object; }`\n\n**get** `/batch/{batch_id}`\n\nCheck progress, and get download links once the batch finishes.\n\n### Parameters\n\n- `batch_id: string`\n ID of the batch to retrieve or cancel.\n\n### Returns\n\n- `{ id: string; crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: object | object; url_pattern: string; }; credits: { net: number; ocr_charged: number; refunded: number; reserved: number; }; failure: { code: string; message: string; }; format: 'markdown' | 'html'; input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; page_errors: { code: string; count: number; }[]; progress: { failed: number; pending: number; succeeded: number; }; results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: { completed_at: string; created_at: string; started_at: string; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `id: string`\n - `crawl: { follow_subdomains: boolean; max_depth: number; max_pages: number; source: { type: 'start_url'; url: string; } | { domain: string; type: 'sitemap'; }; url_pattern: string; }`\n - `credits: { net: number; ocr_charged: number; refunded: number; reserved: number; }`\n - `failure: { code: string; message: string; }`\n - `format: 'markdown' | 'html'`\n - `input: { duplicates: number; invalid: number; reserved: number; reserved_is_ceiling: boolean; submitted: number; }`\n - `invalid_urls: { reason: string; url: string; }[]`\n - `mode: 'scrape' | 'crawl'`\n - `page_errors: { code: string; count: number; }[]`\n - `progress: { failed: number; pending: number; succeeded: number; }`\n - `results: { expires_at: string; files: { bytes: number; items: number; url: string; }[]; }`\n - `status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'`\n - `tags: string[]`\n - `timing: { completed_at: string; created_at: string; started_at: 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 batch = await client.batch.retrieve('batch_9f2c8a');\n\nconsole.log(batch);\n```", perLanguage: { typescript: { method: 'client.batch.retrieve', @@ -2078,9 +2086,9 @@ const EMBEDDED_METHODS: MethodEntry[] = [ qualified: 'client.batch.getResults', params: ['batch_id: string;', 'cursor?: string;', 'limit?: number;'], response: - "{ data?: { final_url: string; http_status: number; metadata: { finalUrl: string; sourceUrl: 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; title?: string; twitter?: object; }; status: 'ok'; url: string; html?: string; itemId?: string; markdown?: string; meta?: object; } | { error_code: string; message: string; status: 'error'; url: string; itemId?: string; meta?: object; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }", + "{ data?: { final_url: string; http_status: number; metadata: { finalUrl: string; sourceUrl: 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; title?: string; twitter?: object; }; status: 'ok'; url: string; html?: string; itemId?: string; markdown?: string; meta?: object; ocr_pages?: number; } | { error_code: string; message: string; status: 'error'; url: string; itemId?: string; meta?: object; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }", markdown: - "## get_results\n\n`client.batch.getResults(batch_id: string, cursor?: string, limit?: number): { data?: object | object[]; has_more?: boolean; key_metadata?: object; next_cursor?: string; }`\n\n**get** `/batch/{batch_id}/results`\n\nPage through a finished batch's results as JSON instead of downloading the NDJSON files.\n\n### Parameters\n\n- `batch_id: string`\n ID of the batch to retrieve or cancel.\n\n- `cursor?: string`\n next_cursor from the previous page.\n\n- `limit?: number`\n Records per page. Defaults to 25. A page can close early so its payload stays under ~8 MB; rely on next_cursor rather than counting records.\n\n### Returns\n\n- `{ data?: { final_url: string; http_status: number; metadata: { finalUrl: string; sourceUrl: 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; title?: string; twitter?: object; }; status: 'ok'; url: string; html?: string; itemId?: string; markdown?: string; meta?: object; } | { error_code: string; message: string; status: 'error'; url: string; itemId?: string; meta?: object; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }`\n\n - `data?: { final_url: string; http_status: number; 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; }; status: 'ok'; url: string; html?: string; itemId?: string; markdown?: string; meta?: object; } | { error_code: string; message: string; status: 'error'; url: string; itemId?: string; meta?: object; }[]`\n - `has_more?: boolean`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\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.batch.getResults('batch_9f2c8a');\n\nconsole.log(response);\n```", + "## get_results\n\n`client.batch.getResults(batch_id: string, cursor?: string, limit?: number): { data?: object | object[]; has_more?: boolean; key_metadata?: object; next_cursor?: string; }`\n\n**get** `/batch/{batch_id}/results`\n\nPage through a finished batch's results as JSON instead of downloading the NDJSON files.\n\n### Parameters\n\n- `batch_id: string`\n ID of the batch to retrieve or cancel.\n\n- `cursor?: string`\n next_cursor from the previous page.\n\n- `limit?: number`\n Records per page. Defaults to 25. A page can close early so its payload stays under ~8 MB; rely on next_cursor rather than counting records.\n\n### Returns\n\n- `{ data?: { final_url: string; http_status: number; metadata: { finalUrl: string; sourceUrl: 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; title?: string; twitter?: object; }; status: 'ok'; url: string; html?: string; itemId?: string; markdown?: string; meta?: object; ocr_pages?: number; } | { error_code: string; message: string; status: 'error'; url: string; itemId?: string; meta?: object; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }`\n\n - `data?: { final_url: string; http_status: number; 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; }; status: 'ok'; url: string; html?: string; itemId?: string; markdown?: string; meta?: object; ocr_pages?: number; } | { error_code: string; message: string; status: 'error'; url: string; itemId?: string; meta?: object; }[]`\n - `has_more?: boolean`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\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.batch.getResults('batch_9f2c8a');\n\nconsole.log(response);\n```", perLanguage: { typescript: { method: 'client.batch.getResults', @@ -2167,6 +2175,115 @@ const EMBEDDED_METHODS: MethodEntry[] = [ }, }, }, + { + name: 'delete', + endpoint: '/batch/{batch_id}', + httpMethod: 'delete', + summary: 'Delete a batch', + description: + 'Permanently delete a finished batch and its stored results. Active batches must settle first.', + stainlessPath: '(resource) batch > (method) delete', + qualified: 'client.batch.delete', + params: ['batch_id: string;'], + response: + '{ id?: string; deleted?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }', + markdown: + "## delete\n\n`client.batch.delete(batch_id: string): { id?: string; deleted?: boolean; key_metadata?: object; }`\n\n**delete** `/batch/{batch_id}`\n\nPermanently delete a finished batch and its stored results. Active batches must settle first.\n\n### Parameters\n\n- `batch_id: string`\n ID of the batch to retrieve or cancel.\n\n### Returns\n\n- `{ id?: string; deleted?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `id?: string`\n - `deleted?: boolean`\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 batch = await client.batch.delete('batch_9f2c8a');\n\nconsole.log(batch);\n```", + perLanguage: { + typescript: { + method: 'client.batch.delete', + 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 batch = await client.batch.delete('batch_9f2c8a');\n\nconsole.log(batch.id);", + }, + python: { + method: 'batch.delete', + 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)\nbatch = client.batch.delete(\n "batch_9f2c8a",\n)\nprint(batch.id)', + }, + go: { + method: 'client.Batch.Delete', + 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\tbatch, err := client.Batch.Delete(context.TODO(), "batch_9f2c8a")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", batch.ID)\n}\n', + }, + ruby: { + method: 'batch.delete', + example: + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nbatch = context_dev.batch.delete("batch_9f2c8a")\n\nputs(batch)', + }, + cli: { + method: 'batch delete', + example: "context-dev batch delete \\\n --api-key 'My API Key' \\\n --batch-id batch_9f2c8a", + }, + php: { + method: 'batch->delete', + example: + "batch->delete('batch_9f2c8a');\n\nvar_dump($batch);", + }, + http: { + example: + 'curl https://api.context.dev/v1/batch/$BATCH_ID \\\n -X DELETE \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY"', + }, + }, + }, + { + name: 'enrich', + endpoint: '/people/enrich', + httpMethod: 'post', + summary: 'Enrich Person', + description: + 'Finds and normalizes the best available person candidate from additive identity clues, then assigns an identity match score from 0 to 100. Available on all paid plans. Successful requests cost 20 credits. Disposable and free email addresses (like gmail.com, yahoo.com) will throw a 422 error.', + stainlessPath: '(resource) people > (method) enrich', + qualified: 'client.people.enrich', + params: [ + 'company?: { domain?: string; name?: string; };', + 'education?: { degree?: string; field_of_study?: string; graduation_year?: number; institution?: { domain?: string; name?: string; }; }[];', + 'email?: string;', + 'location?: { city?: string; country?: string; region?: string; };', + 'name?: { first?: string; last?: string; };', + 'social_urls?: string[];', + 'tags?: string[];', + 'timeoutMS?: number;', + ], + response: + "{ match: { person: { education: object[]; experience: object[]; skills: string[]; social_urls: string[]; website_urls: string[]; avatar_url?: string; bio?: string; current_role?: object; email?: string; location?: object; name?: object; }; score: number; status: 'candidate'; } | { person: null; score: null; status: 'not_found'; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }", + markdown: + "## enrich\n\n`client.people.enrich(company?: { domain?: string; name?: string; }, education?: { degree?: string; field_of_study?: string; graduation_year?: number; institution?: { domain?: string; name?: string; }; }[], email?: string, location?: { city?: string; country?: string; region?: string; }, name?: { first?: string; last?: string; }, social_urls?: string[], tags?: string[], timeoutMS?: number): { match: object | object; key_metadata?: object; }`\n\n**post** `/people/enrich`\n\nFinds and normalizes the best available person candidate from additive identity clues, then assigns an identity match score from 0 to 100. Available on all paid plans. Successful requests cost 20 credits. Disposable and free email addresses (like gmail.com, yahoo.com) will throw a 422 error.\n\n### Parameters\n\n- `company?: { domain?: string; name?: string; }`\n - `domain?: string`\n - `name?: string`\n\n- `education?: { degree?: string; field_of_study?: string; graduation_year?: number; institution?: { domain?: string; name?: string; }; }[]`\n\n- `email?: string`\n\n- `location?: { city?: string; country?: string; region?: string; }`\n - `city?: string`\n - `country?: string`\n - `region?: string`\n\n- `name?: { first?: string; last?: string; }`\n - `first?: string`\n - `last?: string`\n\n- `social_urls?: string[]`\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- `{ match: { person: { education: object[]; experience: object[]; skills: string[]; social_urls: string[]; website_urls: string[]; avatar_url?: string; bio?: string; current_role?: object; email?: string; location?: object; name?: object; }; score: number; status: 'candidate'; } | { person: null; score: null; status: 'not_found'; }; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `match: { person: { education: { institution: { name: string; domain?: string; }; degree?: string; description?: string; end_date?: { year: number; day?: number; month?: number; }; field_of_study?: string; start_date?: { year: number; day?: number; month?: number; }; }[]; experience: { organization: { name: string; domain?: string; }; title: string; description?: string; end_date?: { year: number; day?: number; month?: number; }; is_current?: boolean; location?: string; start_date?: { year: number; day?: number; month?: number; }; }[]; skills: string[]; social_urls: string[]; website_urls: string[]; avatar_url?: string; bio?: string; current_role?: { organization: { name: string; domain?: string; }; title: string; description?: string; end_date?: { year: number; day?: number; month?: number; }; is_current?: boolean; location?: string; start_date?: { year: number; day?: number; month?: number; }; }; email?: string; location?: { city?: string; country?: string; country_code?: string; display?: string; region?: string; }; name?: { first?: string; full?: string; last?: string; }; }; score: number; status: 'candidate'; } | { person: null; score: null; status: 'not_found'; }`\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.people.enrich();\n\nconsole.log(response);\n```", + perLanguage: { + typescript: { + method: 'client.people.enrich', + 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.people.enrich({\n company: { name: 'Analytical Engines', domain: 'analyticalengines.example' },\n name: { first: 'Ada', last: 'Lovelace' },\n social_urls: ['https://www.linkedin.com/in/ada-lovelace/'],\n});\n\nconsole.log(response.match);", + }, + python: { + method: 'people.enrich', + 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.people.enrich(\n company={\n "name": "Analytical Engines",\n "domain": "analyticalengines.example",\n },\n name={\n "first": "Ada",\n "last": "Lovelace",\n },\n social_urls=["https://www.linkedin.com/in/ada-lovelace/"],\n)\nprint(response.match)', + }, + go: { + method: 'client.People.Enrich', + 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.People.Enrich(context.TODO(), contextdev.PersonEnrichParams{\n\t\tCompany: contextdev.PersonEnrichParamsCompany{\n\t\t\tName: contextdev.String("Analytical Engines"),\n\t\t\tDomain: contextdev.String("analyticalengines.example"),\n\t\t},\n\t\tName: contextdev.PersonEnrichParamsName{\n\t\t\tFirst: contextdev.String("Ada"),\n\t\t\tLast: contextdev.String("Lovelace"),\n\t\t},\n\t\tSocialURLs: []string{"https://www.linkedin.com/in/ada-lovelace/"},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Match)\n}\n', + }, + ruby: { + method: 'people.enrich', + example: + 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.people.enrich\n\nputs(response)', + }, + cli: { + method: 'people enrich', + example: "context-dev people enrich \\\n --api-key 'My API Key'", + }, + php: { + method: 'people->enrich', + example: + "people->enrich(\n company: [\n 'domain' => 'analyticalengines.example', 'name' => 'Analytical Engines'\n ],\n education: [\n [\n 'degree' => 'x',\n 'fieldOfStudy' => 'x',\n 'graduationYear' => 1900,\n 'institution' => ['domain' => 'x', 'name' => 'x'],\n ],\n ],\n email: 'dev@stainless.com',\n location: ['city' => 'x', 'country' => 'x', 'region' => 'x'],\n name: ['first' => 'Ada', 'last' => 'Lovelace'],\n socialURLs: ['https://www.linkedin.com/in/ada-lovelace/'],\n tags: ['production', 'team-alpha'],\n timeoutMs: 1000,\n);\n\nvar_dump($response);", + }, + http: { + example: + 'curl https://api.context.dev/v1/people/enrich \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "company": {\n "domain": "analyticalengines.example",\n "name": "Analytical Engines"\n },\n "name": {\n "first": "Ada",\n "last": "Lovelace"\n },\n "social_urls": [\n "https://www.linkedin.com/in/ada-lovelace/"\n ],\n "tags": [\n "production",\n "team-alpha"\n ]\n }\'', + }, + }, + }, ]; const EMBEDDED_READMES: { language: string; content: string }[] = [ diff --git a/packages/mcp-server/src/methods.ts b/packages/mcp-server/src/methods.ts index 2489ea0..7efc229 100644 --- a/packages/mcp-server/src/methods.ts +++ b/packages/mcp-server/src/methods.ts @@ -220,6 +220,12 @@ export const sdkMethods: SdkMethod[] = [ httpMethod: 'get', httpPath: '/batch/list', }, + { + clientCallName: 'client.batch.delete', + fullyQualifiedName: 'batch.delete', + httpMethod: 'delete', + httpPath: '/batch/{batch_id}', + }, { clientCallName: 'client.batch.cancel', fullyQualifiedName: 'batch.cancel', @@ -236,7 +242,13 @@ export const sdkMethods: SdkMethod[] = [ clientCallName: 'client.batch.submit', fullyQualifiedName: 'batch.submit', httpMethod: 'post', - httpPath: '/people/retrieve', + httpPath: '/batch/submit', + }, + { + clientCallName: 'client.people.enrich', + fullyQualifiedName: 'people.enrich', + httpMethod: 'post', + httpPath: '/people/enrich', }, ]; diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts index 497490c..ed00e66 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.9.0', + version: '2.10.0', }, { instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }), diff --git a/src/client.ts b/src/client.ts index c955f7a..21a647b 100644 --- a/src/client.ts +++ b/src/client.ts @@ -27,6 +27,7 @@ import { import { Batch, BatchCancelResponse, + BatchDeleteResponse, BatchGetResultsParams, BatchGetResultsResponse, BatchListParams, @@ -81,6 +82,7 @@ import { WebhookDelivery, } from './resources/monitors'; import { Parse, ParseHandleParams, ParseHandleResponse } from './resources/parse'; +import { People, PersonEnrichParams, PersonEnrichResponse } from './resources/people'; import { Utility, UtilityPrefetchParams, UtilityPrefetchResponse } from './resources/utility'; import { Web, @@ -834,7 +836,11 @@ export class ContextDev { * Monitor pages, sitemaps, and extracted website data for exact or semantic changes. Webhook payloads are documented by the MonitorsChangeDetectedWebhookPayload and MonitorsRunCompletedWebhookPayload schemas. */ monitors: API.Monitors = new API.Monitors(this); + /** + * Scrape many pages or crawl a site asynchronously. + */ batch: API.Batch = new API.Batch(this); + people: API.People = new API.People(this); } ContextDev.Parse = Parse; @@ -845,6 +851,7 @@ ContextDev.Industry = Industry; ContextDev.Utility = Utility; ContextDev.Monitors = Monitors; ContextDev.Batch = Batch; +ContextDev.People = People; export declare namespace ContextDev { export type RequestOptions = Opts.RequestOptions; @@ -947,6 +954,7 @@ export declare namespace ContextDev { type Intake as Intake, type BatchRetrieveResponse as BatchRetrieveResponse, type BatchListResponse as BatchListResponse, + type BatchDeleteResponse as BatchDeleteResponse, type BatchCancelResponse as BatchCancelResponse, type BatchGetResultsResponse as BatchGetResultsResponse, type BatchSubmitResponse as BatchSubmitResponse, @@ -954,4 +962,10 @@ export declare namespace ContextDev { type BatchGetResultsParams as BatchGetResultsParams, type BatchSubmitParams as BatchSubmitParams, }; + + export { + People as People, + type PersonEnrichResponse as PersonEnrichResponse, + type PersonEnrichParams as PersonEnrichParams, + }; } diff --git a/src/resources/batch.ts b/src/resources/batch.ts index 5e3c915..79a9f56 100644 --- a/src/resources/batch.ts +++ b/src/resources/batch.ts @@ -3,9 +3,13 @@ import { APIResource } from '../core/resource'; import * as BatchAPI from './batch'; import { APIPromise } from '../core/api-promise'; +import { buildHeaders } from '../internal/headers'; import { RequestOptions } from '../internal/request-options'; import { path } from '../internal/utils/path'; +/** + * Scrape many pages or crawl a site asynchronously. + */ export class Batch extends APIResource { /** * Check progress, and get download links once the batch finishes. @@ -35,6 +39,19 @@ export class Batch extends APIResource { return this._client.get('/batch/list', { query, ...options }); } + /** + * Permanently delete a finished batch and its stored results. Active batches must + * settle first. + * + * @example + * ```ts + * const batch = await client.batch.delete('batch_9f2c8a'); + * ``` + */ + delete(batchID: string, options?: RequestOptions): APIPromise { + return this._client.delete(path`/batch/${batchID}`, options); + } + /** * Stop a batch from starting new pages. In-progress pages finish, and unused * credits are refunded. @@ -68,20 +85,40 @@ export class Batch extends APIResource { } /** - * Retrieve and normalize a person profile from identifiers. + * Scrape 25K URLs or crawl large websites asynchronously. * * @example * ```ts * const response = await client.batch.submit({ - * identifiers: { - * linkedinUrl: - * 'https://www.linkedin.com/in/yahia-bakour/', + * input: { + * data: { + * urls: [ + * { + * url: 'https://example.com/products/anvil', + * itemId: 'sku-1', + * meta: { category: 'tools' }, + * }, + * { + * url: 'https://example.com/products/hammer', + * itemId: 'sku-2', + * }, + * ], + * options: { useMainContentOnly: true }, + * }, * }, * }); * ``` */ - submit(body: BatchSubmitParams, options?: RequestOptions): APIPromise { - return this._client.post('/people/retrieve', { body, ...options }); + submit(params: BatchSubmitParams, options?: RequestOptions): APIPromise { + const { 'Idempotency-Key': idempotencyKey, ...body } = params; + return this._client.post('/batch/submit', { + body, + ...options, + headers: buildHeaders([ + { ...(idempotencyKey != null ? { 'Idempotency-Key': idempotencyKey } : undefined) }, + options?.headers, + ]), + }); } } @@ -141,7 +178,7 @@ export interface CrawlControls { /** * Where the crawl started. */ - source: CrawlControls.UnionMember0 | CrawlControls.UnionMember1; + source: CrawlControls.StartURL | CrawlControls.Sitemap; /** * RE2 pattern URLs had to match to be crawled. Null when the crawl set none. @@ -150,7 +187,10 @@ export interface CrawlControls { } export namespace CrawlControls { - export interface UnionMember0 { + /** + * The crawl discovered pages by following links from one URL. + */ + export interface StartURL { type: 'start_url'; /** @@ -159,7 +199,10 @@ export namespace CrawlControls { url: string; } - export interface UnionMember1 { + /** + * The crawl scraped the pages listed in the domain's sitemap. + */ + export interface Sitemap { /** * Domain whose sitemap supplied the pages. */ @@ -293,11 +336,17 @@ export namespace BatchRetrieveResponse { */ export interface Credits { /** - * `reserved` minus `refunded` — what the batch has cost so far. Equal to - * `reserved` until the batch settles. + * `reserved` minus `refunded` plus `ocr_charged` — what the batch has cost so far. + * Equal to `reserved` until the batch settles. */ net: number; + /** + * Credits charged for PDF pages recovered by OCR (pdf.ocr=true), 1 per recovered + * page, on top of `reserved`. Stays 0 until the batch settles. + */ + ocr_charged: number; + /** * Credits returned for pages that did not succeed. Stays 0 until the batch reaches * a final status, then settles in one movement. @@ -515,11 +564,17 @@ export namespace BatchListResponse { */ export interface Credits { /** - * `reserved` minus `refunded` — what the batch has cost so far. Equal to - * `reserved` until the batch settles. + * `reserved` minus `refunded` plus `ocr_charged` — what the batch has cost so far. + * Equal to `reserved` until the batch settles. */ net: number; + /** + * Credits charged for PDF pages recovered by OCR (pdf.ocr=true), 1 per recovered + * page, on top of `reserved`. Stays 0 until the batch settles. + */ + ocr_charged: number; + /** * Credits returned for pages that did not succeed. Stays 0 until the batch reaches * a final status, then settles in one movement. @@ -625,6 +680,42 @@ export namespace BatchListResponse { } } +export interface BatchDeleteResponse { + /** + * ID of the deleted batch. + */ + id?: string; + + /** + * Always true on success. + */ + deleted?: boolean; + + /** + * Metadata about the API key used for the request. Included in every response + * whenever a valid API key is provided, even when the response status is not 200. + */ + key_metadata?: BatchDeleteResponse.KeyMetadata; +} + +export namespace BatchDeleteResponse { + /** + * Metadata about the API key used for the request. Included in every response + * whenever a valid API key is provided, even when the response status is not 200. + */ + export interface KeyMetadata { + /** + * The number of credits consumed by this request. + */ + credits_consumed: number; + + /** + * The number of credits remaining for your organization after this request. + */ + credits_remaining: number; + } +} + export interface BatchCancelResponse { /** * Batch ID. @@ -824,6 +915,12 @@ export namespace BatchGetResultsResponse { * Caller-supplied metadata echoed from submission. */ meta?: { [key: string]: unknown }; + + /** + * PDF pages of this document recovered by OCR (pdf.ocr=true). Each recovered page + * bills 1 credit on top of the page base credit; absent when no OCR ran. + */ + ocr_pages?: number; } export namespace Ok { @@ -1007,448 +1104,1703 @@ export namespace BatchGetResultsResponse { export interface BatchSubmitResponse { /** - * HTTP status code. + * Batch ID. Poll GET /batch/{batch_id} with it. */ - code: 200; + id: string; /** - * Additional response details. + * The crawl controls as submitted, so the limits requested can be compared against + * what the crawl reached. */ - metadata: BatchSubmitResponse.Metadata; + crawl: CrawlControls | null; /** - * Retrieved person profile. + * When the batch was created. */ - person: BatchSubmitResponse.Person; + created_at: string; /** - * Response status. + * What accepting this batch cost. */ - status: 'ok'; + credits: BatchSubmitResponse.Credits; /** - * Metadata about the API key used for the request. Included in every response - * whenever a valid API key is provided, even when the response status is not 200. + * What each page will be returned as. + */ + format: 'markdown' | 'html'; + + /** + * What submission took in, and what it charged for. + */ + input: Intake; + + /** + * Rejected URLs, up to 100. These are not charged. + */ + invalid_urls: Array; + + /** + * How pages will be selected. + */ + mode: 'scrape' | 'crawl'; + + /** + * Always `queued`. An accepted batch has not started yet. + */ + status: 'queued'; + + /** + * Tags stored on the batch. + */ + tags: Array; + + /** + * API key usage for this request. */ key_metadata?: BatchSubmitResponse.KeyMetadata; + + /** + * Signing secret for the completion webhook, returned only here and never again. + * Store it now; it is not repeated by GET /batch/{batch_id}. + */ + webhook_secret?: string; } export namespace BatchSubmitResponse { /** - * Additional response details. + * What accepting this batch cost. */ - export interface Metadata { + export interface Credits { /** - * Identifiers returned for the person. + * Credits just debited from your balance. Whatever the batch does not spend is + * refunded when it settles. */ - identifiers: Metadata.Identifiers; + reserved: number; + } + export interface InvalidURL { /** - * Source categories checked. + * Why it was rejected. */ - sourcesAttempted: Array<'linkedin' | 'cv' | 'manual' | 'github' | 'other'>; + reason: string; /** - * Source categories with data. + * Rejected URL. */ - sourcesSucceeded: Array<'linkedin' | 'cv' | 'manual' | 'github' | 'other'>; + url: string; + } + /** + * API key usage for this request. + */ + export interface KeyMetadata { /** - * URLs reviewed for this profile. + * The number of credits consumed by this request. */ - urlsAnalyzed: Array; + credits_consumed: number; /** - * Personal website URL, when found. + * The number of credits remaining for your organization after this request. */ - personalWebsiteUrl?: string; + credits_remaining: number; } +} - export namespace Metadata { - /** - * Identifiers returned for the person. - */ - export interface Identifiers { - /** - * LinkedIn profile URL. - */ - linkedinUrl?: string; - } - } +export interface BatchListParams { + /** + * Cursor from the previous page. + */ + cursor?: string; /** - * Retrieved person profile. + * Batches per page. Defaults to 25. */ - export interface Person { - /** - * Education history. - */ - education: Array; + limit?: number; - /** - * Work history. - */ - experience: Array; + /** + * Free-text search term, matched against the batch id, crawl source (start URL or + * sitemap domain), and tags. + */ + q?: string; + + /** + * `prefix` for as-you-type prefix matching (default), `exact` for full-token + * matching. + */ + search_type?: 'exact' | 'prefix'; + + /** + * Filter by status. + */ + status?: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; + + /** + * Comma-separated list of tags to filter by (matches batches having any of them). + */ + tags?: string; +} + +export interface BatchGetResultsParams { + /** + * next_cursor from the previous page. + */ + cursor?: string; + + /** + * Records per page. Defaults to 25. A page can close early so its payload stays + * under ~8 MB; rely on next_cursor rather than counting records. + */ + limit?: number; +} +export interface BatchSubmitParams { + /** + * Body param: Choose a URL list or a site crawl. + */ + input: BatchSubmitParams.Scrape | BatchSubmitParams.Crawl; + + /** + * Body param: Tags stored on the batch. Filter the batch list by them later. + */ + tags?: Array; + + /** + * Body param: URL notified when the batch finishes. + */ + webhookUrl?: string; + + /** + * Header param: Any string unique to this submission. Retries with the same key + * return the original batch. + */ + 'Idempotency-Key'?: string; +} + +export namespace BatchSubmitParams { + /** + * Scrape up to 25K URLs in one batch. + */ + export interface Scrape { /** - * Core profile details. + * Pages to scrape and their output format. */ - profile: Person.Profile; + data: Scrape.Markdown | Scrape.HTML; /** - * Listed skills. + * Scrape the pages in `data.urls`. */ - skills: Array; + mode: 'scrape'; } - export namespace Person { - export interface Education { - /** - * School or institution name. - */ - institution: Education.Institution; - - /** - * Education dates. - */ - dates?: Education.Dates; - + export namespace Scrape { + /** + * Scrape the listed pages as Markdown. + */ + export interface Markdown { /** - * Additional education details. + * Return page content as Markdown. */ - description?: string; + format: 'markdown'; /** - * Area of study. + * Pages to scrape. Maximum 25000. */ - fieldOfStudy?: string; + urls: Array; /** - * Degree, certificate, or credential. + * Options for Markdown output. */ - qualification?: string; + options?: Markdown.Options; } - export namespace Education { + export namespace Markdown { /** - * School or institution name. + * A page to scrape, with optional data for matching results. */ - export interface Institution { + export interface URL { + /** + * Page URL to scrape. + */ + url: string; + /** - * Display name. + * Your ID for this page, returned with its result. The same URL can use different + * IDs. */ - display: string; + itemId?: string; /** - * Standardized name, when available. + * Custom JSON returned unchanged with this page result. */ - normalized?: string; + meta?: { [key: string]: unknown }; } /** - * Education dates. + * Options for Markdown output. */ - export interface Dates { + export interface Options { /** - * End date, when known. + * Fetch the target page through a residential proxy in this country (ISO 3166-1 + * alpha-2). */ - endDate?: Dates.EndDate; + country?: + | 'ad' + | 'ae' + | 'af' + | 'ag' + | 'ai' + | 'al' + | 'am' + | 'ao' + | 'ar' + | 'at' + | 'au' + | 'aw' + | 'az' + | 'ba' + | 'bb' + | 'bd' + | 'be' + | 'bf' + | 'bg' + | 'bh' + | 'bi' + | 'bj' + | 'bm' + | 'bn' + | 'bo' + | 'bq' + | 'br' + | 'bs' + | 'bw' + | 'by' + | 'bz' + | 'ca' + | 'cd' + | 'cf' + | 'cg' + | 'ch' + | 'ci' + | 'cl' + | 'cm' + | 'cn' + | 'co' + | 'cr' + | 'cv' + | 'cw' + | 'cy' + | 'cz' + | 'de' + | 'dj' + | 'dk' + | 'dm' + | 'do' + | 'dz' + | 'ec' + | 'ee' + | 'eg' + | 'es' + | 'et' + | 'fi' + | 'fj' + | 'fr' + | 'ga' + | 'gb' + | 'gd' + | 'ge' + | 'gf' + | 'gg' + | 'gh' + | 'gm' + | 'gn' + | 'gp' + | 'gq' + | 'gr' + | 'gt' + | 'gu' + | 'gw' + | 'gy' + | 'hk' + | 'hn' + | 'hr' + | 'ht' + | 'hu' + | 'id' + | 'ie' + | 'il' + | 'im' + | 'in' + | 'iq' + | 'ir' + | 'is' + | 'it' + | 'je' + | 'jm' + | 'jo' + | 'jp' + | 'ke' + | 'kg' + | 'kh' + | 'kn' + | 'kr' + | 'kw' + | 'ky' + | 'kz' + | 'la' + | 'lb' + | 'lc' + | 'lk' + | 'lr' + | 'ls' + | 'lt' + | 'lu' + | 'lv' + | 'ly' + | 'ma' + | 'mc' + | 'md' + | 'me' + | 'mf' + | 'mg' + | 'mk' + | 'ml' + | 'mm' + | 'mn' + | 'mo' + | 'mq' + | 'mr' + | 'mt' + | 'mu' + | 'mv' + | 'mw' + | 'mx' + | 'my' + | 'mz' + | 'na' + | 'nc' + | 'ne' + | 'ng' + | 'ni' + | 'nl' + | 'no' + | 'np' + | 'nz' + | 'om' + | 'pa' + | 'pe' + | 'pf' + | 'pg' + | 'ph' + | 'pk' + | 'pl' + | 'pr' + | 'ps' + | 'pt' + | 'py' + | 'qa' + | 're' + | 'ro' + | 'rs' + | 'ru' + | 'rw' + | 'sa' + | 'sc' + | 'sd' + | 'se' + | 'sg' + | 'si' + | 'sk' + | 'sl' + | 'sm' + | 'sn' + | 'so' + | 'sr' + | 'ss' + | 'st' + | 'sv' + | 'sx' + | 'sy' + | 'sz' + | 'tc' + | 'td' + | 'tg' + | 'th' + | 'tj' + | 'tl' + | 'tm' + | 'tn' + | 'tr' + | 'tt' + | 'tw' + | 'tz' + | 'ua' + | 'ug' + | 'us' + | 'uy' + | 'uz' + | 'vc' + | 've' + | 'vg' + | 'vi' + | 'vn' + | 'ye' + | 'yt' + | 'za' + | 'zm' + | 'zw'; /** - * Whether the entry is current. + * Remove elements matching these CSS selectors. Applied after `includeSelectors`, + * so an element matching both is removed. */ - isCurrent?: boolean; + excludeSelectors?: Array | null; /** - * Start date, when known. + * Include image references in the Markdown. */ - startDate?: Dates.StartDate; + includeImages?: boolean; + + /** + * Include links in the Markdown. + */ + includeLinks?: boolean; + + /** + * Keep only the subtrees matching these CSS selectors. Filtered pages are always + * fetched fresh, ignoring `maxAgeMs`. + */ + 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 | null; + + /** + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. + */ + pdf?: Options.Pdf; + + /** + * Wait briefly for CSS and transition animations to settle before extraction, on + * pages that render in a browser. + */ + settleAnimations?: boolean; + + /** + * Shorten inline base64 image data. + */ + shortenBase64Images?: boolean; + + /** + * Return the main content without navigation or footers. + */ + useMainContentOnly?: boolean; + + /** + * How long to wait after initial page load, in milliseconds. `0` waits 500 ms. + */ + waitForMs?: number; } - export namespace Dates { + export namespace Options { /** - * End date, when known. + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. */ - export interface EndDate { + export interface Pdf { /** - * Year value. + * 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. */ - year: number; + end?: number; /** - * Day value, when known. + * When true, OCR the selected PDF pages that have no usable text layer (scans), + * replacing each recovered page's text with the OCR result while pages with a real + * text layer keep it. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. When false, no OCR runs. */ - day?: number; + ocr?: boolean | 'true' | 'false'; /** - * Month value, when known. + * When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and + * a 400 PDF_SKIPPED is returned. */ - month?: number; + shouldParse?: boolean | 'true' | 'false'; + + /** + * First 1-based PDF page to parse. When omitted, parsing starts at the first page. + */ + start?: number; } + } + } + + /** + * Scrape the listed pages as HTML. + */ + export interface HTML { + /** + * Return page content as HTML. + */ + format: 'html'; + + /** + * Pages to scrape. Maximum 25000. + */ + urls: Array; + + /** + * Options for HTML output. + */ + options?: HTML.Options; + } + + export namespace HTML { + /** + * A page to scrape, with optional data for matching results. + */ + export interface URL { + /** + * Page URL to scrape. + */ + url: string; + + /** + * Your ID for this page, returned with its result. The same URL can use different + * IDs. + */ + itemId?: string; + + /** + * Custom JSON returned unchanged with this page result. + */ + meta?: { [key: string]: unknown }; + } + + /** + * Options for HTML output. + */ + export interface Options { + /** + * Fetch the target page through a residential proxy in this country (ISO 3166-1 + * alpha-2). + */ + country?: + | 'ad' + | 'ae' + | 'af' + | 'ag' + | 'ai' + | 'al' + | 'am' + | 'ao' + | 'ar' + | 'at' + | 'au' + | 'aw' + | 'az' + | 'ba' + | 'bb' + | 'bd' + | 'be' + | 'bf' + | 'bg' + | 'bh' + | 'bi' + | 'bj' + | 'bm' + | 'bn' + | 'bo' + | 'bq' + | 'br' + | 'bs' + | 'bw' + | 'by' + | 'bz' + | 'ca' + | 'cd' + | 'cf' + | 'cg' + | 'ch' + | 'ci' + | 'cl' + | 'cm' + | 'cn' + | 'co' + | 'cr' + | 'cv' + | 'cw' + | 'cy' + | 'cz' + | 'de' + | 'dj' + | 'dk' + | 'dm' + | 'do' + | 'dz' + | 'ec' + | 'ee' + | 'eg' + | 'es' + | 'et' + | 'fi' + | 'fj' + | 'fr' + | 'ga' + | 'gb' + | 'gd' + | 'ge' + | 'gf' + | 'gg' + | 'gh' + | 'gm' + | 'gn' + | 'gp' + | 'gq' + | 'gr' + | 'gt' + | 'gu' + | 'gw' + | 'gy' + | 'hk' + | 'hn' + | 'hr' + | 'ht' + | 'hu' + | 'id' + | 'ie' + | 'il' + | 'im' + | 'in' + | 'iq' + | 'ir' + | 'is' + | 'it' + | 'je' + | 'jm' + | 'jo' + | 'jp' + | 'ke' + | 'kg' + | 'kh' + | 'kn' + | 'kr' + | 'kw' + | 'ky' + | 'kz' + | 'la' + | 'lb' + | 'lc' + | 'lk' + | 'lr' + | 'ls' + | 'lt' + | 'lu' + | 'lv' + | 'ly' + | 'ma' + | 'mc' + | 'md' + | 'me' + | 'mf' + | 'mg' + | 'mk' + | 'ml' + | 'mm' + | 'mn' + | 'mo' + | 'mq' + | 'mr' + | 'mt' + | 'mu' + | 'mv' + | 'mw' + | 'mx' + | 'my' + | 'mz' + | 'na' + | 'nc' + | 'ne' + | 'ng' + | 'ni' + | 'nl' + | 'no' + | 'np' + | 'nz' + | 'om' + | 'pa' + | 'pe' + | 'pf' + | 'pg' + | 'ph' + | 'pk' + | 'pl' + | 'pr' + | 'ps' + | 'pt' + | 'py' + | 'qa' + | 're' + | 'ro' + | 'rs' + | 'ru' + | 'rw' + | 'sa' + | 'sc' + | 'sd' + | 'se' + | 'sg' + | 'si' + | 'sk' + | 'sl' + | 'sm' + | 'sn' + | 'so' + | 'sr' + | 'ss' + | 'st' + | 'sv' + | 'sx' + | 'sy' + | 'sz' + | 'tc' + | 'td' + | 'tg' + | 'th' + | 'tj' + | 'tl' + | 'tm' + | 'tn' + | 'tr' + | 'tt' + | 'tw' + | 'tz' + | 'ua' + | 'ug' + | 'us' + | 'uy' + | 'uz' + | 'vc' + | 've' + | 'vg' + | 'vi' + | 'vn' + | 'ye' + | 'yt' + | 'za' + | 'zm' + | 'zw'; + + /** + * Remove elements matching these CSS selectors. Applied after `includeSelectors`, + * so an element matching both is removed. + */ + excludeSelectors?: Array | null; /** - * Start date, when known. + * Keep only the subtrees matching these CSS selectors. Filtered pages are always + * fetched fresh, ignoring `maxAgeMs`. */ - export interface StartDate { + 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 | null; + + /** + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. + */ + pdf?: Options.Pdf; + + /** + * Wait briefly for CSS and transition animations to settle before extraction, on + * pages that render in a browser. + */ + settleAnimations?: boolean; + + /** + * Return the main content without navigation or footers. + */ + useMainContentOnly?: boolean; + + /** + * How long to wait after initial page load, in milliseconds. `0` waits 500 ms. + */ + waitForMs?: number; + } + + export namespace Options { + /** + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. + */ + export interface Pdf { + /** + * 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. + */ + end?: number; + /** - * Year value. + * When true, OCR the selected PDF pages that have no usable text layer (scans), + * replacing each recovered page's text with the OCR result while pages with a real + * text layer keep it. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. When false, no OCR runs. */ - year: number; + ocr?: boolean | 'true' | 'false'; /** - * Day value, when known. + * When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and + * a 400 PDF_SKIPPED is returned. */ - day?: number; + shouldParse?: boolean | 'true' | 'false'; /** - * Month value, when known. + * First 1-based PDF page to parse. When omitted, parsing starts at the first page. */ - month?: number; + start?: number; } } } + } - export interface Experience { - /** - * Company or organization name. - */ - company: Experience.Company; + /** + * Crawl pages starting from a URL or from a domain's sitemap. + */ + export interface Crawl { + /** + * Crawl source and output format. + */ + data: Crawl.Markdown | Crawl.HTML; + /** + * Discover and scrape pages from `data.source`. + */ + mode: 'crawl'; + } + + export namespace Crawl { + /** + * Crawl pages and return Markdown. + */ + export interface Markdown { /** - * Role or job title. + * Return page content as Markdown. */ - title: string; + format: 'markdown'; /** - * Role dates. + * How to find pages to crawl. */ - dates?: Experience.Dates; + source: Markdown.StartURL | Markdown.Sitemap; /** - * Role description. + * Options for Markdown output. */ - description?: string; + options?: Markdown.Options; } - export namespace Experience { + export namespace Markdown { /** - * Company or organization name. + * Discover pages by following links from one URL. */ - export interface Company { + export interface StartURL { /** - * Display name. + * Start from one page. */ - display: string; + type: 'start_url'; + + /** + * Page where crawling begins. A URL without a scheme is read as https://. + */ + url: string; /** - * Standardized name, when available. + * Limits and filters for page discovery. */ - normalized?: string; + controls?: StartURL.Controls; + } + + export namespace StartURL { + /** + * Limits and filters for page discovery. + */ + export interface Controls { + /** + * Follow links to subdomains. + */ + followSubdomains?: boolean; + + /** + * Maximum link depth. Source pages are depth 0. No limit when omitted. + */ + maxDepth?: number; + + /** + * Maximum pages to fetch. Unused reserved credits are refunded. Maximum 25000. + */ + maxUrls?: number; + + /** + * RE2 pattern for URLs to include. The `start_url` itself is always included. + */ + regex?: string; + } } /** - * Role dates. + * Scrape the pages listed in a domain's sitemap. Links on those pages are not + * followed. */ - export interface Dates { + export interface Sitemap { /** - * End date, when known. + * Domain whose sitemap lists the pages to scrape. A full URL is reduced to its + * domain. */ - endDate?: Dates.EndDate; + domain: string; /** - * Whether the entry is current. + * Scrape the URLs in the domain's sitemap. */ - isCurrent?: boolean; + type: 'sitemap'; /** - * Start date, when known. + * Limits and filters for the sitemap URLs. A sitemap batch scrapes exactly those + * URLs and never follows links off them, so there is no crawl depth here. */ - startDate?: Dates.StartDate; + controls?: Sitemap.Controls; } - export namespace Dates { + export namespace Sitemap { /** - * End date, when known. + * Limits and filters for the sitemap URLs. A sitemap batch scrapes exactly those + * URLs and never follows links off them, so there is no crawl depth here. */ - export interface EndDate { + export interface Controls { /** - * Year value. + * Maximum pages to fetch. Unused reserved credits are refunded. Maximum 25000. */ - year: number; + maxUrls?: number; /** - * Day value, when known. + * RE2 pattern; only sitemap URLs matching it are scraped. */ - day?: number; - - /** - * Month value, when known. - */ - month?: number; + regex?: string; } + } + /** + * Options for Markdown output. + */ + export interface Options { /** - * Start date, when known. + * Fetch the target page through a residential proxy in this country (ISO 3166-1 + * alpha-2). */ - export interface StartDate { + country?: + | 'ad' + | 'ae' + | 'af' + | 'ag' + | 'ai' + | 'al' + | 'am' + | 'ao' + | 'ar' + | 'at' + | 'au' + | 'aw' + | 'az' + | 'ba' + | 'bb' + | 'bd' + | 'be' + | 'bf' + | 'bg' + | 'bh' + | 'bi' + | 'bj' + | 'bm' + | 'bn' + | 'bo' + | 'bq' + | 'br' + | 'bs' + | 'bw' + | 'by' + | 'bz' + | 'ca' + | 'cd' + | 'cf' + | 'cg' + | 'ch' + | 'ci' + | 'cl' + | 'cm' + | 'cn' + | 'co' + | 'cr' + | 'cv' + | 'cw' + | 'cy' + | 'cz' + | 'de' + | 'dj' + | 'dk' + | 'dm' + | 'do' + | 'dz' + | 'ec' + | 'ee' + | 'eg' + | 'es' + | 'et' + | 'fi' + | 'fj' + | 'fr' + | 'ga' + | 'gb' + | 'gd' + | 'ge' + | 'gf' + | 'gg' + | 'gh' + | 'gm' + | 'gn' + | 'gp' + | 'gq' + | 'gr' + | 'gt' + | 'gu' + | 'gw' + | 'gy' + | 'hk' + | 'hn' + | 'hr' + | 'ht' + | 'hu' + | 'id' + | 'ie' + | 'il' + | 'im' + | 'in' + | 'iq' + | 'ir' + | 'is' + | 'it' + | 'je' + | 'jm' + | 'jo' + | 'jp' + | 'ke' + | 'kg' + | 'kh' + | 'kn' + | 'kr' + | 'kw' + | 'ky' + | 'kz' + | 'la' + | 'lb' + | 'lc' + | 'lk' + | 'lr' + | 'ls' + | 'lt' + | 'lu' + | 'lv' + | 'ly' + | 'ma' + | 'mc' + | 'md' + | 'me' + | 'mf' + | 'mg' + | 'mk' + | 'ml' + | 'mm' + | 'mn' + | 'mo' + | 'mq' + | 'mr' + | 'mt' + | 'mu' + | 'mv' + | 'mw' + | 'mx' + | 'my' + | 'mz' + | 'na' + | 'nc' + | 'ne' + | 'ng' + | 'ni' + | 'nl' + | 'no' + | 'np' + | 'nz' + | 'om' + | 'pa' + | 'pe' + | 'pf' + | 'pg' + | 'ph' + | 'pk' + | 'pl' + | 'pr' + | 'ps' + | 'pt' + | 'py' + | 'qa' + | 're' + | 'ro' + | 'rs' + | 'ru' + | 'rw' + | 'sa' + | 'sc' + | 'sd' + | 'se' + | 'sg' + | 'si' + | 'sk' + | 'sl' + | 'sm' + | 'sn' + | 'so' + | 'sr' + | 'ss' + | 'st' + | 'sv' + | 'sx' + | 'sy' + | 'sz' + | 'tc' + | 'td' + | 'tg' + | 'th' + | 'tj' + | 'tl' + | 'tm' + | 'tn' + | 'tr' + | 'tt' + | 'tw' + | 'tz' + | 'ua' + | 'ug' + | 'us' + | 'uy' + | 'uz' + | 'vc' + | 've' + | 'vg' + | 'vi' + | 'vn' + | 'ye' + | 'yt' + | 'za' + | 'zm' + | 'zw'; + + /** + * Remove elements matching these CSS selectors. Applied after `includeSelectors`, + * so an element matching both is removed. + */ + excludeSelectors?: Array | null; + + /** + * Include image references in the Markdown. + */ + includeImages?: boolean; + + /** + * Include links in the Markdown. + */ + includeLinks?: boolean; + + /** + * Keep only the subtrees matching these CSS selectors. Filtered pages are always + * fetched fresh, ignoring `maxAgeMs`. + */ + 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 | null; + + /** + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. + */ + pdf?: Options.Pdf; + + /** + * Wait briefly for CSS and transition animations to settle before extraction, on + * pages that render in a browser. + */ + settleAnimations?: boolean; + + /** + * Shorten inline base64 image data. + */ + shortenBase64Images?: boolean; + + /** + * Return the main content without navigation or footers. + */ + useMainContentOnly?: boolean; + + /** + * How long to wait after initial page load, in milliseconds. `0` waits 500 ms. + */ + waitForMs?: number; + } + + export namespace Options { + /** + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. + */ + export interface Pdf { + /** + * 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. + */ + end?: number; + /** - * Year value. + * When true, OCR the selected PDF pages that have no usable text layer (scans), + * replacing each recovered page's text with the OCR result while pages with a real + * text layer keep it. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. When false, no OCR runs. */ - year: number; + ocr?: boolean | 'true' | 'false'; /** - * Day value, when known. + * When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and + * a 400 PDF_SKIPPED is returned. */ - day?: number; + shouldParse?: boolean | 'true' | 'false'; /** - * Month value, when known. + * First 1-based PDF page to parse. When omitted, parsing starts at the first page. */ - month?: number; + start?: number; } } } /** - * Core profile details. + * Crawl pages and return HTML. */ - export interface Profile { + export interface HTML { /** - * Person's full name. + * Return page content as HTML. */ - fullName?: string; + format: 'html'; /** - * Short professional headline. + * How to find pages to crawl. */ - headline?: string; + source: HTML.StartURL | HTML.Sitemap; /** - * Person's listed location. + * Options for HTML output. */ - location?: string; + options?: HTML.Options; + } + export namespace HTML { /** - * Profile image URL. + * Discover pages by following links from one URL. */ - profilePictureUrl?: string; + export interface StartURL { + /** + * Start from one page. + */ + type: 'start_url'; - /** - * Brief profile summary. - */ - summary?: string; - } + /** + * Page where crawling begins. A URL without a scheme is read as https://. + */ + url: string; - export interface Skill { - /** - * Skill name. - */ - name: string; + /** + * Limits and filters for page discovery. + */ + controls?: StartURL.Controls; + } - /** - * Standardized skill name, when available. - */ - normalized?: string; + export namespace StartURL { + /** + * Limits and filters for page discovery. + */ + export interface Controls { + /** + * Follow links to subdomains. + */ + followSubdomains?: boolean; + + /** + * Maximum link depth. Source pages are depth 0. No limit when omitted. + */ + maxDepth?: number; + + /** + * Maximum pages to fetch. Unused reserved credits are refunded. Maximum 25000. + */ + maxUrls?: number; + + /** + * RE2 pattern for URLs to include. The `start_url` itself is always included. + */ + regex?: string; + } + } /** - * Skill proficiency, when available. + * Scrape the pages listed in a domain's sitemap. Links on those pages are not + * followed. */ - proficiency?: string; - } - } + export interface Sitemap { + /** + * Domain whose sitemap lists the pages to scrape. A full URL is reduced to its + * domain. + */ + domain: string; - /** - * Metadata about the API key used for the request. Included in every response - * whenever a valid API key is provided, even when the response status is not 200. - */ - export interface KeyMetadata { - /** - * The number of credits consumed by this request. - */ - credits_consumed: number; + /** + * Scrape the URLs in the domain's sitemap. + */ + type: 'sitemap'; - /** - * The number of credits remaining for your organization after this request. - */ - credits_remaining: number; - } -} + /** + * Limits and filters for the sitemap URLs. A sitemap batch scrapes exactly those + * URLs and never follows links off them, so there is no crawl depth here. + */ + controls?: Sitemap.Controls; + } -export interface BatchListParams { - /** - * Cursor from the previous page. - */ - cursor?: string; + export namespace Sitemap { + /** + * Limits and filters for the sitemap URLs. A sitemap batch scrapes exactly those + * URLs and never follows links off them, so there is no crawl depth here. + */ + export interface Controls { + /** + * Maximum pages to fetch. Unused reserved credits are refunded. Maximum 25000. + */ + maxUrls?: number; - /** - * Batches per page. Defaults to 25. - */ - limit?: number; + /** + * RE2 pattern; only sitemap URLs matching it are scraped. + */ + regex?: string; + } + } - /** - * Free-text search term, matched against the batch id, crawl source (start URL or - * sitemap domain), and tags. - */ - q?: string; + /** + * Options for HTML output. + */ + export interface Options { + /** + * Fetch the target page through a residential proxy in this country (ISO 3166-1 + * alpha-2). + */ + country?: + | 'ad' + | 'ae' + | 'af' + | 'ag' + | 'ai' + | 'al' + | 'am' + | 'ao' + | 'ar' + | 'at' + | 'au' + | 'aw' + | 'az' + | 'ba' + | 'bb' + | 'bd' + | 'be' + | 'bf' + | 'bg' + | 'bh' + | 'bi' + | 'bj' + | 'bm' + | 'bn' + | 'bo' + | 'bq' + | 'br' + | 'bs' + | 'bw' + | 'by' + | 'bz' + | 'ca' + | 'cd' + | 'cf' + | 'cg' + | 'ch' + | 'ci' + | 'cl' + | 'cm' + | 'cn' + | 'co' + | 'cr' + | 'cv' + | 'cw' + | 'cy' + | 'cz' + | 'de' + | 'dj' + | 'dk' + | 'dm' + | 'do' + | 'dz' + | 'ec' + | 'ee' + | 'eg' + | 'es' + | 'et' + | 'fi' + | 'fj' + | 'fr' + | 'ga' + | 'gb' + | 'gd' + | 'ge' + | 'gf' + | 'gg' + | 'gh' + | 'gm' + | 'gn' + | 'gp' + | 'gq' + | 'gr' + | 'gt' + | 'gu' + | 'gw' + | 'gy' + | 'hk' + | 'hn' + | 'hr' + | 'ht' + | 'hu' + | 'id' + | 'ie' + | 'il' + | 'im' + | 'in' + | 'iq' + | 'ir' + | 'is' + | 'it' + | 'je' + | 'jm' + | 'jo' + | 'jp' + | 'ke' + | 'kg' + | 'kh' + | 'kn' + | 'kr' + | 'kw' + | 'ky' + | 'kz' + | 'la' + | 'lb' + | 'lc' + | 'lk' + | 'lr' + | 'ls' + | 'lt' + | 'lu' + | 'lv' + | 'ly' + | 'ma' + | 'mc' + | 'md' + | 'me' + | 'mf' + | 'mg' + | 'mk' + | 'ml' + | 'mm' + | 'mn' + | 'mo' + | 'mq' + | 'mr' + | 'mt' + | 'mu' + | 'mv' + | 'mw' + | 'mx' + | 'my' + | 'mz' + | 'na' + | 'nc' + | 'ne' + | 'ng' + | 'ni' + | 'nl' + | 'no' + | 'np' + | 'nz' + | 'om' + | 'pa' + | 'pe' + | 'pf' + | 'pg' + | 'ph' + | 'pk' + | 'pl' + | 'pr' + | 'ps' + | 'pt' + | 'py' + | 'qa' + | 're' + | 'ro' + | 'rs' + | 'ru' + | 'rw' + | 'sa' + | 'sc' + | 'sd' + | 'se' + | 'sg' + | 'si' + | 'sk' + | 'sl' + | 'sm' + | 'sn' + | 'so' + | 'sr' + | 'ss' + | 'st' + | 'sv' + | 'sx' + | 'sy' + | 'sz' + | 'tc' + | 'td' + | 'tg' + | 'th' + | 'tj' + | 'tl' + | 'tm' + | 'tn' + | 'tr' + | 'tt' + | 'tw' + | 'tz' + | 'ua' + | 'ug' + | 'us' + | 'uy' + | 'uz' + | 'vc' + | 've' + | 'vg' + | 'vi' + | 'vn' + | 'ye' + | 'yt' + | 'za' + | 'zm' + | 'zw'; - /** - * `prefix` for as-you-type prefix matching (default), `exact` for full-token - * matching. - */ - search_type?: 'exact' | 'prefix'; + /** + * Remove elements matching these CSS selectors. Applied after `includeSelectors`, + * so an element matching both is removed. + */ + excludeSelectors?: Array | null; - /** - * Filter by status. - */ - status?: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; + /** + * Keep only the subtrees matching these CSS selectors. Filtered pages are always + * fetched fresh, ignoring `maxAgeMs`. + */ + includeSelectors?: Array | null; - /** - * Comma-separated list of tags to filter by (matches batches having any of them). - */ - tags?: string; -} + /** + * 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 | null; -export interface BatchGetResultsParams { - /** - * next_cursor from the previous page. - */ - cursor?: string; + /** + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. + */ + pdf?: Options.Pdf; - /** - * Records per page. Defaults to 25. A page can close early so its payload stays - * under ~8 MB; rely on next_cursor rather than counting records. - */ - limit?: number; -} + /** + * Wait briefly for CSS and transition animations to settle before extraction, on + * pages that render in a browser. + */ + settleAnimations?: boolean; -export interface BatchSubmitParams { - /** - * Known identifiers for the person. At least one identifier is required. - */ - identifiers: BatchSubmitParams.Identifiers; + /** + * Return the main content without navigation or footers. + */ + useMainContentOnly?: boolean; - /** - * Optional tags for tracking usage. Up to 20 tags, each 1 to 50 characters. - */ - tags?: Array; + /** + * How long to wait after initial page load, in milliseconds. `0` waits 500 ms. + */ + waitForMs?: number; + } - /** - * 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). - */ - timeoutMS?: number; -} + export namespace Options { + /** + * PDF parsing controls. Use start/end to limit text extraction and embedded-image + * detection/OCR to an inclusive 1-based page range. + */ + export interface Pdf { + /** + * 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. + */ + end?: number; -export namespace BatchSubmitParams { - /** - * Known identifiers for the person. At least one identifier is required. - */ - export interface Identifiers { - /** - * LinkedIn profile URL, e.g. https://www.linkedin.com/in/yahia-bakour/. - */ - linkedinUrl?: string; + /** + * When true, OCR the selected PDF pages that have no usable text layer (scans), + * replacing each recovered page's text with the OCR result while pages with a real + * text layer keep it. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. When false, no OCR runs. + */ + ocr?: boolean | 'true' | 'false'; + + /** + * When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and + * a 400 PDF_SKIPPED is returned. + */ + shouldParse?: boolean | 'true' | 'false'; + + /** + * First 1-based PDF page to parse. When omitted, parsing starts at the first page. + */ + start?: number; + } + } + } } } @@ -1460,6 +2812,7 @@ export declare namespace Batch { type Intake as Intake, type BatchRetrieveResponse as BatchRetrieveResponse, type BatchListResponse as BatchListResponse, + type BatchDeleteResponse as BatchDeleteResponse, type BatchCancelResponse as BatchCancelResponse, type BatchGetResultsResponse as BatchGetResultsResponse, type BatchSubmitResponse as BatchSubmitResponse, diff --git a/src/resources/brand.ts b/src/resources/brand.ts index 9435c22..5d18c61 100644 --- a/src/resources/brand.ts +++ b/src/resources/brand.ts @@ -45,7 +45,8 @@ export class Brand extends APIResource { /** * Search brands by name or domain and get back up to 10 lightweight matches - * (domain, name, logo), most popular first: by Tranco rank, then market cap for + * (domain, name, logo). Name matches rank ahead of domain matches; within each + * group the most popular brands come first: by Tranco rank, then market cap for * brands outside the Tranco list, with text relevance breaking ties. Matching is * prefix-based with no typo tolerance, so it is suited to autocomplete. Only * brands already in the Context.dev index are returned — use /brand/retrieve to @@ -120,6 +121,11 @@ export namespace BrandRetrieveResponse { */ email?: string; + /** + * Employee headcount information for the brand (will be null if unknown) + */ + employees?: Brand.Employees; + /** * Industry classification information for the brand */ @@ -397,6 +403,29 @@ export namespace BrandRetrieveResponse { name?: string; } + /** + * Employee headcount information for the brand (will be null if unknown) + */ + export interface Employees { + /** + * Exact employee count when a precise headcount is known + */ + exact?: number; + + /** + * Employee count range for the brand (e.g. '11 to 50') + */ + range?: + | '1 to 10' + | '11 to 50' + | '51 to 200' + | '201 to 500' + | '501 to 1000' + | '1001 to 5000' + | '5001 to 10000' + | '10001+'; + } + /** * Industry classification information for the brand */ @@ -1041,7 +1070,8 @@ export namespace BrandRetrieveSimplifiedResponse { export interface BrandSearchResponse { /** - * Up to 10 matching brands, most popular first. Empty when nothing matches. + * Up to 10 matching brands, name matches first, then domain matches, most popular + * first within each group. Empty when nothing matches. */ results: Array; diff --git a/src/resources/index.ts b/src/resources/index.ts index e8048a9..0f06939 100644 --- a/src/resources/index.ts +++ b/src/resources/index.ts @@ -15,6 +15,7 @@ export { type Intake, type BatchRetrieveResponse, type BatchListResponse, + type BatchDeleteResponse, type BatchCancelResponse, type BatchGetResultsResponse, type BatchSubmitResponse, @@ -64,6 +65,7 @@ export { type MonitorListRunsParams, } from './monitors'; export { Parse, type ParseHandleResponse, type ParseHandleParams } from './parse'; +export { People, type PersonEnrichResponse, type PersonEnrichParams } from './people'; export { Utility, type UtilityPrefetchResponse, type UtilityPrefetchParams } from './utility'; export { Web, diff --git a/src/resources/parse.ts b/src/resources/parse.ts index efcfc65..d841e44 100644 --- a/src/resources/parse.ts +++ b/src/resources/parse.ts @@ -223,11 +223,11 @@ export interface ParseHandleParams { includeLinks?: boolean | 'true' | 'false'; /** - * 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. + * Query param: When true for PDF inputs, OCR the selected pages that have no + * usable text layer (scans), replacing each recovered page's text with the OCR + * result while pages with a real text layer keep it. pdf.start/pdf.end limit the + * inclusive page range. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. When false, no OCR runs. */ ocr?: boolean | 'true' | 'false'; diff --git a/src/resources/people.ts b/src/resources/people.ts new file mode 100644 index 0000000..16096b8 --- /dev/null +++ b/src/resources/people.ts @@ -0,0 +1,322 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import { APIResource } from '../core/resource'; +import { APIPromise } from '../core/api-promise'; +import { RequestOptions } from '../internal/request-options'; + +export class People extends APIResource { + /** + * Finds and normalizes the best available person candidate from additive identity + * clues, then assigns an identity match score from 0 to 100. Available on all paid + * plans. Successful requests cost 20 credits. Disposable and free email addresses + * (like gmail.com, yahoo.com) will throw a 422 error. + * + * @example + * ```ts + * const response = await client.people.enrich({ + * company: { + * name: 'Analytical Engines', + * domain: 'analyticalengines.example', + * }, + * name: { first: 'Ada', last: 'Lovelace' }, + * social_urls: [ + * 'https://www.linkedin.com/in/ada-lovelace/', + * ], + * }); + * ``` + */ + enrich(body: PersonEnrichParams, options?: RequestOptions): APIPromise { + return this._client.post('/people/enrich', { body, ...options }); + } +} + +export interface PersonEnrichResponse { + /** + * The highest-scoring person candidate. + */ + match: + | PersonEnrichResponse.PersonEnrichmentCandidateMatch + | PersonEnrichResponse.PersonEnrichmentNotFoundMatch; + + /** + * Metadata about the API key used for the request. Included in every response + * whenever a valid API key is provided, even when the response status is not 200. + */ + key_metadata?: PersonEnrichResponse.KeyMetadata; +} + +export namespace PersonEnrichResponse { + /** + * The highest-scoring person candidate. + */ + export interface PersonEnrichmentCandidateMatch { + person: PersonEnrichmentCandidateMatch.Person; + + score: number; + + status: 'candidate'; + } + + export namespace PersonEnrichmentCandidateMatch { + export interface Person { + education: Array; + + experience: Array; + + skills: Array; + + social_urls: Array; + + website_urls: Array; + + avatar_url?: string; + + bio?: string; + + current_role?: Person.CurrentRole; + + email?: string; + + location?: Person.Location; + + name?: Person.Name; + } + + export namespace Person { + export interface Education { + institution: Education.Institution; + + degree?: string; + + description?: string; + + end_date?: Education.EndDate; + + field_of_study?: string; + + start_date?: Education.StartDate; + } + + export namespace Education { + export interface Institution { + name: string; + + domain?: string; + } + + export interface EndDate { + year: number; + + day?: number; + + month?: number; + } + + export interface StartDate { + year: number; + + day?: number; + + month?: number; + } + } + + export interface Experience { + organization: Experience.Organization; + + title: string; + + description?: string; + + end_date?: Experience.EndDate; + + is_current?: boolean; + + location?: string; + + start_date?: Experience.StartDate; + } + + export namespace Experience { + export interface Organization { + name: string; + + domain?: string; + } + + export interface EndDate { + year: number; + + day?: number; + + month?: number; + } + + export interface StartDate { + year: number; + + day?: number; + + month?: number; + } + } + + export interface CurrentRole { + organization: CurrentRole.Organization; + + title: string; + + description?: string; + + end_date?: CurrentRole.EndDate; + + is_current?: boolean; + + location?: string; + + start_date?: CurrentRole.StartDate; + } + + export namespace CurrentRole { + export interface Organization { + name: string; + + domain?: string; + } + + export interface EndDate { + year: number; + + day?: number; + + month?: number; + } + + export interface StartDate { + year: number; + + day?: number; + + month?: number; + } + } + + export interface Location { + city?: string; + + country?: string; + + country_code?: string; + + display?: string; + + region?: string; + } + + export interface Name { + first?: string; + + full?: string; + + last?: string; + } + } + } + + /** + * No usable person candidate was found. + */ + export interface PersonEnrichmentNotFoundMatch { + person: null; + + score: null; + + status: 'not_found'; + } + + /** + * Metadata about the API key used for the request. Included in every response + * whenever a valid API key is provided, even when the response status is not 200. + */ + export interface KeyMetadata { + /** + * The number of credits consumed by this request. + */ + credits_consumed: number; + + /** + * The number of credits remaining for your organization after this request. + */ + credits_remaining: number; + } +} + +export interface PersonEnrichParams { + company?: PersonEnrichParams.Company; + + education?: Array; + + email?: string; + + location?: PersonEnrichParams.Location; + + name?: PersonEnrichParams.Name; + + social_urls?: Array; + + /** + * 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 + * value is 300000ms (5 minutes). + */ + timeoutMS?: number; +} + +export namespace PersonEnrichParams { + export interface Company { + domain?: string; + + name?: string; + } + + export interface Education { + degree?: string; + + field_of_study?: string; + + graduation_year?: number; + + institution?: Education.Institution; + } + + export namespace Education { + export interface Institution { + domain?: string; + + name?: string; + } + } + + export interface Location { + city?: string; + + country?: string; + + region?: string; + } + + export interface Name { + first?: string; + + last?: string; + } +} + +export declare namespace People { + export { type PersonEnrichResponse as PersonEnrichResponse, type PersonEnrichParams as PersonEnrichParams }; +} diff --git a/src/resources/web.ts b/src/resources/web.ts index 53cf9ec..4145f32 100644 --- a/src/resources/web.ts +++ b/src/resources/web.ts @@ -162,6 +162,18 @@ export class Web extends APIResource { * responses from a recognized API key; use error_code to distinguish stable * failure categories. * + * ### YouTube + * + * YouTube URLs return the video or channel itself rather than the surrounding + * player and navigation chrome. A URL addressing a single video (`/watch`, + * `youtu.be`, `/shorts`, `/embed`, `/live`) returns its title, channel, duration, + * view count, keywords, full description, and the transcript when the video has + * captions that can be retrieved; videos without captions return everything except + * the transcript. A channel URL (`/channel/UC…`, `/@handle`, `/c/…`, `/user/…`) + * returns its name, handle, subscriber count, video count, and full description. + * When `includeImages=true`, video responses also include the thumbnail and + * channel responses include the avatar. Costs the same as any other scrape. + * * ### Billing & errors * * | HTTP status | Billed? | Meaning | @@ -171,6 +183,7 @@ export class Web extends APIResource { * | 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 | + * | 413 | No | Target content exceeds the maximum supported size (20 MB) | * | 415 | No | Unsupported content type | * | 429 | No | Per-minute rate limit exceeded; honor Retry-After | * | 500 | No | Internal error | @@ -187,7 +200,11 @@ export class Web extends APIResource { } /** - * Crawl an entire website's sitemap and return all discovered page URLs. + * Crawl an entire website's sitemap and return all discovered page URLs. Pass + * `search` to have the crawled sitemap filtered down to the pages about a phrase + * (for example `pricing and plans` or `api authentication docs`), most relevant + * first — a searched crawl scans the whole sitemap and costs 2 credits instead + * of 1. * * @example * ```ts @@ -1134,7 +1151,7 @@ export namespace WebSearchResponse { /** * Per-result scrape outcome. Inspect this before reading `markdown`. */ - code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'WEBSITE_ACCESS_ERROR' | 'ERROR'; + code: 'SUCCESS' | 'NOT_REQUESTED' | 'TIMEOUT' | 'CONTENT_TOO_LARGE' | 'WEBSITE_ACCESS_ERROR' | 'ERROR'; /** * GFM Markdown of the page. Null unless markdownOptions.enabled is true and @@ -1930,7 +1947,8 @@ export interface WebWebScrapeSitemapResponse { success: true; /** - * Array of discovered page URLs from the sitemap (max 500) + * Discovered page URLs from the sitemap, up to `maxLinks`. When `search` is set + * these are only the matching pages, most relevant first. */ urls: Array; @@ -3257,9 +3275,10 @@ export namespace WebWebCrawlMdParams { end?: number; /** - * 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. + * When true, OCR the selected PDF pages that have no usable text layer (scans), + * replacing each recovered page's text with the OCR result while pages with a real + * text layer keep it. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. */ ocr?: boolean; @@ -3613,15 +3632,16 @@ export namespace WebWebScrapeHTMLParams { end?: number; /** - * 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. + * When true, OCR the selected PDF pages that have no usable text layer (scans), + * replacing each recovered page's text with the OCR result while pages with a real + * text layer keep it. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. When false, no OCR runs. */ 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. + * a 400 PDF_SKIPPED is returned. */ shouldParse?: boolean | 'true' | 'false'; @@ -4095,15 +4115,16 @@ export namespace WebWebScrapeMdParams { end?: number; /** - * 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. + * When true, OCR the selected PDF pages that have no usable text layer (scans), + * replacing each recovered page's text with the OCR result while pages with a real + * text layer keep it. Billed at 1 credit per page OCR actually recovered, on top + * of the base request cost. When false, no OCR runs. */ 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. + * a 400 PDF_SKIPPED is returned. */ shouldParse?: boolean | 'true' | 'false'; @@ -4133,6 +4154,13 @@ export interface WebWebScrapeSitemapParams { */ maxLinks?: number; + /** + * Optional search phrase. When provided, the crawled sitemap is filtered to the + * pages whose URLs are about that phrase, most relevant first, and the request + * costs 2 credits instead of 1. + */ + search?: string; + /** * Optional explicit sitemap URL. When provided, exactly this sitemap is crawled * instead of discovering the domain's sitemaps. diff --git a/src/version.ts b/src/version.ts index 07e4d36..7b16f63 100644 --- a/src/version.ts +++ b/src/version.ts @@ -1 +1 @@ -export const VERSION = '2.9.0'; // x-release-please-version +export const VERSION = '2.10.0'; // x-release-please-version diff --git a/tests/api-resources/batch.test.ts b/tests/api-resources/batch.test.ts index 049ab4e..f03fcda 100644 --- a/tests/api-resources/batch.test.ts +++ b/tests/api-resources/batch.test.ts @@ -50,6 +50,18 @@ describe('resource batch', () => { ).rejects.toThrow(ContextDev.NotFoundError); }); + // Mock server tests are disabled + test.skip('delete', async () => { + const responsePromise = client.batch.delete('batch_9f2c8a'); + 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('cancel', async () => { const responsePromise = client.batch.cancel('batch_9f2c8a'); @@ -88,7 +100,18 @@ describe('resource batch', () => { // Mock server tests are disabled test.skip('submit: only required params', async () => { - const responsePromise = client.batch.submit({ identifiers: {} }); + const responsePromise = client.batch.submit({ + input: { + data: { + format: 'markdown', + urls: [ + { url: 'https://example.com/products/anvil' }, + { url: 'https://example.com/products/hammer' }, + ], + }, + mode: 'scrape', + }, + }); const rawResponse = await responsePromise.asResponse(); expect(rawResponse).toBeInstanceOf(Response); const response = await responsePromise; @@ -101,9 +124,45 @@ describe('resource batch', () => { // Mock server tests are disabled test.skip('submit: required and optional params', async () => { const response = await client.batch.submit({ - identifiers: { linkedinUrl: 'https://www.linkedin.com/in/yahia-bakour/' }, - tags: ['production', 'team-alpha'], - timeoutMS: 1000, + input: { + data: { + format: 'markdown', + urls: [ + { + url: 'https://example.com/products/anvil', + itemId: 'sku-1', + meta: { category: 'bar' }, + }, + { + url: 'https://example.com/products/hammer', + itemId: 'sku-2', + meta: { foo: 'bar' }, + }, + ], + options: { + country: 'de', + excludeSelectors: ['x'], + includeImages: true, + includeLinks: true, + includeSelectors: ['x'], + maxAgeMs: 0, + pdf: { + end: 1, + ocr: 'true', + shouldParse: 'true', + start: 1, + }, + settleAnimations: true, + shortenBase64Images: true, + useMainContentOnly: true, + waitForMs: 0, + }, + }, + mode: 'scrape', + }, + tags: ['docs', 'competitor'], + webhookUrl: 'webhookUrl', + 'Idempotency-Key': 'Idempotency-Key', }); }); }); diff --git a/tests/api-resources/people.test.ts b/tests/api-resources/people.test.ts new file mode 100644 index 0000000..ecb969f --- /dev/null +++ b/tests/api-resources/people.test.ts @@ -0,0 +1,22 @@ +// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details. + +import ContextDev from 'context.dev'; + +const client = new ContextDev({ + apiKey: 'My API Key', + baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010', +}); + +describe('resource people', () => { + // Mock server tests are disabled + test.skip('enrich', async () => { + const responsePromise = client.people.enrich({}); + 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); + }); +}); diff --git a/tests/api-resources/web.test.ts b/tests/api-resources/web.test.ts index d92ae8d..4a13912 100644 --- a/tests/api-resources/web.test.ts +++ b/tests/api-resources/web.test.ts @@ -393,6 +393,7 @@ describe('resource web', () => { domain: 'xxx', headers: { foo: 'J!' }, maxLinks: 1, + search: 'help center and troubleshooting articles', sitemapUrl: 'https://example.com', tags: ['production', 'team-alpha'], timeoutMS: 1,