diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 69e82f1..6ed9c80 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "2.6.0"
+ ".": "2.7.0"
}
diff --git a/.stats.yml b/.stats.yml
index 0ac1eb3..33b7080 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 32
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-242450ea46eb8c3e843fd6c4bf87e73192b5f62f6da697cd091d13c6aa7a991b.yml
-openapi_spec_hash: c1c561976de1abcacede71fd5ab9b3d9
-config_hash: 70e7e80b5e87f94981bee396c6cd41e8
+configured_endpoints: 37
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/context-dev/context.dev-960cb623c7ec84bf4dc0f5945cbc19eec9cca48271071f400d96066eaa55dbd6.yml
+openapi_spec_hash: 84fd39e3f4dc964bf0c32d4e95da1b34
+config_hash: 2bea1743c84d63bd61f8501a6ea63065
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 54d170a..6251975 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,20 @@
# Changelog
+## 2.7.0 (2026-07-31)
+
+Full Changelog: [v2.6.0...v2.7.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v2.6.0...v2.7.0)
+
+### Features
+
+* **api:** api update ([47d8000](https://github.com/context-dot-dev/context-typescript-sdk/commit/47d80006d38f7ef8773c0c62fccd73ed11342453))
+* **api:** api update ([5fa7a85](https://github.com/context-dot-dev/context-typescript-sdk/commit/5fa7a85eb0033571484c3badfada513d948736e4))
+* **api:** api update ([df82d37](https://github.com/context-dot-dev/context-typescript-sdk/commit/df82d37a48db2f31a5a134349dee53a74e3ac2c1))
+* **api:** api update ([d8cc126](https://github.com/context-dot-dev/context-typescript-sdk/commit/d8cc126ae50c1922706ade5c598a63fef97077ef))
+* **api:** api update ([54940ea](https://github.com/context-dot-dev/context-typescript-sdk/commit/54940ea4237cf68a517cff23b36b3a4dd0c56283))
+* **api:** api update ([09c34c9](https://github.com/context-dot-dev/context-typescript-sdk/commit/09c34c9d22462550b52a3468818b28848a291cf9))
+* **api:** api update ([dc895a6](https://github.com/context-dot-dev/context-typescript-sdk/commit/dc895a6f73ace40d48d008ba447d80d1283061aa))
+* **api:** manual updates ([7ececf2](https://github.com/context-dot-dev/context-typescript-sdk/commit/7ececf23429c46cebf13d4c1edfb93312426fd4c))
+
## 2.6.0 (2026-07-22)
Full Changelog: [v2.5.0...v2.6.0](https://github.com/context-dot-dev/context-typescript-sdk/compare/v2.5.0...v2.6.0)
diff --git a/api.md b/api.md
index fdc70b0..7e96fd9 100644
--- a/api.md
+++ b/api.md
@@ -118,3 +118,23 @@ Methods:
- client.monitors.listRuns(monitorID, { ...params }) -> MonitorListRunsResponse
- client.monitors.retrieveChange(changeID) -> MonitorRetrieveChangeResponse
- client.monitors.run(monitorID) -> MonitorRunResponse
+
+# Batch
+
+Types:
+
+- ErrorCount
+- Error
+- BatchRetrieveResponse
+- BatchListResponse
+- BatchCancelResponse
+- BatchGetResultsResponse
+- BatchSubmitResponse
+
+Methods:
+
+- client.batch.retrieve(batchID) -> BatchRetrieveResponse
+- client.batch.list({ ...params }) -> BatchListResponse
+- client.batch.cancel(batchID) -> BatchCancelResponse
+- client.batch.getResults(batchID, { ...params }) -> BatchGetResultsResponse
+- client.batch.submit({ ...params }) -> BatchSubmitResponse
diff --git a/package.json b/package.json
index 008caa7..2c4dd1a 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "context.dev",
- "version": "2.6.0",
+ "version": "2.7.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 a024e4d..82f5835 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.6.0",
+ "version": "2.7.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 d964768..f80a63e 100644
--- a/packages/mcp-server/package.json
+++ b/packages/mcp-server/package.json
@@ -1,6 +1,6 @@
{
"name": "context.dev-mcp",
- "version": "2.6.0",
+ "version": "2.7.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 2abec5e..6c28678 100644
--- a/packages/mcp-server/src/code-tool-worker.ts
+++ b/packages/mcp-server/src/code-tool-worker.ts
@@ -140,6 +140,11 @@ const fuse = new Fuse(
'client.monitors.retrieveChange',
'client.monitors.run',
'client.monitors.update',
+ 'client.batch.cancel',
+ 'client.batch.getResults',
+ 'client.batch.list',
+ 'client.batch.retrieve',
+ 'client.batch.submit',
],
{ 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 a392002..1ff7a15 100644
--- a/packages/mcp-server/src/local-docs-search.ts
+++ b/packages/mcp-server/src/local-docs-search.ts
@@ -139,9 +139,9 @@ const EMBEDDED_METHODS: MethodEntry[] = [
"zdr?: 'enabled' | 'disabled';",
],
response:
- '{ html: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; type: string; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }',
+ "{ 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; key_metadata?: object; }`\n\n**get** `/web/scrape/html`\n\nScrapes the given URL and returns the raw HTML content of the page. The base request costs 1 credit; requests with browser actions cost 2 credits.\n\n### Parameters\n\n- `url: string`\n Full URL to scrape (must include http:// or https:// protocol)\n\n- `actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[]`\n Optional browser actions executed in array order after the page loads and before content is captured. Requires a paid plan. Send a JSON array in the query parameter. Maximum: 5 actions.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove from the result. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: \"nav\", \"footer\", \".ad-banner\", \"[aria-hidden=true]\".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean | 'true' | 'false'`\n When true, iframes are rendered inline into the returned HTML.\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching subtrees (and their descendants) are kept and everything else is dropped. When omitted, the entire document is kept. Examples: \"article.main\", \"#content\", \"[role=main]\".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean | 'true' | 'false'`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean | 'true' | 'false'`\n When true, waits briefly for CSS and transition animations to settle before extracting HTML. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean | 'true' | 'false'`\n When true, return only the page's main content in the HTML response, excluding headers, footers, sidebars, and navigation when detectable.\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load. Min: 0. Max: 30000 (30 seconds).\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ html: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; type: string; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `html: string`\n - `metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }`\n - `success: true`\n - `type: string`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeHTML({ url: 'https://example.com' });\n\nconsole.log(response);\n```",
+ "## 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 Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove from the result. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: \"nav\", \"footer\", \".ad-banner\", \"[aria-hidden=true]\".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean | 'true' | 'false'`\n When true, iframes are rendered inline into the returned HTML.\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching subtrees (and their descendants) are kept and everything else is dropped. When omitted, the entire document is kept. Examples: \"article.main\", \"#content\", \"[role=main]\".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean | 'true' | 'false'`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean | 'true' | 'false'`\n When true, waits briefly for CSS and transition animations to settle before extracting HTML. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean | 'true' | 'false'`\n When true, return only the page's main content in the HTML response, excluding headers, footers, sidebars, and navigation when detectable.\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load. Min: 0. Max: 30000 (30 seconds).\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ html: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; type: string; url: string; 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',
@@ -209,9 +209,9 @@ const EMBEDDED_METHODS: MethodEntry[] = [
"zdr?: 'enabled' | 'disabled';",
],
response:
- '{ contentLength: number; markdown: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }',
+ "{ 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; key_metadata?: object; }`\n\n**get** `/web/scrape/markdown`\n\nScrapes the given URL into LLM usable Markdown. Inspect key_metadata on JSON responses from a recognized API key; use error_code to distinguish stable failure categories.\n\n### Billing & errors\n\n| HTTP status | Billed? | Meaning |\n| --- | --- | --- |\n| 200 | Yes — 1 credit, or 2 credits with actions | Successful scrape, including a zero-length result when includeSelectors matched nothing |\n| 400 | No | Invalid input, skipped PDF, or the page could not be scraped |\n| 401 / 403 | No | Invalid/disabled key, insufficient permissions, or credits exhausted; inspect error_code |\n| 404 | No | Target page returned or fingerprinted as not found |\n| 408 | No | Request timed out |\n| 415 | No | Unsupported content type |\n| 429 | No | Per-minute rate limit exceeded; honor Retry-After |\n| 500 | No | Internal error |\n\n### Parameters\n\n- `url: string`\n Full URL to scrape into LLM usable Markdown (must include http:// or https:// protocol)\n\n- `actions?: { do: 'wait'; timeMs: number; } | { action: string; do: 'perform'; }[]`\n Optional browser actions executed in array order after the page loads and before content is captured. Requires a paid plan. Send a JSON array in the query parameter. Maximum: 5 actions.\n\n- `country?: string`\n Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove before conversion to Markdown. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: \"nav\", \"footer\", \".ad-banner\", \"[aria-hidden=true]\".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean | 'true' | 'false'`\n When true, the contents of iframes are rendered to Markdown.\n\n- `includeImages?: boolean | 'true' | 'false'`\n Include image references in Markdown output\n\n- `includeLinks?: boolean | 'true' | 'false'`\n Preserve hyperlinks in Markdown output\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before conversion to Markdown. When omitted, the entire document is kept. Examples: \"article.main\", \"#content\", \"[role=main]\".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean | 'true' | 'false'`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean | 'true' | 'false'`\n When true, waits briefly for CSS and transition animations to settle before converting to Markdown. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `shortenBase64Images?: boolean | 'true' | 'false'`\n Shorten base64-encoded image data in the Markdown output\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean | 'true' | 'false'`\n Extract only the main content of the page, excluding headers, footers, sidebars, and navigation\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before converting the page to Markdown. Min: 0. Max: 30000 (30 seconds).\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ contentLength: number; markdown: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; url: string; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `contentLength: number`\n - `markdown: string`\n - `metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }`\n - `success: true`\n - `url: string`\n - `key_metadata?: { credits_consumed: number; credits_remaining: number; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst response = await client.web.webScrapeMd({ url: 'https://example.com' });\n\nconsole.log(response);\n```",
+ "## 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 Two-letter ISO 3166-1 alpha-2 country code identifying a supported Context.dev residential proxy exit location. Must be one of Context.dev's supported countries. When provided, Context.dev fetches the target page from that country.\n\n- `excludeSelectors?: string[]`\n CSS selectors to remove before conversion to Markdown. Applied after includeSelectors. Exclusion takes precedence: an element matching both is removed. Examples: \"nav\", \"footer\", \".ad-banner\", \"[aria-hidden=true]\".\n\n- `headers?: object`\n Optional outbound HTTP headers forwarded only to the target URL, sent as deep-object query params such as headers[X-Custom]=value. When provided, caching is bypassed: the result is neither read from nor written to cache.\n\n- `includeFrames?: boolean | 'true' | 'false'`\n When true, the contents of iframes are rendered to Markdown.\n\n- `includeImages?: boolean | 'true' | 'false'`\n Include image references in Markdown output\n\n- `includeLinks?: boolean | 'true' | 'false'`\n Preserve hyperlinks in Markdown output\n\n- `includeSelectors?: string[]`\n CSS selectors. When provided, only matching HTML subtrees (and their descendants) are kept before conversion to Markdown. When omitted, the entire document is kept. Examples: \"article.main\", \"#content\", \"[role=main]\".\n\n- `maxAgeMs?: number`\n Return a cached result if a prior scrape for the same parameters exists and is younger than this many milliseconds. Defaults to 1 day (86400000 ms) when omitted. Max is 30 days (2592000000 ms). Set to 0 to always scrape fresh.\n\n- `pdf?: { end?: number; ocr?: boolean | 'true' | 'false'; shouldParse?: boolean | 'true' | 'false'; start?: number; }`\n PDF parsing controls. Use start/end to limit text extraction and embedded-image detection/OCR to an inclusive 1-based page range.\n - `end?: number`\n Last 1-based PDF page to parse. When omitted, parsing ends at the last page. Must be greater than or equal to start when both are provided.\n - `ocr?: boolean | 'true' | 'false'`\n When true, detect and OCR images embedded in the selected PDF pages, inserting recognized text at each image's position in page reading order while preserving the PDF text layer. This is separate from automatic scanned-PDF OCR fallback.\n - `shouldParse?: boolean | 'true' | 'false'`\n When true, PDF URLs are fetched and parsed. When false, PDF URLs are skipped and a 400 WEBSITE_ACCESS_ERROR is returned.\n - `start?: number`\n First 1-based PDF page to parse. When omitted, parsing starts at the first page.\n\n- `settleAnimations?: boolean | 'true' | 'false'`\n When true, waits briefly for CSS and transition animations to settle before converting to Markdown. Defaults to false. This adds a bit of latency in exchange for more stable output on animated pages.\n\n- `shortenBase64Images?: boolean | 'true' | 'false'`\n Shorten base64-encoded image data in the Markdown output\n\n- `tags?: string[]`\n Optional comma-separated caller-defined tags for tracking this request. Tags are recorded on the request's usage log and can be used to filter usage on the dashboard usage page. Up to 20 tags, each 1-50 characters.\n\n- `timeoutMS?: number`\n Optional timeout in milliseconds for the request. If the request takes longer than this value, it will be aborted with a 408 status code. Maximum allowed value is 300000ms (5 minutes).\n\n- `useMainContentOnly?: boolean | 'true' | 'false'`\n Extract only the main content of the page, excluding headers, footers, sidebars, and navigation\n\n- `waitForMs?: number`\n Optional browser wait time in milliseconds after initial page load before converting the page to Markdown. Min: 0. Max: 30000 (30 seconds).\n\n- `zdr?: 'enabled' | 'disabled'`\n Set to enabled to bypass shared caches and omit request and response content from retained usage logs. Requires zero data retention to be enabled for your organization (contact support@context.dev), otherwise the request fails with ZDR_NOT_ENABLED. Successful ZDR responses include X-Context-ZDR: true.\n\n### Returns\n\n- `{ contentLength: number; markdown: string; metadata: { finalUrl: string; sourceUrl: string; additionalMeta?: object; alternates?: { href: string; hreflang?: string; title?: string; type?: string; }[]; author?: string; canonicalUrl?: string; description?: string; favicon?: string; image?: string; jsonLd?: object[]; keywords?: string[]; language?: string; modifiedTime?: string; openGraph?: object; publishedTime?: string; robots?: string; siteName?: string; title?: string; twitter?: object; }; success: true; url: string; 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',
@@ -1180,52 +1180,52 @@ const EMBEDDED_METHODS: MethodEntry[] = [
stainlessPath: '(resource) monitors > (method) create',
qualified: 'client.monitors.create',
params: [
- "change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; };",
'name: string;',
- "schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; };",
- "target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; };",
+ "target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; };",
+ "change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; };",
"mode?: 'web';",
+ "schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; };",
'tags?: string[];',
"webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; };",
],
response:
- "{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }",
+ "{ id: string; change_detection: object | object; created_at: string; initial_run_id: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }",
markdown:
- "## create\n\n`client.monitors.create(change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, name: string, schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, mode?: 'web', tags?: string[], webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**post** `/monitors`\n\nCreates a monitor. The request body is a union of the supported target/change detection combinations. The monitor runs immediately after creation to create its initial baseline.\n\n### Parameters\n\n- `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `name: string`\n\n- `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `mode?: 'web'`\n Top-level monitor category. Always `web` today; the concrete behavior is described by `target` and `change_detection`.\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes. Duplicates are removed.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.create({\n change_detection: { type: 'exact' },\n name: 'Acme pricing page',\n schedule: {\n frequency: 6,\n type: 'interval',\n unit: 'hours',\n},\n target: { type: 'page', url: 'https://acme.com/pricing' },\n});\n\nconsole.log(monitor);\n```",
+ "## create\n\n`client.monitors.create(name: string, target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, mode?: 'web', schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, tags?: string[], webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; initial_run_id: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**post** `/monitors`\n\nCreates a monitor. The request body is a union of the supported target/change detection combinations. The monitor runs immediately after creation to create its initial baseline.\n\n### Parameters\n\n- `name: string`\n\n- `target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `mode?: 'web'`\n Top-level monitor category. Always `web` today; the concrete behavior is described by `target` and `change_detection`.\n\n- `schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes. Duplicates are removed.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; initial_run_id: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A newly created monitor plus `initial_run_id`, the id of the baseline run queued at creation.\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `initial_run_id: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.create({\n name: 'Acme pricing page',\n target: { type: 'page', url: 'https://acme.com/pricing' },\n});\n\nconsole.log(monitor);\n```",
perLanguage: {
typescript: {
method: 'client.monitors.create',
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 monitor = await client.monitors.create({\n change_detection: { type: 'exact' },\n name: 'Acme pricing page',\n schedule: {\n type: 'interval',\n frequency: 6,\n unit: 'hours',\n },\n target: { type: 'page', url: 'https://acme.com/pricing' },\n mode: 'web',\n webhook: { url: 'https://example.com/webhook' },\n});\n\nconsole.log(monitor.id);",
+ "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 monitor = await client.monitors.create({\n name: 'Acme pricing page',\n target: { type: 'page', url: 'https://acme.com/pricing' },\n change_detection: { type: 'exact' },\n mode: 'web',\n schedule: {\n type: 'interval',\n frequency: 6,\n unit: 'hours',\n },\n webhook: { url: 'https://example.com/webhook' },\n});\n\nconsole.log(monitor.id);",
},
python: {
method: 'monitors.create',
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)\nmonitor = client.monitors.create(\n change_detection={\n "type": "exact"\n },\n name="Acme pricing page",\n schedule={\n "type": "interval",\n "frequency": 6,\n "unit": "hours",\n },\n target={\n "type": "page",\n "url": "https://acme.com/pricing",\n },\n mode="web",\n webhook={\n "url": "https://example.com/webhook"\n },\n)\nprint(monitor.id)',
+ '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)\nmonitor = client.monitors.create(\n name="Acme pricing page",\n target={\n "type": "page",\n "url": "https://acme.com/pricing",\n },\n change_detection={\n "type": "exact"\n },\n mode="web",\n schedule={\n "type": "interval",\n "frequency": 6,\n "unit": "hours",\n },\n webhook={\n "url": "https://example.com/webhook"\n },\n)\nprint(monitor.id)',
},
go: {
method: 'client.Monitors.New',
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\tmonitor, err := client.Monitors.New(context.TODO(), contextdev.MonitorNewParams{\n\t\tChangeDetection: contextdev.MonitorNewParamsChangeDetectionUnion{\n\t\t\tOfExact: &contextdev.MonitorNewParamsChangeDetectionExact{},\n\t\t},\n\t\tName: "Acme pricing page",\n\t\tSchedule: contextdev.MonitorNewParamsSchedule{\n\t\t\tType: "interval",\n\t\t\tFrequency: 6,\n\t\t\tUnit: "hours",\n\t\t},\n\t\tTarget: contextdev.MonitorNewParamsTargetUnion{\n\t\t\tOfPage: &contextdev.MonitorNewParamsTargetPage{\n\t\t\t\tURL: "https://acme.com/pricing",\n\t\t\t},\n\t\t},\n\t\tMode: contextdev.MonitorNewParamsModeWeb,\n\t\tWebhook: contextdev.MonitorNewParamsWebhook{\n\t\t\tURL: "https://example.com/webhook",\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", monitor.ID)\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\tmonitor, err := client.Monitors.New(context.TODO(), contextdev.MonitorNewParams{\n\t\tName: "Acme pricing page",\n\t\tTarget: contextdev.MonitorNewParamsTargetUnion{\n\t\t\tOfPage: &contextdev.MonitorNewParamsTargetPage{\n\t\t\t\tURL: "https://acme.com/pricing",\n\t\t\t},\n\t\t},\n\t\tChangeDetection: contextdev.MonitorNewParamsChangeDetectionUnion{\n\t\t\tOfExact: &contextdev.MonitorNewParamsChangeDetectionExact{},\n\t\t},\n\t\tMode: contextdev.MonitorNewParamsModeWeb,\n\t\tSchedule: contextdev.MonitorNewParamsSchedule{\n\t\t\tType: "interval",\n\t\t\tFrequency: 6,\n\t\t\tUnit: "hours",\n\t\t},\n\t\tWebhook: contextdev.MonitorNewParamsWebhook{\n\t\t\tURL: "https://example.com/webhook",\n\t\t},\n\t})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", monitor.ID)\n}\n',
},
ruby: {
method: 'monitors.create',
example:
- 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nmonitor = context_dev.monitors.create(\n change_detection: {type: :exact},\n name: "Acme pricing page",\n schedule: {frequency: 6, type: :interval, unit: :hours},\n target: {type: :page, url: "https://acme.com/pricing"}\n)\n\nputs(monitor)',
+ 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nmonitor = context_dev.monitors.create(\n name: "Acme pricing page",\n target: {type: :page, url: "https://acme.com/pricing"}\n)\n\nputs(monitor)',
},
cli: {
method: 'monitors create',
example:
- "context-dev monitors create \\\n --api-key 'My API Key' \\\n --change-detection '{type: exact}' \\\n --name 'Acme pricing page' \\\n --schedule '{frequency: 6, type: interval, unit: hours}' \\\n --target '{type: page, url: https://acme.com/pricing}'",
+ "context-dev monitors create \\\n --api-key 'My API Key' \\\n --name 'Acme pricing page' \\\n --target '{type: page, url: https://acme.com/pricing}'",
},
php: {
method: 'monitors->create',
example:
- "monitors->create(\n changeDetection: ['type' => 'exact'],\n name: 'Acme pricing page',\n schedule: ['frequency' => 6, 'type' => 'interval', 'unit' => 'hours'],\n target: [\n 'type' => 'page',\n 'url' => 'https://acme.com/pricing',\n 'normalizeWhitespace' => true,\n ],\n mode: 'web',\n tags: ['pricing', 'competitor'],\n webhook: [\n 'url' => 'https://example.com/webhook',\n 'events' => ['change.detected', 'run.completed'],\n ],\n);\n\nvar_dump($monitor);",
+ "monitors->create(\n name: 'Acme pricing page',\n target: [\n 'type' => 'page',\n 'url' => 'https://acme.com/pricing',\n 'instructions' => 'Report pricing or plan availability changes. Ignore counters, timestamps, testimonials, and navigation.',\n 'normalizeWhitespace' => true,\n ],\n changeDetection: ['type' => 'exact'],\n mode: 'web',\n schedule: ['frequency' => 6, 'type' => 'interval', 'unit' => 'hours'],\n tags: ['pricing', 'competitor'],\n webhook: [\n 'url' => 'https://example.com/webhook',\n 'events' => ['change.detected', 'run.completed'],\n ],\n);\n\nvar_dump($monitor);",
},
http: {
example:
- 'curl https://api.context.dev/v1/monitors \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "change_detection": {\n "type": "exact"\n },\n "name": "Acme pricing page",\n "schedule": {\n "frequency": 6,\n "type": "interval",\n "unit": "hours"\n },\n "target": {\n "type": "page",\n "url": "https://acme.com/pricing"\n },\n "mode": "web",\n "tags": [\n "pricing",\n "competitor"\n ],\n "webhook": {\n "url": "https://example.com/webhook"\n }\n }\'',
+ 'curl https://api.context.dev/v1/monitors \\\n -H \'Content-Type: application/json\' \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY" \\\n -d \'{\n "name": "Acme pricing page",\n "target": {\n "type": "page",\n "url": "https://acme.com/pricing"\n },\n "change_detection": {\n "type": "exact"\n },\n "mode": "web",\n "schedule": {\n "frequency": 6,\n "type": "interval",\n "unit": "hours"\n },\n "tags": [\n "pricing",\n "competitor"\n ],\n "webhook": {\n "url": "https://example.com/webhook"\n }\n }\'',
},
},
},
@@ -1253,7 +1253,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
response:
"{ data: { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }[]; has_more: boolean; next_cursor: string; }",
markdown:
- "## list\n\n`client.monitors.list(change_detection_type?: 'exact' | 'semantic', cursor?: string, limit?: number, q?: string, search_by?: 'name' | 'url' | 'instructions' | 'tags'[], search_type?: 'exact' | 'prefix', status?: 'active' | 'paused' | 'failed', tag?: string, tags?: string[], target_type?: 'page' | 'sitemap' | 'extract'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors`\n\nLists monitors for the authenticated organization. Supports free-text search (`q` over `search_by` fields, `prefix` or `exact` via `search_type`) plus status/type/tag filters. Results are paginated via the opaque `cursor`.\n\n### Parameters\n\n- `change_detection_type?: 'exact' | 'semantic'`\n Filter by change detection type.\n\n- `cursor?: string`\n Opaque pagination cursor from a previous response.\n\n- `limit?: number`\n Maximum number of items to return per page (1-100). Defaults to 25.\n\n- `q?: string`\n Free-text search term, matched against the fields named in `search_by`.\n\n- `search_by?: 'name' | 'url' | 'instructions' | 'tags'[]`\n Comma-separated fields to search with `q`. Defaults to all of them. Note `instructions` only exists on extract monitors.\n\n- `search_type?: 'exact' | 'prefix'`\n `prefix` for as-you-type prefix matching (default), `exact` for full-token matching.\n\n- `status?: 'active' | 'paused' | 'failed'`\n Filter monitors by lifecycle status.\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `tags?: string[]`\n Comma-separated list of tags to filter by (matches monitors having any of them).\n\n- `target_type?: 'page' | 'sitemap' | 'extract'`\n Filter by target type.\n\n### Returns\n\n- `{ data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitors = await client.monitors.list();\n\nconsole.log(monitors);\n```",
+ "## list\n\n`client.monitors.list(change_detection_type?: 'exact' | 'semantic', cursor?: string, limit?: number, q?: string, search_by?: 'name' | 'url' | 'instructions' | 'tags'[], search_type?: 'exact' | 'prefix', status?: 'active' | 'paused' | 'failed', tag?: string, tags?: string[], target_type?: 'page' | 'sitemap' | 'extract'): { data: object[]; has_more: boolean; next_cursor: string; }`\n\n**get** `/monitors`\n\nLists monitors for the authenticated organization. Supports free-text search (`q` over `search_by` fields, `prefix` or `exact` via `search_type`) plus status/type/tag filters. Results are paginated via the opaque `cursor`.\n\n### Parameters\n\n- `change_detection_type?: 'exact' | 'semantic'`\n Filter by change detection type.\n\n- `cursor?: string`\n Opaque pagination cursor from a previous response.\n\n- `limit?: number`\n Maximum number of items to return per page (1-100). Defaults to 25.\n\n- `q?: string`\n Free-text search term, matched against the fields named in `search_by`.\n\n- `search_by?: 'name' | 'url' | 'instructions' | 'tags'[]`\n Comma-separated fields to search with `q`. Defaults to all of them. Note `instructions` only exists on extract monitors.\n\n- `search_type?: 'exact' | 'prefix'`\n `prefix` for as-you-type prefix matching (default), `exact` for full-token matching.\n\n- `status?: 'active' | 'paused' | 'failed'`\n Filter monitors by lifecycle status.\n\n- `tag?: string`\n Filter to items that have this tag.\n\n- `tags?: string[]`\n Comma-separated list of tags to filter by (matches monitors having any of them).\n\n- `target_type?: 'page' | 'sitemap' | 'extract'`\n Filter by target type.\n\n### Returns\n\n- `{ data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]; has_more: boolean; next_cursor: string; }`\n\n - `data: { id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }[]`\n - `has_more: boolean`\n - `next_cursor: string`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitors = await client.monitors.list();\n\nconsole.log(monitors);\n```",
perLanguage: {
typescript: {
method: 'client.monitors.list',
@@ -1300,9 +1300,9 @@ const EMBEDDED_METHODS: MethodEntry[] = [
qualified: 'client.monitors.retrieve',
params: ['monitor_id: string;'],
response:
- "{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }",
+ "{ id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }",
markdown:
- "## retrieve\n\n`client.monitors.retrieve(monitor_id: string): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**get** `/monitors/{monitor_id}`\n\nGet a monitor\n\n### Parameters\n\n- `monitor_id: string`\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.retrieve('mon_123');\n\nconsole.log(monitor);\n```",
+ "## retrieve\n\n`client.monitors.retrieve(monitor_id: string): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**get** `/monitors/{monitor_id}`\n\nGet a monitor\n\n### Parameters\n\n- `monitor_id: string`\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.retrieve('mon_123');\n\nconsole.log(monitor);\n```",
perLanguage: {
typescript: {
method: 'client.monitors.retrieve',
@@ -1355,13 +1355,13 @@ const EMBEDDED_METHODS: MethodEntry[] = [
"schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; };",
"status?: 'active' | 'paused';",
'tags?: string[];',
- "target?: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; };",
+ "target?: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; };",
"webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; };",
],
response:
- "{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }",
+ "{ id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }",
markdown:
- "## update\n\n`client.monitors.update(monitor_id: string, change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, name?: string, schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, status?: 'active' | 'paused', tags?: string[], target?: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**patch** `/monitors/{monitor_id}`\n\nUpdates a monitor. If `target` or `change_detection` changes, the monitor creates a new baseline. Unsupported target/change detection combinations are rejected.\n\n### Parameters\n\n- `monitor_id: string`\n\n- `change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `name?: string`\n\n- `schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `status?: 'active' | 'paused'`\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes. Duplicates are removed.\n\n- `target?: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n Set to null to remove the webhook.\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.update('mon_123');\n\nconsole.log(monitor);\n```",
+ "## update\n\n`client.monitors.update(monitor_id: string, change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }, name?: string, schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }, status?: 'active' | 'paused', tags?: string[], target?: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }, webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }): { id: string; change_detection: object | object; created_at: string; mode: 'web'; name: string; schedule: object; status: 'active' | 'paused' | 'failed'; target: object | object | object; updated_at: string; baseline?: object | object | object; last_change_at?: string; last_error?: object; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: object; webhook_failure?: object; }`\n\n**patch** `/monitors/{monitor_id}`\n\nUpdates a monitor. If `target` or `change_detection` changes, the monitor creates a new baseline. Unsupported target/change detection combinations are rejected.\n\n### Parameters\n\n- `monitor_id: string`\n\n- `change_detection?: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n Discriminated union describing how changes are detected.\n\n- `name?: string`\n\n- `schedule?: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n Run the monitor on a fixed interval defined by a frequency and a unit, e.g. every 6 hours or every 2 days. The total interval (frequency × unit) must be between 10 minutes and 1 year.\n - `frequency: number`\n Number of units between runs. The resulting interval (frequency × unit) must be at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes; maximum 365 when unit is days).\n - `type: 'interval'`\n - `unit: 'minutes' | 'hours' | 'days'`\n\n- `status?: 'active' | 'paused'`\n\n- `tags?: string[]`\n User-defined tags for grouping and filtering monitors and their changes. Duplicates are removed.\n\n- `target?: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n Discriminated union describing what the monitor watches.\n\n- `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n Set to null to remove the webhook.\n - `url: string`\n Webhook URL events are delivered to.\n - `events?: 'change.detected' | 'run.completed'[]`\n Events delivered to this endpoint. `change.detected` fires only when a run detects a change; `run.completed` fires on every completed run — including runs that detected no change — and embeds the change when one was detected. Defaults to `[\"change.detected\"]` when omitted.\n - `secret?: string`\n Signing secret used to verify webhook authenticity. Each delivery includes an `X-Context-Signature: t=,v1=` header, where the HMAC is SHA-256 over `\"{t}.{rawRequestBody}\"` keyed by this secret. Recompute it with a constant-time compare and reject stale timestamps to prevent replay. Generated by the API; cannot be set by clients.\n\n### Returns\n\n- `{ id: string; change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }; created_at: string; mode: 'web'; name: string; schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }; status: 'active' | 'paused' | 'failed'; target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }; updated_at: string; baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }; last_change_at?: string; last_error?: { code: string; message: string; }; last_run_at?: string; next_run_at?: string; tags?: string[]; webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }; webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }; }`\n A web monitor. `mode` is the constant `web`; behavior is described by `target` (page/sitemap/extract) and `change_detection` (exact/semantic).\n\n - `id: string`\n - `change_detection: { type: 'exact'; } | { type: 'semantic'; confidence_threshold?: number; }`\n - `created_at: string`\n - `mode: 'web'`\n - `name: string`\n - `schedule: { frequency: number; type: 'interval'; unit: 'minutes' | 'hours' | 'days'; }`\n - `status: 'active' | 'paused' | 'failed'`\n - `target: { type: 'page'; url: string; instructions?: string; normalize_whitespace?: boolean; } | { type: 'sitemap'; url: string; exclude?: string[]; include?: string[]; max_urls?: number; } | { instructions: string; type: 'extract'; url: string; follow_subdomains?: boolean; max_depth?: number; max_pages?: number; schema?: object; }`\n - `updated_at: string`\n - `baseline?: { captured_at: string; text: string; } | { captured_at: string; url_count: number; urls: string[]; } | { captured_at: string; data: object; urls_analyzed: string[]; }`\n - `last_change_at?: string`\n - `last_error?: { code: string; message: string; }`\n - `last_run_at?: string`\n - `next_run_at?: string`\n - `tags?: string[]`\n - `webhook?: { url: string; events?: 'change.detected' | 'run.completed'[]; secret?: string; }`\n - `webhook_failure?: { consecutive_failures: number; last_failed_at: string; last_message: string; last_status: 'rejected' | 'failed' | 'skipped_unsafe_url'; }`\n\n### Example\n\n```typescript\nimport ContextDev from 'context.dev';\n\nconst client = new ContextDev();\n\nconst monitor = await client.monitors.update('mon_123');\n\nconsole.log(monitor);\n```",
perLanguage: {
typescript: {
method: 'client.monitors.update',
@@ -1390,7 +1390,7 @@ const EMBEDDED_METHODS: MethodEntry[] = [
php: {
method: 'monitors->update',
example:
- "monitors->update(\n 'mon_123',\n changeDetection: ['type' => 'exact'],\n name: 'Acme pricing monitor',\n schedule: ['frequency' => 1, 'type' => 'interval', 'unit' => 'hours'],\n status: 'active',\n tags: ['pricing', 'competitor'],\n target: [\n 'type' => 'page',\n 'url' => 'https://acme.com/pricing',\n 'normalizeWhitespace' => true,\n ],\n webhook: [\n 'url' => 'https://example.com/webhook',\n 'events' => ['change.detected', 'run.completed'],\n ],\n);\n\nvar_dump($monitor);",
+ "monitors->update(\n 'mon_123',\n changeDetection: ['type' => 'exact'],\n name: 'Acme pricing monitor',\n schedule: ['frequency' => 1, 'type' => 'interval', 'unit' => 'hours'],\n status: 'active',\n tags: ['pricing', 'competitor'],\n target: [\n 'type' => 'page',\n 'url' => 'https://acme.com/pricing',\n 'instructions' => 'Report pricing or plan availability changes. Ignore counters, timestamps, testimonials, and navigation.',\n 'normalizeWhitespace' => true,\n ],\n webhook: [\n 'url' => 'https://example.com/webhook',\n 'events' => ['change.detected', 'run.completed'],\n ],\n);\n\nvar_dump($monitor);",
},
http: {
example:
@@ -1864,6 +1864,261 @@ const EMBEDDED_METHODS: MethodEntry[] = [
},
},
},
+ {
+ name: 'submit',
+ endpoint: '/people/retrieve',
+ httpMethod: 'post',
+ summary: 'Retrieve Person',
+ description: 'Retrieve and normalize a person profile from identifiers.',
+ stainlessPath: '(resource) batch > (method) submit',
+ qualified: 'client.batch.submit',
+ params: ['identifiers: { linkedinUrl?: string; };', 'tags?: string[];', 'timeoutMS?: number;'],
+ 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; }; }",
+ 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```",
+ 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);",
+ },
+ 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)',
+ },
+ 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',
+ },
+ 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)',
+ },
+ cli: {
+ method: 'batch submit',
+ example: "context-dev batch submit \\\n --api-key 'My API Key' \\\n --identifiers '{}'",
+ },
+ 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);",
+ },
+ 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 }\'',
+ },
+ },
+ },
+ {
+ name: 'list',
+ endpoint: '/batch/list',
+ httpMethod: 'get',
+ summary: 'List batches',
+ description: 'List your batches from newest to oldest. Filter by status or continue with a cursor.',
+ stainlessPath: '(resource) batch > (method) list',
+ qualified: 'client.batch.list',
+ params: [
+ 'cursor?: string;',
+ 'limit?: number;',
+ 'q?: string;',
+ "search_type?: 'exact' | 'prefix';",
+ "status?: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed';",
+ 'tags?: string;',
+ ],
+ response:
+ "{ data?: { id: string; credits: { charged: number; estimated: number; }; error: object; errors: object[]; input: { accepted: number; duplicates: number; invalid: number; submitted: number; }; mode: 'scrape' | 'crawl'; 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; }; type: 'markdown' | 'html'; }[]; 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; credits: { charged: number; estimated: number; }; error: object; errors: object[]; input: { accepted: number; duplicates: number; invalid: number; submitted: number; }; mode: 'scrape' | 'crawl'; 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; }; type: 'markdown' | 'html'; }[]; has_more?: boolean; key_metadata?: { credits_consumed: number; credits_remaining: number; }; next_cursor?: string; }`\n\n - `data?: { id: string; credits: { charged: number; estimated: number; }; error: { code: string; message: string; }; errors: { code: string; count: number; }[]; input: { accepted: number; duplicates: number; invalid: number; submitted: number; }; mode: 'scrape' | 'crawl'; 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; }; type: 'markdown' | 'html'; }[]`\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',
+ 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 batches = await client.batch.list();\n\nconsole.log(batches.data);",
+ },
+ python: {
+ method: 'batch.list',
+ 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)\nbatches = client.batch.list()\nprint(batches.data)',
+ },
+ go: {
+ method: 'client.Batch.List',
+ 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\tbatches, err := client.Batch.List(context.TODO(), contextdev.BatchListParams{})\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", batches.Data)\n}\n',
+ },
+ ruby: {
+ method: 'batch.list',
+ example:
+ 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nbatches = context_dev.batch.list\n\nputs(batches)',
+ },
+ cli: {
+ method: 'batch list',
+ example: "context-dev batch list \\\n --api-key 'My API Key'",
+ },
+ php: {
+ method: 'batch->list',
+ example:
+ "batch->list(\n cursor: 'cursor',\n limit: 1,\n q: 'batch_1a2b',\n searchType: 'exact',\n status: 'queued',\n tags: 'docs,competitor',\n);\n\nvar_dump($batches);",
+ },
+ http: {
+ example:
+ 'curl https://api.context.dev/v1/batch/list \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY"',
+ },
+ },
+ },
+ {
+ name: 'retrieve',
+ endpoint: '/batch/{batch_id}',
+ httpMethod: 'get',
+ summary: 'Get a batch',
+ description:
+ 'Check progress and get download links when the batch finishes. Also returns the rejected-URL list and webhook signing secret from submission, so nothing is lost if the submit response was dropped.',
+ stainlessPath: '(resource) batch > (method) retrieve',
+ qualified: 'client.batch.retrieve',
+ params: ['batch_id: string;'],
+ response:
+ "{ id: string; credits: { charged: number; estimated: number; }; error: { code: string; message: string; }; errors: { code: string; count: number; }[]; input: { accepted: number; duplicates: number; invalid: number; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; 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; }; type: 'markdown' | 'html'; key_metadata?: { credits_consumed: number; credits_remaining: number; }; webhook_secret?: string; }",
+ markdown:
+ "## retrieve\n\n`client.batch.retrieve(batch_id: string): { id: string; credits: object; error: error; errors: error_count[]; input: object; invalid_urls: object[]; mode: 'scrape' | 'crawl'; progress: object; results: object; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: object; type: 'markdown' | 'html'; key_metadata?: object; webhook_secret?: string; }`\n\n**get** `/batch/{batch_id}`\n\nCheck progress and get download links when the batch finishes. Also returns the rejected-URL list and webhook signing secret from submission, so nothing is lost if the submit response was dropped.\n\n### Parameters\n\n- `batch_id: string`\n ID of the batch to retrieve or cancel.\n\n### Returns\n\n- `{ id: string; credits: { charged: number; estimated: number; }; error: { code: string; message: string; }; errors: { code: string; count: number; }[]; input: { accepted: number; duplicates: number; invalid: number; submitted: number; }; invalid_urls: { reason: string; url: string; }[]; mode: 'scrape' | 'crawl'; 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; }; type: 'markdown' | 'html'; key_metadata?: { credits_consumed: number; credits_remaining: number; }; webhook_secret?: string; }`\n\n - `id: string`\n - `credits: { charged: number; estimated: number; }`\n - `error: { code: string; message: string; }`\n - `errors: { code: string; count: number; }[]`\n - `input: { accepted: number; duplicates: number; invalid: number; submitted: number; }`\n - `invalid_urls: { reason: string; url: string; }[]`\n - `mode: 'scrape' | 'crawl'`\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 - `type: 'markdown' | 'html'`\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 batch = await client.batch.retrieve('batch_9f2c8a');\n\nconsole.log(batch);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.batch.retrieve',
+ 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.retrieve('batch_9f2c8a');\n\nconsole.log(batch.id);",
+ },
+ python: {
+ method: 'batch.retrieve',
+ 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.retrieve(\n "batch_9f2c8a",\n)\nprint(batch.id)',
+ },
+ go: {
+ method: 'client.Batch.Get',
+ 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.Get(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.retrieve',
+ example:
+ 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nbatch = context_dev.batch.retrieve("batch_9f2c8a")\n\nputs(batch)',
+ },
+ cli: {
+ method: 'batch retrieve',
+ example: "context-dev batch retrieve \\\n --api-key 'My API Key' \\\n --batch-id batch_9f2c8a",
+ },
+ php: {
+ method: 'batch->retrieve',
+ example:
+ "batch->retrieve('batch_9f2c8a');\n\nvar_dump($batch);",
+ },
+ http: {
+ example:
+ 'curl https://api.context.dev/v1/batch/$BATCH_ID \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY"',
+ },
+ },
+ },
+ {
+ name: 'get_results',
+ endpoint: '/batch/{batch_id}/results',
+ httpMethod: 'get',
+ summary: 'Get batch results',
+ description:
+ 'Page through the result records of a finished batch as JSON, in the same order as the downloadable result files. Use this instead of downloading and parsing the NDJSON files yourself.',
+ stainlessPath: '(resource) batch > (method) get_results',
+ 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; }",
+ 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 the result records of a finished batch as JSON, in the same order as the downloadable result files. Use this instead of downloading and parsing the NDJSON files yourself.\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```",
+ perLanguage: {
+ typescript: {
+ method: 'client.batch.getResults',
+ 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.getResults('batch_9f2c8a');\n\nconsole.log(response.data);",
+ },
+ python: {
+ method: 'batch.get_results',
+ 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.get_results(\n batch_id="batch_9f2c8a",\n)\nprint(response.data)',
+ },
+ go: {
+ method: 'client.Batch.GetResults',
+ 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.GetResults(\n\t\tcontext.TODO(),\n\t\t"batch_9f2c8a",\n\t\tcontextdev.BatchGetResultsParams{},\n\t)\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.Data)\n}\n',
+ },
+ ruby: {
+ method: 'batch.get_results',
+ example:
+ 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.batch.get_results("batch_9f2c8a")\n\nputs(response)',
+ },
+ cli: {
+ method: 'batch get_results',
+ example: "context-dev batch get-results \\\n --api-key 'My API Key' \\\n --batch-id batch_9f2c8a",
+ },
+ php: {
+ method: 'batch->getResults',
+ example:
+ "batch->getResults(\n 'batch_9f2c8a', cursor: 'cursor', limit: 1\n);\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl https://api.context.dev/v1/batch/$BATCH_ID/results \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY"',
+ },
+ },
+ },
+ {
+ name: 'cancel',
+ endpoint: '/batch/{batch_id}/cancel',
+ httpMethod: 'post',
+ summary: 'Cancel a batch',
+ description:
+ 'Stop a batch from starting new pages. In-progress pages finish, and unused credits are refunded.',
+ stainlessPath: '(resource) batch > (method) cancel',
+ qualified: 'client.batch.cancel',
+ params: ['batch_id: string;'],
+ response:
+ "{ id: string; credits: { charged: number; estimated: number; }; error: { code: string; message: string; }; errors: { code: string; count: number; }[]; input: { accepted: number; duplicates: number; invalid: number; submitted: number; }; mode: 'scrape' | 'crawl'; 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; }; type: 'markdown' | 'html'; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }",
+ markdown:
+ "## cancel\n\n`client.batch.cancel(batch_id: string): { id: string; credits: object; error: error; errors: error_count[]; input: object; mode: 'scrape' | 'crawl'; progress: object; results: object; status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed'; tags: string[]; timing: object; type: 'markdown' | 'html'; key_metadata?: object; }`\n\n**post** `/batch/{batch_id}/cancel`\n\nStop a batch from starting new pages. In-progress pages finish, and unused credits are refunded.\n\n### Parameters\n\n- `batch_id: string`\n ID of the batch to retrieve or cancel.\n\n### Returns\n\n- `{ id: string; credits: { charged: number; estimated: number; }; error: { code: string; message: string; }; errors: { code: string; count: number; }[]; input: { accepted: number; duplicates: number; invalid: number; submitted: number; }; mode: 'scrape' | 'crawl'; 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; }; type: 'markdown' | 'html'; key_metadata?: { credits_consumed: number; credits_remaining: number; }; }`\n\n - `id: string`\n - `credits: { charged: number; estimated: number; }`\n - `error: { code: string; message: string; }`\n - `errors: { code: string; count: number; }[]`\n - `input: { accepted: number; duplicates: number; invalid: number; submitted: number; }`\n - `mode: 'scrape' | 'crawl'`\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 - `type: 'markdown' | 'html'`\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.cancel('batch_9f2c8a');\n\nconsole.log(response);\n```",
+ perLanguage: {
+ typescript: {
+ method: 'client.batch.cancel',
+ 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.cancel('batch_9f2c8a');\n\nconsole.log(response.id);",
+ },
+ python: {
+ method: 'batch.cancel',
+ 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.cancel(\n "batch_9f2c8a",\n)\nprint(response.id)',
+ },
+ go: {
+ method: 'client.Batch.Cancel',
+ 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.Cancel(context.TODO(), "batch_9f2c8a")\n\tif err != nil {\n\t\tpanic(err.Error())\n\t}\n\tfmt.Printf("%+v\\n", response.ID)\n}\n',
+ },
+ ruby: {
+ method: 'batch.cancel',
+ example:
+ 'require "context_dev"\n\ncontext_dev = ContextDev::Client.new(api_key: "My API Key")\n\nresponse = context_dev.batch.cancel("batch_9f2c8a")\n\nputs(response)',
+ },
+ cli: {
+ method: 'batch cancel',
+ example: "context-dev batch cancel \\\n --api-key 'My API Key' \\\n --batch-id batch_9f2c8a",
+ },
+ php: {
+ method: 'batch->cancel',
+ example:
+ "batch->cancel('batch_9f2c8a');\n\nvar_dump($response);",
+ },
+ http: {
+ example:
+ 'curl https://api.context.dev/v1/batch/$BATCH_ID/cancel \\\n -X POST \\\n -H "Authorization: Bearer $CONTEXT_DEV_API_KEY"',
+ },
+ },
+ },
];
const EMBEDDED_READMES: { language: string; content: string }[] = [
diff --git a/packages/mcp-server/src/methods.ts b/packages/mcp-server/src/methods.ts
index 2099187..e3ee5c2 100644
--- a/packages/mcp-server/src/methods.ts
+++ b/packages/mcp-server/src/methods.ts
@@ -202,6 +202,36 @@ export const sdkMethods: SdkMethod[] = [
httpMethod: 'post',
httpPath: '/monitors/{monitor_id}/run',
},
+ {
+ clientCallName: 'client.batch.retrieve',
+ fullyQualifiedName: 'batch.retrieve',
+ httpMethod: 'get',
+ httpPath: '/batch/{batch_id}',
+ },
+ {
+ clientCallName: 'client.batch.list',
+ fullyQualifiedName: 'batch.list',
+ httpMethod: 'get',
+ httpPath: '/batch/list',
+ },
+ {
+ clientCallName: 'client.batch.cancel',
+ fullyQualifiedName: 'batch.cancel',
+ httpMethod: 'post',
+ httpPath: '/batch/{batch_id}/cancel',
+ },
+ {
+ clientCallName: 'client.batch.getResults',
+ fullyQualifiedName: 'batch.getResults',
+ httpMethod: 'get',
+ httpPath: '/batch/{batch_id}/results',
+ },
+ {
+ clientCallName: 'client.batch.submit',
+ fullyQualifiedName: 'batch.submit',
+ httpMethod: 'post',
+ httpPath: '/people/retrieve',
+ },
];
function allowedMethodsForCodeTool(options: McpOptions | undefined): SdkMethod[] | undefined {
diff --git a/packages/mcp-server/src/server.ts b/packages/mcp-server/src/server.ts
index a954c9b..b8ff8c7 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.6.0',
+ version: '2.7.0',
},
{
instructions: await getInstructions({ stainlessApiKey, customInstructionsPath }),
diff --git a/src/client.ts b/src/client.ts
index 14f5c7e..8da0bbb 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -24,6 +24,19 @@ import {
AIExtractProductsParams,
AIExtractProductsResponse,
} from './resources/ai';
+import {
+ Batch,
+ BatchCancelResponse,
+ BatchGetResultsParams,
+ BatchGetResultsResponse,
+ BatchListParams,
+ BatchListResponse,
+ BatchRetrieveResponse,
+ BatchSubmitParams,
+ BatchSubmitResponse,
+ Error,
+ ErrorCount,
+} from './resources/batch';
import {
Brand,
BrandRetrieveParams,
@@ -817,6 +830,7 @@ 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);
+ batch: API.Batch = new API.Batch(this);
}
ContextDev.Parse = Parse;
@@ -826,6 +840,7 @@ ContextDev.Brand = Brand;
ContextDev.Industry = Industry;
ContextDev.Utility = Utility;
ContextDev.Monitors = Monitors;
+ContextDev.Batch = Batch;
export declare namespace ContextDev {
export type RequestOptions = Opts.RequestOptions;
@@ -917,4 +932,18 @@ export declare namespace ContextDev {
type MonitorListChangesParams as MonitorListChangesParams,
type MonitorListRunsParams as MonitorListRunsParams,
};
+
+ export {
+ Batch as Batch,
+ type ErrorCount as ErrorCount,
+ type Error as Error,
+ type BatchRetrieveResponse as BatchRetrieveResponse,
+ type BatchListResponse as BatchListResponse,
+ type BatchCancelResponse as BatchCancelResponse,
+ type BatchGetResultsResponse as BatchGetResultsResponse,
+ type BatchSubmitResponse as BatchSubmitResponse,
+ type BatchListParams as BatchListParams,
+ type BatchGetResultsParams as BatchGetResultsParams,
+ type BatchSubmitParams as BatchSubmitParams,
+ };
}
diff --git a/src/resources/batch.ts b/src/resources/batch.ts
new file mode 100644
index 0000000..65e610c
--- /dev/null
+++ b/src/resources/batch.ts
@@ -0,0 +1,1465 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../core/resource';
+import * as BatchAPI from './batch';
+import { APIPromise } from '../core/api-promise';
+import { RequestOptions } from '../internal/request-options';
+import { path } from '../internal/utils/path';
+
+export class Batch extends APIResource {
+ /**
+ * Check progress and get download links when the batch finishes. Also returns the
+ * rejected-URL list and webhook signing secret from submission, so nothing is lost
+ * if the submit response was dropped.
+ *
+ * @example
+ * ```ts
+ * const batch = await client.batch.retrieve('batch_9f2c8a');
+ * ```
+ */
+ retrieve(batchID: string, options?: RequestOptions): APIPromise {
+ return this._client.get(path`/batch/${batchID}`, options);
+ }
+
+ /**
+ * List your batches from newest to oldest. Filter by status or continue with a
+ * cursor.
+ *
+ * @example
+ * ```ts
+ * const batches = await client.batch.list();
+ * ```
+ */
+ list(
+ query: BatchListParams | null | undefined = {},
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.get('/batch/list', { query, ...options });
+ }
+
+ /**
+ * Stop a batch from starting new pages. In-progress pages finish, and unused
+ * credits are refunded.
+ *
+ * @example
+ * ```ts
+ * const response = await client.batch.cancel('batch_9f2c8a');
+ * ```
+ */
+ cancel(batchID: string, options?: RequestOptions): APIPromise {
+ return this._client.post(path`/batch/${batchID}/cancel`, options);
+ }
+
+ /**
+ * Page through the result records of a finished batch as JSON, in the same order
+ * as the downloadable result files. Use this instead of downloading and parsing
+ * the NDJSON files yourself.
+ *
+ * @example
+ * ```ts
+ * const response = await client.batch.getResults(
+ * 'batch_9f2c8a',
+ * );
+ * ```
+ */
+ getResults(
+ batchID: string,
+ query: BatchGetResultsParams | null | undefined = {},
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.get(path`/batch/${batchID}/results`, { query, ...options });
+ }
+
+ /**
+ * Retrieve and normalize a person profile from identifiers.
+ *
+ * @example
+ * ```ts
+ * const response = await client.batch.submit({
+ * identifiers: {
+ * linkedinUrl:
+ * 'https://www.linkedin.com/in/yahia-bakour/',
+ * },
+ * });
+ * ```
+ */
+ submit(body: BatchSubmitParams, options?: RequestOptions): APIPromise {
+ return this._client.post('/people/retrieve', { body, ...options });
+ }
+}
+
+/**
+ * Page failures sharing one error code.
+ */
+export interface ErrorCount {
+ /**
+ * Error code for these failures.
+ */
+ code: string;
+
+ /**
+ * Pages that failed with this code.
+ */
+ count: number;
+}
+
+/**
+ * Why the batch failed.
+ */
+export interface Error {
+ /**
+ * Batch error code.
+ */
+ code: string;
+
+ /**
+ * Batch error message.
+ */
+ message: string;
+}
+
+export interface BatchRetrieveResponse {
+ /**
+ * Batch ID used to retrieve or cancel the job.
+ */
+ id: string;
+
+ /**
+ * Reserved and used credits.
+ */
+ credits: BatchRetrieveResponse.Credits;
+
+ /**
+ * Why the batch failed.
+ */
+ error: Error | null;
+
+ /**
+ * Page failures grouped by error code.
+ */
+ errors: Array;
+
+ /**
+ * Submission counts.
+ */
+ input: BatchRetrieveResponse.Input;
+
+ /**
+ * Rejected URLs, up to 100. These are not charged.
+ */
+ invalid_urls: Array;
+
+ /**
+ * How pages are selected.
+ */
+ mode: 'scrape' | 'crawl';
+
+ /**
+ * Current processing counts. Use `status` to check completion.
+ */
+ progress: BatchRetrieveResponse.Progress;
+
+ /**
+ * Download links available when the batch finishes. GET /batch/{batch_id}/results
+ * serves the same records as paginated JSON.
+ */
+ results: BatchRetrieveResponse.Results | null;
+
+ /**
+ * Current state. `completed`, `cancelled`, and `failed` are final.
+ */
+ status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed';
+
+ /**
+ * Tags stored on the batch at submission.
+ */
+ tags: Array;
+
+ timing: BatchRetrieveResponse.Timing;
+
+ /**
+ * Output format.
+ */
+ type: 'markdown' | 'html';
+
+ /**
+ * API key usage for this request.
+ */
+ key_metadata?: BatchRetrieveResponse.KeyMetadata;
+
+ /**
+ * Webhook signing secret. Also returned by GET /batch/{batch_id}.
+ */
+ webhook_secret?: string;
+}
+
+export namespace BatchRetrieveResponse {
+ /**
+ * Reserved and used credits.
+ */
+ export interface Credits {
+ /**
+ * Credits used by successful pages.
+ */
+ charged: number;
+
+ /**
+ * Credits reserved when the batch was accepted.
+ */
+ estimated: number;
+ }
+
+ /**
+ * Submission counts.
+ */
+ export interface Input {
+ /**
+ * Pages accepted, or the crawl page limit. Credits are reserved for this count.
+ */
+ accepted: number;
+
+ /**
+ * Duplicate URL and `itemId` pairs skipped. Always 0 for crawls.
+ */
+ duplicates: number;
+
+ /**
+ * Pages rejected during validation.
+ */
+ invalid: number;
+
+ /**
+ * Pages submitted before validation. For a crawl, the page limit.
+ */
+ submitted: number;
+ }
+
+ export interface InvalidURL {
+ /**
+ * Why it was rejected.
+ */
+ reason: string;
+
+ /**
+ * Rejected URL.
+ */
+ url: string;
+ }
+
+ /**
+ * Current processing counts. Use `status` to check completion.
+ */
+ export interface Progress {
+ /**
+ * Pages that could not be scraped.
+ */
+ failed: number;
+
+ /**
+ * Accepted pages not yet attempted. Always 0 once the batch completes; a crawl can
+ * finish under its page limit when the site has no more reachable pages.
+ */
+ pending: number;
+
+ /**
+ * Pages scraped successfully.
+ */
+ succeeded: number;
+ }
+
+ /**
+ * Download links available when the batch finishes. GET /batch/{batch_id}/results
+ * serves the same records as paginated JSON.
+ */
+ export interface Results {
+ /**
+ * When the download URLs expire.
+ */
+ expires_at: string;
+
+ /**
+ * Result files. Order is not guaranteed.
+ */
+ files: Array;
+ }
+
+ export namespace Results {
+ export interface File {
+ /**
+ * Compressed file size in bytes.
+ */
+ bytes: number;
+
+ /**
+ * Results in this file.
+ */
+ items: number;
+
+ /**
+ * Temporary URL for a gzipped NDJSON file.
+ */
+ url: string;
+ }
+ }
+
+ export interface Timing {
+ /**
+ * When processing finished. Null while active.
+ */
+ completed_at: string | null;
+
+ /**
+ * When the batch was created.
+ */
+ created_at: string;
+
+ /**
+ * When processing started. Null while queued.
+ */
+ started_at: string | null;
+ }
+
+ /**
+ * API key usage for this request.
+ */
+ 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 BatchListResponse {
+ /**
+ * Batches on this page.
+ */
+ data?: Array;
+
+ /**
+ * Whether another page is available.
+ */
+ has_more?: 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?: BatchListResponse.KeyMetadata;
+
+ /**
+ * Cursor for the next page.
+ */
+ next_cursor?: string | null;
+}
+
+export namespace BatchListResponse {
+ /**
+ * An asynchronous web scraping job.
+ */
+ export interface Data {
+ /**
+ * Batch ID used to retrieve or cancel the job.
+ */
+ id: string;
+
+ /**
+ * Reserved and used credits.
+ */
+ credits: Data.Credits;
+
+ /**
+ * Why the batch failed.
+ */
+ error: BatchAPI.Error | null;
+
+ /**
+ * Page failures grouped by error code.
+ */
+ errors: Array;
+
+ /**
+ * Submission counts.
+ */
+ input: Data.Input;
+
+ /**
+ * How pages are selected.
+ */
+ mode: 'scrape' | 'crawl';
+
+ /**
+ * Current processing counts. Use `status` to check completion.
+ */
+ progress: Data.Progress;
+
+ /**
+ * Download links available when the batch finishes. GET /batch/{batch_id}/results
+ * serves the same records as paginated JSON.
+ */
+ results: Data.Results | null;
+
+ /**
+ * Current state. `completed`, `cancelled`, and `failed` are final.
+ */
+ status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed';
+
+ /**
+ * Tags stored on the batch at submission.
+ */
+ tags: Array;
+
+ timing: Data.Timing;
+
+ /**
+ * Output format.
+ */
+ type: 'markdown' | 'html';
+ }
+
+ export namespace Data {
+ /**
+ * Reserved and used credits.
+ */
+ export interface Credits {
+ /**
+ * Credits used by successful pages.
+ */
+ charged: number;
+
+ /**
+ * Credits reserved when the batch was accepted.
+ */
+ estimated: number;
+ }
+
+ /**
+ * Submission counts.
+ */
+ export interface Input {
+ /**
+ * Pages accepted, or the crawl page limit. Credits are reserved for this count.
+ */
+ accepted: number;
+
+ /**
+ * Duplicate URL and `itemId` pairs skipped. Always 0 for crawls.
+ */
+ duplicates: number;
+
+ /**
+ * Pages rejected during validation.
+ */
+ invalid: number;
+
+ /**
+ * Pages submitted before validation. For a crawl, the page limit.
+ */
+ submitted: number;
+ }
+
+ /**
+ * Current processing counts. Use `status` to check completion.
+ */
+ export interface Progress {
+ /**
+ * Pages that could not be scraped.
+ */
+ failed: number;
+
+ /**
+ * Accepted pages not yet attempted. Always 0 once the batch completes; a crawl can
+ * finish under its page limit when the site has no more reachable pages.
+ */
+ pending: number;
+
+ /**
+ * Pages scraped successfully.
+ */
+ succeeded: number;
+ }
+
+ /**
+ * Download links available when the batch finishes. GET /batch/{batch_id}/results
+ * serves the same records as paginated JSON.
+ */
+ export interface Results {
+ /**
+ * When the download URLs expire.
+ */
+ expires_at: string;
+
+ /**
+ * Result files. Order is not guaranteed.
+ */
+ files: Array;
+ }
+
+ export namespace Results {
+ export interface File {
+ /**
+ * Compressed file size in bytes.
+ */
+ bytes: number;
+
+ /**
+ * Results in this file.
+ */
+ items: number;
+
+ /**
+ * Temporary URL for a gzipped NDJSON file.
+ */
+ url: string;
+ }
+ }
+
+ export interface Timing {
+ /**
+ * When processing finished. Null while active.
+ */
+ completed_at: string | null;
+
+ /**
+ * When the batch was created.
+ */
+ created_at: string;
+
+ /**
+ * When processing started. Null while queued.
+ */
+ started_at: string | null;
+ }
+ }
+
+ /**
+ * 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 used to retrieve or cancel the job.
+ */
+ id: string;
+
+ /**
+ * Reserved and used credits.
+ */
+ credits: BatchCancelResponse.Credits;
+
+ /**
+ * Why the batch failed.
+ */
+ error: Error | null;
+
+ /**
+ * Page failures grouped by error code.
+ */
+ errors: Array;
+
+ /**
+ * Submission counts.
+ */
+ input: BatchCancelResponse.Input;
+
+ /**
+ * How pages are selected.
+ */
+ mode: 'scrape' | 'crawl';
+
+ /**
+ * Current processing counts. Use `status` to check completion.
+ */
+ progress: BatchCancelResponse.Progress;
+
+ /**
+ * Download links available when the batch finishes. GET /batch/{batch_id}/results
+ * serves the same records as paginated JSON.
+ */
+ results: BatchCancelResponse.Results | null;
+
+ /**
+ * Current state. `completed`, `cancelled`, and `failed` are final.
+ */
+ status: 'queued' | 'running' | 'cancelling' | 'completed' | 'cancelled' | 'failed';
+
+ /**
+ * Tags stored on the batch at submission.
+ */
+ tags: Array;
+
+ timing: BatchCancelResponse.Timing;
+
+ /**
+ * Output format.
+ */
+ type: 'markdown' | 'html';
+
+ /**
+ * API key usage for this request.
+ */
+ key_metadata?: BatchCancelResponse.KeyMetadata;
+}
+
+export namespace BatchCancelResponse {
+ /**
+ * Reserved and used credits.
+ */
+ export interface Credits {
+ /**
+ * Credits used by successful pages.
+ */
+ charged: number;
+
+ /**
+ * Credits reserved when the batch was accepted.
+ */
+ estimated: number;
+ }
+
+ /**
+ * Submission counts.
+ */
+ export interface Input {
+ /**
+ * Pages accepted, or the crawl page limit. Credits are reserved for this count.
+ */
+ accepted: number;
+
+ /**
+ * Duplicate URL and `itemId` pairs skipped. Always 0 for crawls.
+ */
+ duplicates: number;
+
+ /**
+ * Pages rejected during validation.
+ */
+ invalid: number;
+
+ /**
+ * Pages submitted before validation. For a crawl, the page limit.
+ */
+ submitted: number;
+ }
+
+ /**
+ * Current processing counts. Use `status` to check completion.
+ */
+ export interface Progress {
+ /**
+ * Pages that could not be scraped.
+ */
+ failed: number;
+
+ /**
+ * Accepted pages not yet attempted. Always 0 once the batch completes; a crawl can
+ * finish under its page limit when the site has no more reachable pages.
+ */
+ pending: number;
+
+ /**
+ * Pages scraped successfully.
+ */
+ succeeded: number;
+ }
+
+ /**
+ * Download links available when the batch finishes. GET /batch/{batch_id}/results
+ * serves the same records as paginated JSON.
+ */
+ export interface Results {
+ /**
+ * When the download URLs expire.
+ */
+ expires_at: string;
+
+ /**
+ * Result files. Order is not guaranteed.
+ */
+ files: Array;
+ }
+
+ export namespace Results {
+ export interface File {
+ /**
+ * Compressed file size in bytes.
+ */
+ bytes: number;
+
+ /**
+ * Results in this file.
+ */
+ items: number;
+
+ /**
+ * Temporary URL for a gzipped NDJSON file.
+ */
+ url: string;
+ }
+ }
+
+ export interface Timing {
+ /**
+ * When processing finished. Null while active.
+ */
+ completed_at: string | null;
+
+ /**
+ * When the batch was created.
+ */
+ created_at: string;
+
+ /**
+ * When processing started. Null while queued.
+ */
+ started_at: string | null;
+ }
+
+ /**
+ * API key usage for this request.
+ */
+ 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 BatchGetResultsResponse {
+ /**
+ * Result records on this page.
+ */
+ data?: Array;
+
+ /**
+ * Whether another page is available.
+ */
+ has_more?: 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?: BatchGetResultsResponse.KeyMetadata;
+
+ /**
+ * Cursor for the next page.
+ */
+ next_cursor?: string | null;
+}
+
+export namespace BatchGetResultsResponse {
+ /**
+ * A page the batch fetched successfully.
+ */
+ export interface Ok {
+ /**
+ * URL the content was read from, after redirects.
+ */
+ final_url: string;
+
+ /**
+ * HTTP status of the final response, when known.
+ */
+ http_status: number | null;
+
+ /**
+ * Metadata extracted from the scraped page HTML.
+ */
+ metadata: Ok.Metadata;
+
+ /**
+ * The page was scraped.
+ */
+ status: 'ok';
+
+ /**
+ * URL as submitted, or as discovered by the crawl.
+ */
+ url: string;
+
+ /**
+ * Raw page HTML. Present on html batches.
+ */
+ html?: string;
+
+ /**
+ * Caller-supplied identifier echoed from submission.
+ */
+ itemId?: string;
+
+ /**
+ * Page content as Markdown. Present on markdown batches.
+ */
+ markdown?: string;
+
+ /**
+ * Caller-supplied metadata echoed from submission.
+ */
+ meta?: { [key: string]: unknown };
+ }
+
+ export namespace Ok {
+ /**
+ * Metadata extracted from the scraped page HTML.
+ */
+ export interface Metadata {
+ /**
+ * Final URL scraped after redirects or scraper fallback, when known. Falls back to
+ * sourceUrl when unavailable.
+ */
+ finalUrl: string;
+
+ /**
+ * Original URL requested by the caller.
+ */
+ sourceUrl: string;
+
+ /**
+ * Additional non-social meta tags not promoted to top-level metadata fields.
+ */
+ additionalMeta?: { [key: string]: string | Array };
+
+ /**
+ * Resolved alternate links from link rel=alternate tags.
+ */
+ alternates?: Array;
+
+ /**
+ * Author metadata, when present.
+ */
+ author?: string;
+
+ /**
+ * Resolved canonical URL, when present.
+ */
+ canonicalUrl?: string;
+
+ /**
+ * Best description extracted from standard, Open Graph, or Twitter metadata.
+ */
+ description?: string;
+
+ /**
+ * Resolved favicon URL, when present.
+ */
+ favicon?: string;
+
+ /**
+ * Primary resolved preview image from Open Graph, Twitter, or image metadata.
+ */
+ image?: string;
+
+ /**
+ * JSON-LD structured data blocks parsed from the page.
+ */
+ jsonLd?: Array<{ [key: string]: unknown }>;
+
+ /**
+ * Keywords extracted from the page's keywords meta tag.
+ */
+ keywords?: Array;
+
+ /**
+ * Language extracted from html lang or language meta tags.
+ */
+ language?: string;
+
+ /**
+ * Modified timestamp/date from page metadata, when present.
+ */
+ modifiedTime?: string;
+
+ /**
+ * Open Graph metadata with the og: prefix removed and keys camel-cased.
+ */
+ openGraph?: { [key: string]: string | Array };
+
+ /**
+ * Published timestamp/date from page metadata, when present.
+ */
+ publishedTime?: string;
+
+ /**
+ * Robots meta directive, when present.
+ */
+ robots?: string;
+
+ /**
+ * Site or application name from page metadata.
+ */
+ siteName?: string;
+
+ /**
+ * Best title extracted from the page.
+ */
+ title?: string;
+
+ /**
+ * Twitter card metadata with the twitter: prefix removed and keys camel-cased.
+ */
+ twitter?: { [key: string]: string | Array };
+ }
+
+ export namespace Metadata {
+ export interface Alternate {
+ /**
+ * Resolved alternate URL.
+ */
+ href: string;
+
+ /**
+ * Language or locale for the alternate URL, when present.
+ */
+ hreflang?: string;
+
+ /**
+ * Alternate resource title, when present.
+ */
+ title?: string;
+
+ /**
+ * Alternate resource MIME type, when present.
+ */
+ type?: string;
+ }
+ }
+ }
+
+ /**
+ * A page the batch could not fetch.
+ */
+ export interface Error {
+ /**
+ * Why the page failed.
+ */
+ error_code: string;
+
+ /**
+ * Human-readable failure detail.
+ */
+ message: string;
+
+ /**
+ * The page could not be scraped.
+ */
+ status: 'error';
+
+ /**
+ * URL as submitted, or as discovered by the crawl.
+ */
+ url: string;
+
+ /**
+ * Caller-supplied identifier echoed from submission.
+ */
+ itemId?: string;
+
+ /**
+ * Caller-supplied metadata echoed from submission.
+ */
+ meta?: { [key: string]: unknown };
+ }
+
+ /**
+ * 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 BatchSubmitResponse {
+ /**
+ * HTTP status code.
+ */
+ code: 200;
+
+ /**
+ * Additional response details.
+ */
+ metadata: BatchSubmitResponse.Metadata;
+
+ /**
+ * Retrieved person profile.
+ */
+ person: BatchSubmitResponse.Person;
+
+ /**
+ * Response status.
+ */
+ status: 'ok';
+
+ /**
+ * 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?: BatchSubmitResponse.KeyMetadata;
+}
+
+export namespace BatchSubmitResponse {
+ /**
+ * Additional response details.
+ */
+ export interface Metadata {
+ /**
+ * Identifiers returned for the person.
+ */
+ identifiers: Metadata.Identifiers;
+
+ /**
+ * Source categories checked.
+ */
+ sourcesAttempted: Array<'linkedin' | 'cv' | 'manual' | 'github' | 'other'>;
+
+ /**
+ * Source categories with data.
+ */
+ sourcesSucceeded: Array<'linkedin' | 'cv' | 'manual' | 'github' | 'other'>;
+
+ /**
+ * URLs reviewed for this profile.
+ */
+ urlsAnalyzed: Array;
+
+ /**
+ * Personal website URL, when found.
+ */
+ personalWebsiteUrl?: string;
+ }
+
+ export namespace Metadata {
+ /**
+ * Identifiers returned for the person.
+ */
+ export interface Identifiers {
+ /**
+ * LinkedIn profile URL.
+ */
+ linkedinUrl?: string;
+ }
+ }
+
+ /**
+ * Retrieved person profile.
+ */
+ export interface Person {
+ /**
+ * Education history.
+ */
+ education: Array;
+
+ /**
+ * Work history.
+ */
+ experience: Array;
+
+ /**
+ * Core profile details.
+ */
+ profile: Person.Profile;
+
+ /**
+ * Listed skills.
+ */
+ skills: Array;
+ }
+
+ export namespace Person {
+ export interface Education {
+ /**
+ * School or institution name.
+ */
+ institution: Education.Institution;
+
+ /**
+ * Education dates.
+ */
+ dates?: Education.Dates;
+
+ /**
+ * Additional education details.
+ */
+ description?: string;
+
+ /**
+ * Area of study.
+ */
+ fieldOfStudy?: string;
+
+ /**
+ * Degree, certificate, or credential.
+ */
+ qualification?: string;
+ }
+
+ export namespace Education {
+ /**
+ * School or institution name.
+ */
+ export interface Institution {
+ /**
+ * Display name.
+ */
+ display: string;
+
+ /**
+ * Standardized name, when available.
+ */
+ normalized?: string;
+ }
+
+ /**
+ * Education dates.
+ */
+ export interface Dates {
+ /**
+ * End date, when known.
+ */
+ endDate?: Dates.EndDate;
+
+ /**
+ * Whether the entry is current.
+ */
+ isCurrent?: boolean;
+
+ /**
+ * Start date, when known.
+ */
+ startDate?: Dates.StartDate;
+ }
+
+ export namespace Dates {
+ /**
+ * End date, when known.
+ */
+ export interface EndDate {
+ /**
+ * Year value.
+ */
+ year: number;
+
+ /**
+ * Day value, when known.
+ */
+ day?: number;
+
+ /**
+ * Month value, when known.
+ */
+ month?: number;
+ }
+
+ /**
+ * Start date, when known.
+ */
+ export interface StartDate {
+ /**
+ * Year value.
+ */
+ year: number;
+
+ /**
+ * Day value, when known.
+ */
+ day?: number;
+
+ /**
+ * Month value, when known.
+ */
+ month?: number;
+ }
+ }
+ }
+
+ export interface Experience {
+ /**
+ * Company or organization name.
+ */
+ company: Experience.Company;
+
+ /**
+ * Role or job title.
+ */
+ title: string;
+
+ /**
+ * Role dates.
+ */
+ dates?: Experience.Dates;
+
+ /**
+ * Role description.
+ */
+ description?: string;
+ }
+
+ export namespace Experience {
+ /**
+ * Company or organization name.
+ */
+ export interface Company {
+ /**
+ * Display name.
+ */
+ display: string;
+
+ /**
+ * Standardized name, when available.
+ */
+ normalized?: string;
+ }
+
+ /**
+ * Role dates.
+ */
+ export interface Dates {
+ /**
+ * End date, when known.
+ */
+ endDate?: Dates.EndDate;
+
+ /**
+ * Whether the entry is current.
+ */
+ isCurrent?: boolean;
+
+ /**
+ * Start date, when known.
+ */
+ startDate?: Dates.StartDate;
+ }
+
+ export namespace Dates {
+ /**
+ * End date, when known.
+ */
+ export interface EndDate {
+ /**
+ * Year value.
+ */
+ year: number;
+
+ /**
+ * Day value, when known.
+ */
+ day?: number;
+
+ /**
+ * Month value, when known.
+ */
+ month?: number;
+ }
+
+ /**
+ * Start date, when known.
+ */
+ export interface StartDate {
+ /**
+ * Year value.
+ */
+ year: number;
+
+ /**
+ * Day value, when known.
+ */
+ day?: number;
+
+ /**
+ * Month value, when known.
+ */
+ month?: number;
+ }
+ }
+ }
+
+ /**
+ * Core profile details.
+ */
+ export interface Profile {
+ /**
+ * Person's full name.
+ */
+ fullName?: string;
+
+ /**
+ * Short professional headline.
+ */
+ headline?: string;
+
+ /**
+ * Person's listed location.
+ */
+ location?: string;
+
+ /**
+ * Profile image URL.
+ */
+ profilePictureUrl?: string;
+
+ /**
+ * Brief profile summary.
+ */
+ summary?: string;
+ }
+
+ export interface Skill {
+ /**
+ * Skill name.
+ */
+ name: string;
+
+ /**
+ * Standardized skill name, when available.
+ */
+ normalized?: string;
+
+ /**
+ * Skill proficiency, when available.
+ */
+ proficiency?: 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;
+
+ /**
+ * The number of credits remaining for your organization after this request.
+ */
+ credits_remaining: number;
+ }
+}
+
+export interface BatchListParams {
+ /**
+ * Cursor from the previous page.
+ */
+ cursor?: string;
+
+ /**
+ * Batches per page. Defaults to 25.
+ */
+ limit?: number;
+
+ /**
+ * 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 {
+ /**
+ * Known identifiers for the person. At least one identifier is required.
+ */
+ identifiers: BatchSubmitParams.Identifiers;
+
+ /**
+ * 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 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;
+ }
+}
+
+export declare namespace Batch {
+ export {
+ type ErrorCount as ErrorCount,
+ type Error as Error,
+ type BatchRetrieveResponse as BatchRetrieveResponse,
+ type BatchListResponse as BatchListResponse,
+ type BatchCancelResponse as BatchCancelResponse,
+ type BatchGetResultsResponse as BatchGetResultsResponse,
+ type BatchSubmitResponse as BatchSubmitResponse,
+ type BatchListParams as BatchListParams,
+ type BatchGetResultsParams as BatchGetResultsParams,
+ type BatchSubmitParams as BatchSubmitParams,
+ };
+}
diff --git a/src/resources/index.ts b/src/resources/index.ts
index fe1b275..114192f 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -7,6 +7,19 @@ export {
type AIExtractProductParams,
type AIExtractProductsParams,
} from './ai';
+export {
+ Batch,
+ type ErrorCount,
+ type Error,
+ type BatchRetrieveResponse,
+ type BatchListResponse,
+ type BatchCancelResponse,
+ type BatchGetResultsResponse,
+ type BatchSubmitResponse,
+ type BatchListParams,
+ type BatchGetResultsParams,
+ type BatchSubmitParams,
+} from './batch';
export {
Brand,
type BrandRetrieveResponse,
diff --git a/src/resources/monitors.ts b/src/resources/monitors.ts
index 9d8d990..e2f6302 100644
--- a/src/resources/monitors.ts
+++ b/src/resources/monitors.ts
@@ -18,15 +18,15 @@ export class Monitors extends APIResource {
* @example
* ```ts
* const monitor = await client.monitors.create({
- * change_detection: { type: 'exact' },
* name: 'Acme pricing page',
+ * target: { type: 'page', url: 'https://acme.com/pricing' },
+ * change_detection: { type: 'exact' },
+ * mode: 'web',
* schedule: {
* type: 'interval',
* frequency: 6,
* unit: 'hours',
* },
- * target: { type: 'page', url: 'https://acme.com/pricing' },
- * mode: 'web',
* webhook: { url: 'https://example.com/webhook' },
* });
* ```
@@ -262,8 +262,8 @@ export namespace WebhookDelivery {
}
/**
- * A web monitor. `mode` is the constant `web`; behavior is described by `target`
- * (page/sitemap/extract) and `change_detection` (exact/semantic).
+ * A newly created monitor plus `initial_run_id`, the id of the baseline run queued
+ * at creation.
*/
export interface MonitorCreateResponse {
id: string;
@@ -277,6 +277,13 @@ export interface MonitorCreateResponse {
created_at: string;
+ /**
+ * The baseline run queued by this create call, or null if it could not be queued
+ * immediately (in which case the baseline runs on the next scheduled tick). Poll
+ * GET /monitors/{monitor_id}/runs/{run_id}.
+ */
+ initial_run_id: string | null;
+
/**
* Top-level monitor category. Always `web` today; the concrete behavior is
* described by `target` and `change_detection`.
@@ -363,9 +370,10 @@ export namespace MonitorCreateResponse {
}
/**
- * Detect meaning-level changes to tracked page content, ignoring cosmetic or
- * paraphrase-only differences. Which changes are meaningful is judged against the
- * extract target's `instructions` (and `schema`, when provided).
+ * Detect meaning-level changes to page content, ignoring cosmetic or
+ * instruction-irrelevant differences. Which changes are meaningful is judged
+ * against the page or extract target's `instructions` (and an extract target's
+ * `schema`, when provided).
*/
export interface MonitorsSemanticChangeDetection {
type: 'semantic';
@@ -392,13 +400,20 @@ export namespace MonitorCreateResponse {
}
/**
- * Watch a single web page.
+ * Watch a single web page. Exact detection reports visible-text diffs; semantic
+ * detection judges confirmed stable diffs against `instructions`.
*/
export interface MonitorsPageTarget {
type: 'page';
url: string;
+ /**
+ * Plain-language goal describing which page changes matter. When provided without
+ * change_detection, semantic detection is inferred.
+ */
+ instructions?: string;
+
/**
* Normalize whitespace before comparing or analyzing text.
*/
@@ -704,9 +719,10 @@ export namespace MonitorRetrieveResponse {
}
/**
- * Detect meaning-level changes to tracked page content, ignoring cosmetic or
- * paraphrase-only differences. Which changes are meaningful is judged against the
- * extract target's `instructions` (and `schema`, when provided).
+ * Detect meaning-level changes to page content, ignoring cosmetic or
+ * instruction-irrelevant differences. Which changes are meaningful is judged
+ * against the page or extract target's `instructions` (and an extract target's
+ * `schema`, when provided).
*/
export interface MonitorsSemanticChangeDetection {
type: 'semantic';
@@ -733,13 +749,20 @@ export namespace MonitorRetrieveResponse {
}
/**
- * Watch a single web page.
+ * Watch a single web page. Exact detection reports visible-text diffs; semantic
+ * detection judges confirmed stable diffs against `instructions`.
*/
export interface MonitorsPageTarget {
type: 'page';
url: string;
+ /**
+ * Plain-language goal describing which page changes matter. When provided without
+ * change_detection, semantic detection is inferred.
+ */
+ instructions?: string;
+
/**
* Normalize whitespace before comparing or analyzing text.
*/
@@ -1045,9 +1068,10 @@ export namespace MonitorUpdateResponse {
}
/**
- * Detect meaning-level changes to tracked page content, ignoring cosmetic or
- * paraphrase-only differences. Which changes are meaningful is judged against the
- * extract target's `instructions` (and `schema`, when provided).
+ * Detect meaning-level changes to page content, ignoring cosmetic or
+ * instruction-irrelevant differences. Which changes are meaningful is judged
+ * against the page or extract target's `instructions` (and an extract target's
+ * `schema`, when provided).
*/
export interface MonitorsSemanticChangeDetection {
type: 'semantic';
@@ -1074,13 +1098,20 @@ export namespace MonitorUpdateResponse {
}
/**
- * Watch a single web page.
+ * Watch a single web page. Exact detection reports visible-text diffs; semantic
+ * detection judges confirmed stable diffs against `instructions`.
*/
export interface MonitorsPageTarget {
type: 'page';
url: string;
+ /**
+ * Plain-language goal describing which page changes matter. When provided without
+ * change_detection, semantic detection is inferred.
+ */
+ instructions?: string;
+
/**
* Normalize whitespace before comparing or analyzing text.
*/
@@ -1386,9 +1417,10 @@ export namespace MonitorListResponse {
}
/**
- * Detect meaning-level changes to tracked page content, ignoring cosmetic or
- * paraphrase-only differences. Which changes are meaningful is judged against the
- * extract target's `instructions` (and `schema`, when provided).
+ * Detect meaning-level changes to page content, ignoring cosmetic or
+ * instruction-irrelevant differences. Which changes are meaningful is judged
+ * against the page or extract target's `instructions` (and an extract target's
+ * `schema`, when provided).
*/
export interface MonitorsSemanticChangeDetection {
type: 'semantic';
@@ -1415,13 +1447,20 @@ export namespace MonitorListResponse {
}
/**
- * Watch a single web page.
+ * Watch a single web page. Exact detection reports visible-text diffs; semantic
+ * detection judges confirmed stable diffs against `instructions`.
*/
export interface MonitorsPageTarget {
type: 'page';
url: string;
+ /**
+ * Plain-language goal describing which page changes matter. When provided without
+ * change_detection, semantic detection is inferred.
+ */
+ instructions?: string;
+
/**
* Normalize whitespace before comparing or analyzing text.
*/
@@ -2062,22 +2101,8 @@ export interface MonitorRunResponse {
}
export interface MonitorCreateParams {
- /**
- * Discriminated union describing how changes are detected.
- */
- change_detection:
- | MonitorCreateParams.MonitorsExactChangeDetection
- | MonitorCreateParams.MonitorsSemanticChangeDetection;
-
name: string;
- /**
- * Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- * every 6 hours or every 2 days. The total interval (frequency × unit) must be
- * between 10 minutes and 1 year.
- */
- schedule: MonitorCreateParams.Schedule;
-
/**
* Discriminated union describing what the monitor watches.
*/
@@ -2086,12 +2111,26 @@ export interface MonitorCreateParams {
| MonitorCreateParams.MonitorsSitemapTarget
| MonitorCreateParams.MonitorsExtractTarget;
+ /**
+ * Discriminated union describing how changes are detected.
+ */
+ change_detection?:
+ | MonitorCreateParams.MonitorsExactChangeDetection
+ | MonitorCreateParams.MonitorsSemanticChangeDetection;
+
/**
* Top-level monitor category. Always `web` today; the concrete behavior is
* described by `target` and `change_detection`.
*/
mode?: 'web';
+ /**
+ * Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ * every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ * between 10 minutes and 1 year.
+ */
+ schedule?: MonitorCreateParams.Schedule;
+
/**
* User-defined tags for grouping and filtering monitors and their changes.
* Duplicates are removed.
@@ -2103,50 +2142,20 @@ export interface MonitorCreateParams {
export namespace MonitorCreateParams {
/**
- * Detect exact changes. For page targets, this means visible text diffs. For
- * sitemap targets, this means URL additions and removals.
- */
- export interface MonitorsExactChangeDetection {
- type: 'exact';
- }
-
- /**
- * Detect meaning-level changes to tracked page content, ignoring cosmetic or
- * paraphrase-only differences. Which changes are meaningful is judged against the
- * extract target's `instructions` (and `schema`, when provided).
- */
- export interface MonitorsSemanticChangeDetection {
- type: 'semantic';
-
- confidence_threshold?: number;
- }
-
- /**
- * Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
- * every 6 hours or every 2 days. The total interval (frequency × unit) must be
- * between 10 minutes and 1 year.
- */
- export interface Schedule {
- /**
- * Number of units between runs. The resulting interval (frequency × unit) must be
- * at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes;
- * maximum 365 when unit is days).
- */
- frequency: number;
-
- type: 'interval';
-
- unit: 'minutes' | 'hours' | 'days';
- }
-
- /**
- * Watch a single web page.
+ * Watch a single web page. Exact detection reports visible-text diffs; semantic
+ * detection judges confirmed stable diffs against `instructions`.
*/
export interface MonitorsPageTarget {
type: 'page';
url: string;
+ /**
+ * Plain-language goal describing which page changes matter. When provided without
+ * change_detection, semantic detection is inferred.
+ */
+ instructions?: string;
+
/**
* Normalize whitespace before comparing or analyzing text.
*/
@@ -2230,6 +2239,44 @@ export namespace MonitorCreateParams {
schema?: { [key: string]: unknown };
}
+ /**
+ * Detect exact changes. For page targets, this means visible text diffs. For
+ * sitemap targets, this means URL additions and removals.
+ */
+ export interface MonitorsExactChangeDetection {
+ type: 'exact';
+ }
+
+ /**
+ * Detect meaning-level changes to page content, ignoring cosmetic or
+ * instruction-irrelevant differences. Which changes are meaningful is judged
+ * against the page or extract target's `instructions` (and an extract target's
+ * `schema`, when provided).
+ */
+ export interface MonitorsSemanticChangeDetection {
+ type: 'semantic';
+
+ confidence_threshold?: number;
+ }
+
+ /**
+ * Run the monitor on a fixed interval defined by a frequency and a unit, e.g.
+ * every 6 hours or every 2 days. The total interval (frequency × unit) must be
+ * between 10 minutes and 1 year.
+ */
+ export interface Schedule {
+ /**
+ * Number of units between runs. The resulting interval (frequency × unit) must be
+ * at least 10 minutes and at most 1 year (e.g. minimum 10 when unit is minutes;
+ * maximum 365 when unit is days).
+ */
+ frequency: number;
+
+ type: 'interval';
+
+ unit: 'minutes' | 'hours' | 'days';
+ }
+
export interface Webhook {
/**
* Webhook URL events are delivered to.
@@ -2295,9 +2342,10 @@ export namespace MonitorUpdateParams {
}
/**
- * Detect meaning-level changes to tracked page content, ignoring cosmetic or
- * paraphrase-only differences. Which changes are meaningful is judged against the
- * extract target's `instructions` (and `schema`, when provided).
+ * Detect meaning-level changes to page content, ignoring cosmetic or
+ * instruction-irrelevant differences. Which changes are meaningful is judged
+ * against the page or extract target's `instructions` (and an extract target's
+ * `schema`, when provided).
*/
export interface MonitorsSemanticChangeDetection {
type: 'semantic';
@@ -2324,13 +2372,20 @@ export namespace MonitorUpdateParams {
}
/**
- * Watch a single web page.
+ * Watch a single web page. Exact detection reports visible-text diffs; semantic
+ * detection judges confirmed stable diffs against `instructions`.
*/
export interface MonitorsPageTarget {
type: 'page';
url: string;
+ /**
+ * Plain-language goal describing which page changes matter. When provided without
+ * change_detection, semantic detection is inferred.
+ */
+ instructions?: string;
+
/**
* Normalize whitespace before comparing or analyzing text.
*/
diff --git a/src/resources/web.ts b/src/resources/web.ts
index bd89fcc..ca71f14 100644
--- a/src/resources/web.ts
+++ b/src/resources/web.ts
@@ -1417,6 +1417,17 @@ export interface WebWebScrapeHTMLResponse {
*/
url: string;
+ /**
+ * One verified outcome per requested browser action, in request order.
+ */
+ actionsApplied?: Array;
+
+ /**
+ * True when an action was applied but the returned content could not be refreshed
+ * afterward.
+ */
+ actionsHtmlStale?: 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.
@@ -1550,6 +1561,29 @@ export namespace WebWebScrapeHTMLResponse {
}
}
+ export interface ActionsApplied {
+ instruction: string;
+
+ /**
+ * Applied means the requested page state was visibly verified. Failed means it was
+ * not verified. Skipped means it was not attempted.
+ */
+ status: 'applied' | 'failed' | 'skipped';
+
+ /**
+ * Visible page evidence used to verify an applied action.
+ */
+ completionEvidence?: string;
+
+ durationMs?: number;
+
+ error?: string;
+
+ method?: string;
+
+ targetDescription?: 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.
@@ -1695,6 +1729,17 @@ export interface WebWebScrapeMdResponse {
*/
url: string;
+ /**
+ * One verified outcome per requested browser action, in request order.
+ */
+ actionsApplied?: Array;
+
+ /**
+ * True when an action was applied but the returned content could not be refreshed
+ * afterward.
+ */
+ actionsHtmlStale?: 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.
@@ -1828,6 +1873,29 @@ export namespace WebWebScrapeMdResponse {
}
}
+ export interface ActionsApplied {
+ instruction: string;
+
+ /**
+ * Applied means the requested page state was visibly verified. Failed means it was
+ * not verified. Skipped means it was not attempted.
+ */
+ status: 'applied' | 'failed' | 'skipped';
+
+ /**
+ * Visible page evidence used to verify an applied action.
+ */
+ completionEvidence?: string;
+
+ durationMs?: number;
+
+ error?: string;
+
+ method?: string;
+
+ targetDescription?: 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.
diff --git a/src/version.ts b/src/version.ts
index cc6e4a8..9556c21 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '2.6.0'; // x-release-please-version
+export const VERSION = '2.7.0'; // x-release-please-version
diff --git a/tests/api-resources/batch.test.ts b/tests/api-resources/batch.test.ts
new file mode 100644
index 0000000..049ab4e
--- /dev/null
+++ b/tests/api-resources/batch.test.ts
@@ -0,0 +1,109 @@
+// 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 batch', () => {
+ // Mock server tests are disabled
+ test.skip('retrieve', async () => {
+ const responsePromise = client.batch.retrieve('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('list', async () => {
+ const responsePromise = client.batch.list();
+ 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('list: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.batch.list(
+ {
+ cursor: 'cursor',
+ limit: 1,
+ q: 'batch_1a2b',
+ search_type: 'exact',
+ status: 'queued',
+ tags: 'docs,competitor',
+ },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(ContextDev.NotFoundError);
+ });
+
+ // Mock server tests are disabled
+ test.skip('cancel', async () => {
+ const responsePromise = client.batch.cancel('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('getResults', async () => {
+ const responsePromise = client.batch.getResults('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('getResults: request options and params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(
+ client.batch.getResults(
+ 'batch_9f2c8a',
+ { cursor: 'cursor', limit: 1 },
+ { path: '/_stainless_unknown_path' },
+ ),
+ ).rejects.toThrow(ContextDev.NotFoundError);
+ });
+
+ // Mock server tests are disabled
+ test.skip('submit: only required params', async () => {
+ const responsePromise = client.batch.submit({ identifiers: {} });
+ 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('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,
+ });
+ });
+});
diff --git a/tests/api-resources/monitors.test.ts b/tests/api-resources/monitors.test.ts
index 26a89f3..cd7c960 100644
--- a/tests/api-resources/monitors.test.ts
+++ b/tests/api-resources/monitors.test.ts
@@ -11,13 +11,7 @@ describe('resource monitors', () => {
// Mock server tests are disabled
test.skip('create: only required params', async () => {
const responsePromise = client.monitors.create({
- change_detection: { type: 'exact' },
name: 'Acme pricing page',
- schedule: {
- frequency: 6,
- type: 'interval',
- unit: 'hours',
- },
target: { type: 'page', url: 'https://acme.com/pricing' },
});
const rawResponse = await responsePromise.asResponse();
@@ -32,19 +26,21 @@ describe('resource monitors', () => {
// Mock server tests are disabled
test.skip('create: required and optional params', async () => {
const response = await client.monitors.create({
- change_detection: { type: 'exact' },
name: 'Acme pricing page',
- schedule: {
- frequency: 6,
- type: 'interval',
- unit: 'hours',
- },
target: {
type: 'page',
url: 'https://acme.com/pricing',
+ instructions:
+ 'Report pricing or plan availability changes. Ignore counters, timestamps, testimonials, and navigation.',
normalize_whitespace: true,
},
+ change_detection: { type: 'exact' },
mode: 'web',
+ schedule: {
+ frequency: 6,
+ type: 'interval',
+ unit: 'hours',
+ },
tags: ['pricing', 'competitor'],
webhook: { url: 'https://example.com/webhook', events: ['change.detected', 'run.completed'] },
});
diff --git a/yarn.lock b/yarn.lock
index 443cc05..f16b683 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1228,9 +1228,9 @@ baseline-browser-mapping@^2.9.0:
integrity sha512-B0xUquLkiGLgHhpPBqvl7GWegWBUNuujQ6kXd/r1U38ElPT6Ok8KZ8e+FpUGEc2ZoRQUzq/aUnaKFc/svWUGSg==
brace-expansion@^2.0.2:
- version "2.1.2"
- resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.2.tgz#0bba2271feb7d458b0d31ad13625aaa4754431e2"
- integrity sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==
+ version "2.1.4"
+ resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.1.4.tgz#589dab11c0018d0366be64cd8bf12c8dbecc8326"
+ integrity sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==
dependencies:
balanced-match "^1.0.0"