@crawlbrulee/sdk 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -129,14 +129,6 @@ interface ResponseMeta {
129
129
  type ScreenshotType = 'viewport' | 'full_page';
130
130
  /** Emulated device class for the viewport (drives default width/height). */
131
131
  type ScreenshotDeviceMode = 'desktop' | 'mobile';
132
- /** Pre-capture cleanup options applied to the page before the screenshot. */
133
- interface ScreenshotCleanup {
134
- /**
135
- * Remove ads, cookie banners, and popups before capturing. Defaults to
136
- * `true` server-side.
137
- */
138
- ads_and_popups?: boolean;
139
- }
140
132
  /** A `wait` action: pause for `ms` milliseconds before the next step. */
141
133
  interface ScreenshotWaitAction {
142
134
  type: 'wait';
@@ -185,8 +177,6 @@ interface ScreenshotRequest {
185
177
  viewport?: ScreenshotViewport;
186
178
  /** Emulate desktop or mobile. Defaults to `desktop`. */
187
179
  device_mode?: ScreenshotDeviceMode;
188
- /** Page cleanup applied before capture. */
189
- cleanup?: ScreenshotCleanup;
190
180
  /** Pre-capture actions (waits and scrolls). Maximum 5 entries. */
191
181
  actions_before?: ScreenshotBeforeAction[];
192
182
  /** Post-capture actions (e.g. slice into tiles). Maximum 1 entry. */
@@ -196,7 +186,7 @@ interface ScreenshotRequest {
196
186
  * Machine-readable error names returned by the crawlbrulee API. Stable
197
187
  * identifiers — clients can switch on them.
198
188
  */
199
- type ApiErrorName = 'usage_allocation_error' | 'request_timeout' | 'invalid_url' | 'url_too_long' | 'client_closed_request' | 'reset_password_token_expired' | 'user_not_found' | 'unsupported_url_schema' | 'url_credentials_not_supported' | 'blocked_url' | 'scrape_error' | 'job_failed' | 'incorrect_login_method_used' | 'not_found' | 'invalid_credentials' | 'resource_already_exists' | 'access_denied' | 'internal_server_error' | 'service_unavailable' | 'too_many_requests' | 'unsupported_content' | 'unsupported_screenshot_output' | 'validation_error' | 'antibot_blocked';
189
+ type ApiErrorName = 'usage_allocation_error' | 'request_timeout' | 'invalid_url' | 'url_too_long' | 'client_closed_request' | 'reset_password_token_expired' | 'user_not_found' | 'unsupported_url_schema' | 'url_credentials_not_supported' | 'blocked_url' | 'scrape_error' | 'job_failed' | 'incorrect_login_method_used' | 'not_found' | 'invalid_credentials' | 'resource_already_exists' | 'access_denied' | 'internal_server_error' | 'service_unavailable' | 'too_many_requests' | 'unsupported_content' | 'unsupported_screenshot_output' | 'validation_error' | 'antibot_blocked' | 'too_many_redirects' | 'page_too_large';
200
190
  /** Reason a usage allocation was denied (when `error_name = usage_allocation_error`). */
201
191
  type UsageAllocationReason = 'credit_limit' | 'concurrency_limit' | 'duplicate_reservation' | 'internal_error';
202
192
  /** Snapshot of the org's current usage at the moment the error was raised. */
@@ -243,6 +233,10 @@ interface ApiErrorResponse {
243
233
  * Which content formats to extract from the scraped page. Every field is
244
234
  * optional; the server defaults are noted on each field. The default request
245
235
  * extracts `{ metadata: true, cleaned_html: true }`.
236
+ *
237
+ * `extract` only selects what is returned — it is not part of the cache key.
238
+ * Every scrape stores the whole page, so adding a field (e.g. `raw_html`) to an
239
+ * otherwise identical request is still a 0-credit cache hit.
246
240
  */
247
241
  interface ScrapeExtract {
248
242
  /** Extract page metadata (title, description, OG/Twitter tags, etc.). Default `true`. */
@@ -274,7 +268,37 @@ interface ScrapeExtract {
274
268
  /** Capture a screenshot. Omit to skip; set to a `ScreenshotRequest` to enable. */
275
269
  screenshot?: ScreenshotRequest;
276
270
  }
277
- /** Cache settings for a scrape request. */
271
+ /**
272
+ * What is removed from the page before any output is built.
273
+ *
274
+ * Applies to `markdown`, `cleaned_html`, `links` and `images` on every engine,
275
+ * and to the screenshot. It never applies to `raw_html` — that is always the
276
+ * page as it arrived, before anything was removed.
277
+ */
278
+ interface ScrapeCleanup {
279
+ /**
280
+ * Remove ads, cookie banners, consent dialogs and chat widgets. Defaults to
281
+ * `true` server-side. Set it to `false` to capture the page as-is, or to get
282
+ * past a site that refuses to serve content to an ad-blocking client.
283
+ */
284
+ ads_and_popups?: boolean;
285
+ /**
286
+ * CSS selectors whose elements are removed before anything is captured. Use
287
+ * it for a banner or widget `ads_and_popups` does not recognise.
288
+ *
289
+ * At most 100 selectors, each at most 500 characters. Sending any selector
290
+ * here makes the request skip the cache, so it always costs a live fetch.
291
+ */
292
+ exclude_selectors?: string[];
293
+ }
294
+ /**
295
+ * Cache settings for a scrape request. A cached result is keyed on the url
296
+ * (after tracking-param cleanup), the screenshot setup (type, viewport, device
297
+ * mode), `cleanup.ads_and_popups` and `location.locale`. `extract` is not part
298
+ * of the key. `require_js: true` only matches browser-rendered results.
299
+ * `cleanup.exclude_selectors` and a non-zero `actions_before` wait or scroll
300
+ * disable the cache for that request.
301
+ */
278
302
  interface ScrapeCache {
279
303
  /**
280
304
  * Maximum cache age. Either a number of seconds (non-negative integer) or
@@ -314,8 +338,14 @@ interface ScrapeRequest {
314
338
  * and credits — only enable when the page requires it. Default `false`.
315
339
  */
316
340
  require_js?: boolean;
317
- /** CSS selectors to strip from the extracted content. */
318
- exclude_selectors?: string[];
341
+ /**
342
+ * What is removed from the page before any output is built. Shapes
343
+ * `markdown`, `cleaned_html`, `links`, `images` and the screenshot.
344
+ *
345
+ * Never applies to `raw_html`, which is always the page before anything was
346
+ * removed.
347
+ */
348
+ cleanup?: ScrapeCleanup;
319
349
  /**
320
350
  * Proxy tier to use for fetching. Defaults to `auto` (tries the basic tier
321
351
  * first, escalates to advanced on failure; billed at the delivered tier).
@@ -542,7 +572,13 @@ interface ScrapeResponse {
542
572
  //#region src/types/map.d.ts
543
573
  /** Filter which link types appear in the map result. */
544
574
  interface MapTypes {
545
- /** Include internal links (same domain). Default `true`. */
575
+ /**
576
+ * Include internal links (same domain; `www.` and the bare domain count as
577
+ * the same site). Default `true`.
578
+ *
579
+ * Note this is only about *classifying* a link — the URLs that come back keep
580
+ * the host exactly as the site publishes it. See {@link MapLinkItem.url}.
581
+ */
546
582
  internal?: boolean;
547
583
  /** Include links to subdomains of the target. Default `true`. */
548
584
  internal_subdomains?: boolean;
@@ -578,14 +614,20 @@ interface MapRequest {
578
614
  /** Cache settings for this request. */
579
615
  cache?: MapCache;
580
616
  /**
581
- * Maximum number of URLs to store in the map. Must be in `(0, 100 000]`.
582
- * Defaults to 100 000.
617
+ * Maximum number of URLs to discover and store in the map. Must be in
618
+ * `(0, 100 000]`. Defaults to 5 000.
619
+ *
620
+ * Sitemap discovery stops as soon as this many URLs have been found, so a
621
+ * smaller value is a cheaper and faster crawl, not just a shorter answer. A
622
+ * map that stopped this way comes back with exactly `max_urls` links and
623
+ * {@link MapTruncation.discovery_cap_reason} set to `max_urls` — ask again
624
+ * with a higher `max_urls` to get more.
583
625
  */
584
626
  max_urls?: number;
585
627
  /** 1-based page number for paginated results. Defaults to 1. */
586
628
  page?: number;
587
629
  /**
588
- * Number of URLs per page. Must be in `(0, 10 000]`. Defaults to 10 000.
630
+ * Number of URLs per page. Must be in `(0, 10 000]`. Defaults to 5 000.
589
631
  */
590
632
  limit?: number;
591
633
  /** Optional country emulation. */
@@ -593,7 +635,12 @@ interface MapRequest {
593
635
  }
594
636
  /** Single discovered URL in a map result. */
595
637
  interface MapLinkItem {
596
- /** The discovered URL. */
638
+ /**
639
+ * The discovered URL, normalised the same way `/scrape` normalises the `url`
640
+ * it returns: the host is kept as the site publishes it (a `www.` host stays
641
+ * `www.`), the query string is sorted with known tracking parameters
642
+ * stripped, and a trailing slash is dropped.
643
+ */
597
644
  url: string;
598
645
  }
599
646
  /** Pagination details on a map response. */
@@ -605,16 +652,50 @@ interface MapPagination {
605
652
  total_pages: number;
606
653
  has_more: boolean;
607
654
  }
655
+ /**
656
+ * Which limit stopped sitemap discovery first, or `null` when nothing stopped
657
+ * it.
658
+ *
659
+ * - `max_urls` — your own {@link MapRequest.max_urls} was reached. This is the
660
+ * only reason you can do something about: ask again with a higher one.
661
+ * - `time` — discovery ran out of its time budget.
662
+ * - `file_budget` — the site has more sitemap files than one request reads.
663
+ * - `depth` — the site's sitemap indexes nest too deeply.
664
+ * - `file_size` — a sitemap file was too large to read.
665
+ */
666
+ type MapDiscoveryCapReason = 'max_urls' | 'time' | 'file_budget' | 'depth' | 'file_size';
608
667
  /** Information about whether the stored or returned map was truncated. */
609
668
  interface MapTruncation {
610
- /** Whether the stored map was capped by `max_urls`. */
669
+ /** Whether the stored map hit the 100 000-URL storage cap. */
611
670
  storage_capped: boolean;
612
- /** Whether the response was capped by pagination. */
671
+ /**
672
+ * Whether more links were eligible than `max_urls`, so the list was trimmed.
673
+ * Discovery itself stops at `max_urls`, so this is normally `true` only when
674
+ * home-page links pushed the total past it. A map that ran into the
675
+ * `max_urls` limit during discovery reports `response_capped: false` and
676
+ * signals the stop through {@link discovery_cap_reason} instead.
677
+ */
613
678
  response_capped: boolean;
614
679
  /** Total URLs found before the `max_urls` cap was applied. */
615
680
  total_before_max_urls: number;
616
681
  /** Total URLs detected during discovery before the storage cap was applied. */
617
682
  total_detected_before_storage_cap: number;
683
+ /**
684
+ * Whether sitemap discovery stopped before it had read every sitemap file it
685
+ * found. When `true`, the site has more pages than this map lists.
686
+ */
687
+ discovery_capped: boolean;
688
+ /**
689
+ * How many sitemap files were skipped or only partly read during discovery,
690
+ * because a file was too large, could not be fetched, or a discovery limit
691
+ * was reached. Integer `>= 0`.
692
+ */
693
+ sitemaps_skipped: number;
694
+ /**
695
+ * Which limit stopped sitemap discovery first, or `null` when nothing did.
696
+ * Only `max_urls` is something you can change from the request.
697
+ */
698
+ discovery_cap_reason: MapDiscoveryCapReason | null;
618
699
  }
619
700
  /** Billing engine reported by map: fresh discovery or a cached result. */
620
701
  type MapBillingEngine = 'text' | 'cache';
@@ -638,7 +719,14 @@ interface MapResponseMeta {
638
719
  }
639
720
  /** Success response from `POST /api/map`. */
640
721
  interface MapResponse {
641
- /** The current page of discovered URLs. */
722
+ /**
723
+ * The current page of discovered URLs.
724
+ *
725
+ * Ordering is stable: link type first, then home-page links before
726
+ * sitemap-only links, then shallower paths before deeper ones, then
727
+ * alphabetical. Where a URL came from drives that ordering server-side and is
728
+ * deliberately not returned.
729
+ */
642
730
  links: MapLinkItem[];
643
731
  /** Usage, pagination, and truncation metadata for the result set. */
644
732
  response_meta: MapResponseMeta;
@@ -947,7 +1035,14 @@ declare class CrawlbruleeError extends Error {
947
1035
  cause?: unknown;
948
1036
  });
949
1037
  }
950
- /** Raised for 401 / 403 responses (missing, invalid, or unauthorized API key). */
1038
+ /**
1039
+ * Raised when the API rejects your credentials — a missing, invalid, or
1040
+ * unauthorized API key (`invalid_credentials`, `access_denied`).
1041
+ *
1042
+ * Not every 403 is a key problem: a 403 carrying `antibot_blocked` is the
1043
+ * *target site* blocking us and raises {@link AntibotBlockedError} instead.
1044
+ * Only an unrecognized 403 name falls back to this class.
1045
+ */
951
1046
  declare class AuthenticationError extends CrawlbruleeError {
952
1047
  constructor(message: string, options: {
953
1048
  status: number;
@@ -955,6 +1050,46 @@ declare class AuthenticationError extends CrawlbruleeError {
955
1050
  response?: ApiErrorResponse;
956
1051
  });
957
1052
  }
1053
+ /**
1054
+ * Raised when the target site's anti-bot protection blocked the request
1055
+ * (HTTP 403, `antibot_blocked`). Not an API-key problem — retrying the same
1056
+ * tier rarely helps; try a higher proxy tier or skip the site.
1057
+ */
1058
+ declare class AntibotBlockedError extends CrawlbruleeError {
1059
+ constructor(message: string, options: {
1060
+ status: number;
1061
+ errorName: ApiErrorName;
1062
+ response?: ApiErrorResponse;
1063
+ });
1064
+ }
1065
+ /**
1066
+ * Raised when the target site redirected the request in a loop, or through
1067
+ * more hops than the API follows (HTTP 422, `too_many_redirects`). Like
1068
+ * {@link AntibotBlockedError} this is the target's doing — not a key problem
1069
+ * and not a bad request — so it is neither an `AuthenticationError` nor a
1070
+ * `ValidationError`. Retrying rarely helps. Returned by both `scrape` and `map`.
1071
+ */
1072
+ declare class TooManyRedirectsError extends CrawlbruleeError {
1073
+ constructor(message: string, options: {
1074
+ status: number;
1075
+ errorName: ApiErrorName;
1076
+ response?: ApiErrorResponse;
1077
+ });
1078
+ }
1079
+ /**
1080
+ * Raised when the page's HTML was too large to process (HTTP 422,
1081
+ * `page_too_large`). Like {@link TooManyRedirectsError} this is about the page,
1082
+ * not your request — so it is neither an `AuthenticationError` nor a
1083
+ * `ValidationError`. It is terminal: the same URL fails the same way, so do not
1084
+ * retry it. Returned by `scrape`.
1085
+ */
1086
+ declare class PageTooLargeError extends CrawlbruleeError {
1087
+ constructor(message: string, options: {
1088
+ status: number;
1089
+ errorName: ApiErrorName;
1090
+ response?: ApiErrorResponse;
1091
+ });
1092
+ }
958
1093
  /**
959
1094
  * Raised for HTTP 429 responses. When the server included a `retry_after_ms`
960
1095
  * hint in `details` it is surfaced directly on the instance.
@@ -1149,5 +1284,5 @@ interface VerifyWebhookSignatureOptions {
1149
1284
  */
1150
1285
  declare function verifyWebhookSignature(options: VerifyWebhookSignatureOptions): Promise<WebhookVerificationResult>;
1151
1286
  //#endregion
1152
- export { ApiErrorDetails, ApiErrorName, ApiErrorResponse, AsyncJobStatus, AsyncJobStatusResponse, AsyncScrapeRequest, AsyncScrapeResponse, AsyncScrapeWebhook, AuthenticationError, BillingEngine, Crawlbrulee, CrawlbruleeError, type CrawlbruleeOptions, DEFAULT_BASE_URL, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_WEBHOOK_TOLERANCE_SECONDS, ENV_API_KEY, type HttpMethod, MapBillingEngine, MapCache, MapLinkItem, MapLocation, MapPagination, MapRequest, MapResponse, MapResponseMeta, MapTruncation, MapTypes, MapUsage, NotFoundError, PageInlineImage, PageLink, ProxyTier, RateLimitError, RateLimitErrorDetails, type RequestOptions, ResolvedProxyTier, ResponseMeta, ScrapeCache, ScrapeCompleteWebhook, ScrapeCompleteWebhookData, ScrapeExtract, ScrapeLocation, ScrapeMetadata, ScrapeRequest, ScrapeResponse, ScrapeWarningCode, ScrapeWebhookStatus, ScreenshotAfterAction, ScreenshotBeforeAction, ScreenshotCleanup, ScreenshotDeviceMode, ScreenshotProperties, ScreenshotRequest, ScreenshotResult, ScreenshotScrollAction, ScreenshotSlice, ScreenshotSliceAction, ScreenshotType, ScreenshotViewport, ScreenshotViewportInfo, ScreenshotWaitAction, ServiceUnavailableError, TransportError, Usage, UsageAllocationError, UsageAllocationErrorDetails, UsageAllocationReason, UsageLimitDetails, UsageResponse, ValidationError, type VerifyWebhookSignatureOptions, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_SIGNATURE_ROTATED_HEADER, type WaitForScrapeOptions, type WebhookSignatureSource, type WebhookVerificationFailureReason, type WebhookVerificationResult, WhoamiResponse, isCrawlbruleeError, verifyWebhookSignature };
1287
+ export { AntibotBlockedError, ApiErrorDetails, ApiErrorName, ApiErrorResponse, AsyncJobStatus, AsyncJobStatusResponse, AsyncScrapeRequest, AsyncScrapeResponse, AsyncScrapeWebhook, AuthenticationError, BillingEngine, Crawlbrulee, CrawlbruleeError, type CrawlbruleeOptions, DEFAULT_BASE_URL, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_WEBHOOK_TOLERANCE_SECONDS, ENV_API_KEY, type HttpMethod, MapBillingEngine, MapCache, MapDiscoveryCapReason, MapLinkItem, MapLocation, MapPagination, MapRequest, MapResponse, MapResponseMeta, MapTruncation, MapTypes, MapUsage, NotFoundError, PageInlineImage, PageLink, PageTooLargeError, ProxyTier, RateLimitError, RateLimitErrorDetails, type RequestOptions, ResolvedProxyTier, ResponseMeta, ScrapeCache, ScrapeCleanup, ScrapeCompleteWebhook, ScrapeCompleteWebhookData, ScrapeExtract, ScrapeLocation, ScrapeMetadata, ScrapeRequest, ScrapeResponse, ScrapeWarningCode, ScrapeWebhookStatus, ScreenshotAfterAction, ScreenshotBeforeAction, ScreenshotDeviceMode, ScreenshotProperties, ScreenshotRequest, ScreenshotResult, ScreenshotScrollAction, ScreenshotSlice, ScreenshotSliceAction, ScreenshotType, ScreenshotViewport, ScreenshotViewportInfo, ScreenshotWaitAction, ServiceUnavailableError, TooManyRedirectsError, TransportError, Usage, UsageAllocationError, UsageAllocationErrorDetails, UsageAllocationReason, UsageLimitDetails, UsageResponse, ValidationError, type VerifyWebhookSignatureOptions, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_SIGNATURE_ROTATED_HEADER, type WaitForScrapeOptions, type WebhookSignatureSource, type WebhookVerificationFailureReason, type WebhookVerificationResult, WhoamiResponse, isCrawlbruleeError, verifyWebhookSignature };
1153
1288
  //# sourceMappingURL=index.d.cts.map
package/dist/index.d.ts CHANGED
@@ -129,14 +129,6 @@ interface ResponseMeta {
129
129
  type ScreenshotType = 'viewport' | 'full_page';
130
130
  /** Emulated device class for the viewport (drives default width/height). */
131
131
  type ScreenshotDeviceMode = 'desktop' | 'mobile';
132
- /** Pre-capture cleanup options applied to the page before the screenshot. */
133
- interface ScreenshotCleanup {
134
- /**
135
- * Remove ads, cookie banners, and popups before capturing. Defaults to
136
- * `true` server-side.
137
- */
138
- ads_and_popups?: boolean;
139
- }
140
132
  /** A `wait` action: pause for `ms` milliseconds before the next step. */
141
133
  interface ScreenshotWaitAction {
142
134
  type: 'wait';
@@ -185,8 +177,6 @@ interface ScreenshotRequest {
185
177
  viewport?: ScreenshotViewport;
186
178
  /** Emulate desktop or mobile. Defaults to `desktop`. */
187
179
  device_mode?: ScreenshotDeviceMode;
188
- /** Page cleanup applied before capture. */
189
- cleanup?: ScreenshotCleanup;
190
180
  /** Pre-capture actions (waits and scrolls). Maximum 5 entries. */
191
181
  actions_before?: ScreenshotBeforeAction[];
192
182
  /** Post-capture actions (e.g. slice into tiles). Maximum 1 entry. */
@@ -196,7 +186,7 @@ interface ScreenshotRequest {
196
186
  * Machine-readable error names returned by the crawlbrulee API. Stable
197
187
  * identifiers — clients can switch on them.
198
188
  */
199
- type ApiErrorName = 'usage_allocation_error' | 'request_timeout' | 'invalid_url' | 'url_too_long' | 'client_closed_request' | 'reset_password_token_expired' | 'user_not_found' | 'unsupported_url_schema' | 'url_credentials_not_supported' | 'blocked_url' | 'scrape_error' | 'job_failed' | 'incorrect_login_method_used' | 'not_found' | 'invalid_credentials' | 'resource_already_exists' | 'access_denied' | 'internal_server_error' | 'service_unavailable' | 'too_many_requests' | 'unsupported_content' | 'unsupported_screenshot_output' | 'validation_error' | 'antibot_blocked';
189
+ type ApiErrorName = 'usage_allocation_error' | 'request_timeout' | 'invalid_url' | 'url_too_long' | 'client_closed_request' | 'reset_password_token_expired' | 'user_not_found' | 'unsupported_url_schema' | 'url_credentials_not_supported' | 'blocked_url' | 'scrape_error' | 'job_failed' | 'incorrect_login_method_used' | 'not_found' | 'invalid_credentials' | 'resource_already_exists' | 'access_denied' | 'internal_server_error' | 'service_unavailable' | 'too_many_requests' | 'unsupported_content' | 'unsupported_screenshot_output' | 'validation_error' | 'antibot_blocked' | 'too_many_redirects' | 'page_too_large';
200
190
  /** Reason a usage allocation was denied (when `error_name = usage_allocation_error`). */
201
191
  type UsageAllocationReason = 'credit_limit' | 'concurrency_limit' | 'duplicate_reservation' | 'internal_error';
202
192
  /** Snapshot of the org's current usage at the moment the error was raised. */
@@ -243,6 +233,10 @@ interface ApiErrorResponse {
243
233
  * Which content formats to extract from the scraped page. Every field is
244
234
  * optional; the server defaults are noted on each field. The default request
245
235
  * extracts `{ metadata: true, cleaned_html: true }`.
236
+ *
237
+ * `extract` only selects what is returned — it is not part of the cache key.
238
+ * Every scrape stores the whole page, so adding a field (e.g. `raw_html`) to an
239
+ * otherwise identical request is still a 0-credit cache hit.
246
240
  */
247
241
  interface ScrapeExtract {
248
242
  /** Extract page metadata (title, description, OG/Twitter tags, etc.). Default `true`. */
@@ -274,7 +268,37 @@ interface ScrapeExtract {
274
268
  /** Capture a screenshot. Omit to skip; set to a `ScreenshotRequest` to enable. */
275
269
  screenshot?: ScreenshotRequest;
276
270
  }
277
- /** Cache settings for a scrape request. */
271
+ /**
272
+ * What is removed from the page before any output is built.
273
+ *
274
+ * Applies to `markdown`, `cleaned_html`, `links` and `images` on every engine,
275
+ * and to the screenshot. It never applies to `raw_html` — that is always the
276
+ * page as it arrived, before anything was removed.
277
+ */
278
+ interface ScrapeCleanup {
279
+ /**
280
+ * Remove ads, cookie banners, consent dialogs and chat widgets. Defaults to
281
+ * `true` server-side. Set it to `false` to capture the page as-is, or to get
282
+ * past a site that refuses to serve content to an ad-blocking client.
283
+ */
284
+ ads_and_popups?: boolean;
285
+ /**
286
+ * CSS selectors whose elements are removed before anything is captured. Use
287
+ * it for a banner or widget `ads_and_popups` does not recognise.
288
+ *
289
+ * At most 100 selectors, each at most 500 characters. Sending any selector
290
+ * here makes the request skip the cache, so it always costs a live fetch.
291
+ */
292
+ exclude_selectors?: string[];
293
+ }
294
+ /**
295
+ * Cache settings for a scrape request. A cached result is keyed on the url
296
+ * (after tracking-param cleanup), the screenshot setup (type, viewport, device
297
+ * mode), `cleanup.ads_and_popups` and `location.locale`. `extract` is not part
298
+ * of the key. `require_js: true` only matches browser-rendered results.
299
+ * `cleanup.exclude_selectors` and a non-zero `actions_before` wait or scroll
300
+ * disable the cache for that request.
301
+ */
278
302
  interface ScrapeCache {
279
303
  /**
280
304
  * Maximum cache age. Either a number of seconds (non-negative integer) or
@@ -314,8 +338,14 @@ interface ScrapeRequest {
314
338
  * and credits — only enable when the page requires it. Default `false`.
315
339
  */
316
340
  require_js?: boolean;
317
- /** CSS selectors to strip from the extracted content. */
318
- exclude_selectors?: string[];
341
+ /**
342
+ * What is removed from the page before any output is built. Shapes
343
+ * `markdown`, `cleaned_html`, `links`, `images` and the screenshot.
344
+ *
345
+ * Never applies to `raw_html`, which is always the page before anything was
346
+ * removed.
347
+ */
348
+ cleanup?: ScrapeCleanup;
319
349
  /**
320
350
  * Proxy tier to use for fetching. Defaults to `auto` (tries the basic tier
321
351
  * first, escalates to advanced on failure; billed at the delivered tier).
@@ -542,7 +572,13 @@ interface ScrapeResponse {
542
572
  //#region src/types/map.d.ts
543
573
  /** Filter which link types appear in the map result. */
544
574
  interface MapTypes {
545
- /** Include internal links (same domain). Default `true`. */
575
+ /**
576
+ * Include internal links (same domain; `www.` and the bare domain count as
577
+ * the same site). Default `true`.
578
+ *
579
+ * Note this is only about *classifying* a link — the URLs that come back keep
580
+ * the host exactly as the site publishes it. See {@link MapLinkItem.url}.
581
+ */
546
582
  internal?: boolean;
547
583
  /** Include links to subdomains of the target. Default `true`. */
548
584
  internal_subdomains?: boolean;
@@ -578,14 +614,20 @@ interface MapRequest {
578
614
  /** Cache settings for this request. */
579
615
  cache?: MapCache;
580
616
  /**
581
- * Maximum number of URLs to store in the map. Must be in `(0, 100 000]`.
582
- * Defaults to 100 000.
617
+ * Maximum number of URLs to discover and store in the map. Must be in
618
+ * `(0, 100 000]`. Defaults to 5 000.
619
+ *
620
+ * Sitemap discovery stops as soon as this many URLs have been found, so a
621
+ * smaller value is a cheaper and faster crawl, not just a shorter answer. A
622
+ * map that stopped this way comes back with exactly `max_urls` links and
623
+ * {@link MapTruncation.discovery_cap_reason} set to `max_urls` — ask again
624
+ * with a higher `max_urls` to get more.
583
625
  */
584
626
  max_urls?: number;
585
627
  /** 1-based page number for paginated results. Defaults to 1. */
586
628
  page?: number;
587
629
  /**
588
- * Number of URLs per page. Must be in `(0, 10 000]`. Defaults to 10 000.
630
+ * Number of URLs per page. Must be in `(0, 10 000]`. Defaults to 5 000.
589
631
  */
590
632
  limit?: number;
591
633
  /** Optional country emulation. */
@@ -593,7 +635,12 @@ interface MapRequest {
593
635
  }
594
636
  /** Single discovered URL in a map result. */
595
637
  interface MapLinkItem {
596
- /** The discovered URL. */
638
+ /**
639
+ * The discovered URL, normalised the same way `/scrape` normalises the `url`
640
+ * it returns: the host is kept as the site publishes it (a `www.` host stays
641
+ * `www.`), the query string is sorted with known tracking parameters
642
+ * stripped, and a trailing slash is dropped.
643
+ */
597
644
  url: string;
598
645
  }
599
646
  /** Pagination details on a map response. */
@@ -605,16 +652,50 @@ interface MapPagination {
605
652
  total_pages: number;
606
653
  has_more: boolean;
607
654
  }
655
+ /**
656
+ * Which limit stopped sitemap discovery first, or `null` when nothing stopped
657
+ * it.
658
+ *
659
+ * - `max_urls` — your own {@link MapRequest.max_urls} was reached. This is the
660
+ * only reason you can do something about: ask again with a higher one.
661
+ * - `time` — discovery ran out of its time budget.
662
+ * - `file_budget` — the site has more sitemap files than one request reads.
663
+ * - `depth` — the site's sitemap indexes nest too deeply.
664
+ * - `file_size` — a sitemap file was too large to read.
665
+ */
666
+ type MapDiscoveryCapReason = 'max_urls' | 'time' | 'file_budget' | 'depth' | 'file_size';
608
667
  /** Information about whether the stored or returned map was truncated. */
609
668
  interface MapTruncation {
610
- /** Whether the stored map was capped by `max_urls`. */
669
+ /** Whether the stored map hit the 100 000-URL storage cap. */
611
670
  storage_capped: boolean;
612
- /** Whether the response was capped by pagination. */
671
+ /**
672
+ * Whether more links were eligible than `max_urls`, so the list was trimmed.
673
+ * Discovery itself stops at `max_urls`, so this is normally `true` only when
674
+ * home-page links pushed the total past it. A map that ran into the
675
+ * `max_urls` limit during discovery reports `response_capped: false` and
676
+ * signals the stop through {@link discovery_cap_reason} instead.
677
+ */
613
678
  response_capped: boolean;
614
679
  /** Total URLs found before the `max_urls` cap was applied. */
615
680
  total_before_max_urls: number;
616
681
  /** Total URLs detected during discovery before the storage cap was applied. */
617
682
  total_detected_before_storage_cap: number;
683
+ /**
684
+ * Whether sitemap discovery stopped before it had read every sitemap file it
685
+ * found. When `true`, the site has more pages than this map lists.
686
+ */
687
+ discovery_capped: boolean;
688
+ /**
689
+ * How many sitemap files were skipped or only partly read during discovery,
690
+ * because a file was too large, could not be fetched, or a discovery limit
691
+ * was reached. Integer `>= 0`.
692
+ */
693
+ sitemaps_skipped: number;
694
+ /**
695
+ * Which limit stopped sitemap discovery first, or `null` when nothing did.
696
+ * Only `max_urls` is something you can change from the request.
697
+ */
698
+ discovery_cap_reason: MapDiscoveryCapReason | null;
618
699
  }
619
700
  /** Billing engine reported by map: fresh discovery or a cached result. */
620
701
  type MapBillingEngine = 'text' | 'cache';
@@ -638,7 +719,14 @@ interface MapResponseMeta {
638
719
  }
639
720
  /** Success response from `POST /api/map`. */
640
721
  interface MapResponse {
641
- /** The current page of discovered URLs. */
722
+ /**
723
+ * The current page of discovered URLs.
724
+ *
725
+ * Ordering is stable: link type first, then home-page links before
726
+ * sitemap-only links, then shallower paths before deeper ones, then
727
+ * alphabetical. Where a URL came from drives that ordering server-side and is
728
+ * deliberately not returned.
729
+ */
642
730
  links: MapLinkItem[];
643
731
  /** Usage, pagination, and truncation metadata for the result set. */
644
732
  response_meta: MapResponseMeta;
@@ -947,7 +1035,14 @@ declare class CrawlbruleeError extends Error {
947
1035
  cause?: unknown;
948
1036
  });
949
1037
  }
950
- /** Raised for 401 / 403 responses (missing, invalid, or unauthorized API key). */
1038
+ /**
1039
+ * Raised when the API rejects your credentials — a missing, invalid, or
1040
+ * unauthorized API key (`invalid_credentials`, `access_denied`).
1041
+ *
1042
+ * Not every 403 is a key problem: a 403 carrying `antibot_blocked` is the
1043
+ * *target site* blocking us and raises {@link AntibotBlockedError} instead.
1044
+ * Only an unrecognized 403 name falls back to this class.
1045
+ */
951
1046
  declare class AuthenticationError extends CrawlbruleeError {
952
1047
  constructor(message: string, options: {
953
1048
  status: number;
@@ -955,6 +1050,46 @@ declare class AuthenticationError extends CrawlbruleeError {
955
1050
  response?: ApiErrorResponse;
956
1051
  });
957
1052
  }
1053
+ /**
1054
+ * Raised when the target site's anti-bot protection blocked the request
1055
+ * (HTTP 403, `antibot_blocked`). Not an API-key problem — retrying the same
1056
+ * tier rarely helps; try a higher proxy tier or skip the site.
1057
+ */
1058
+ declare class AntibotBlockedError extends CrawlbruleeError {
1059
+ constructor(message: string, options: {
1060
+ status: number;
1061
+ errorName: ApiErrorName;
1062
+ response?: ApiErrorResponse;
1063
+ });
1064
+ }
1065
+ /**
1066
+ * Raised when the target site redirected the request in a loop, or through
1067
+ * more hops than the API follows (HTTP 422, `too_many_redirects`). Like
1068
+ * {@link AntibotBlockedError} this is the target's doing — not a key problem
1069
+ * and not a bad request — so it is neither an `AuthenticationError` nor a
1070
+ * `ValidationError`. Retrying rarely helps. Returned by both `scrape` and `map`.
1071
+ */
1072
+ declare class TooManyRedirectsError extends CrawlbruleeError {
1073
+ constructor(message: string, options: {
1074
+ status: number;
1075
+ errorName: ApiErrorName;
1076
+ response?: ApiErrorResponse;
1077
+ });
1078
+ }
1079
+ /**
1080
+ * Raised when the page's HTML was too large to process (HTTP 422,
1081
+ * `page_too_large`). Like {@link TooManyRedirectsError} this is about the page,
1082
+ * not your request — so it is neither an `AuthenticationError` nor a
1083
+ * `ValidationError`. It is terminal: the same URL fails the same way, so do not
1084
+ * retry it. Returned by `scrape`.
1085
+ */
1086
+ declare class PageTooLargeError extends CrawlbruleeError {
1087
+ constructor(message: string, options: {
1088
+ status: number;
1089
+ errorName: ApiErrorName;
1090
+ response?: ApiErrorResponse;
1091
+ });
1092
+ }
958
1093
  /**
959
1094
  * Raised for HTTP 429 responses. When the server included a `retry_after_ms`
960
1095
  * hint in `details` it is surfaced directly on the instance.
@@ -1149,5 +1284,5 @@ interface VerifyWebhookSignatureOptions {
1149
1284
  */
1150
1285
  declare function verifyWebhookSignature(options: VerifyWebhookSignatureOptions): Promise<WebhookVerificationResult>;
1151
1286
  //#endregion
1152
- export { ApiErrorDetails, ApiErrorName, ApiErrorResponse, AsyncJobStatus, AsyncJobStatusResponse, AsyncScrapeRequest, AsyncScrapeResponse, AsyncScrapeWebhook, AuthenticationError, BillingEngine, Crawlbrulee, CrawlbruleeError, type CrawlbruleeOptions, DEFAULT_BASE_URL, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_WEBHOOK_TOLERANCE_SECONDS, ENV_API_KEY, type HttpMethod, MapBillingEngine, MapCache, MapLinkItem, MapLocation, MapPagination, MapRequest, MapResponse, MapResponseMeta, MapTruncation, MapTypes, MapUsage, NotFoundError, PageInlineImage, PageLink, ProxyTier, RateLimitError, RateLimitErrorDetails, type RequestOptions, ResolvedProxyTier, ResponseMeta, ScrapeCache, ScrapeCompleteWebhook, ScrapeCompleteWebhookData, ScrapeExtract, ScrapeLocation, ScrapeMetadata, ScrapeRequest, ScrapeResponse, ScrapeWarningCode, ScrapeWebhookStatus, ScreenshotAfterAction, ScreenshotBeforeAction, ScreenshotCleanup, ScreenshotDeviceMode, ScreenshotProperties, ScreenshotRequest, ScreenshotResult, ScreenshotScrollAction, ScreenshotSlice, ScreenshotSliceAction, ScreenshotType, ScreenshotViewport, ScreenshotViewportInfo, ScreenshotWaitAction, ServiceUnavailableError, TransportError, Usage, UsageAllocationError, UsageAllocationErrorDetails, UsageAllocationReason, UsageLimitDetails, UsageResponse, ValidationError, type VerifyWebhookSignatureOptions, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_SIGNATURE_ROTATED_HEADER, type WaitForScrapeOptions, type WebhookSignatureSource, type WebhookVerificationFailureReason, type WebhookVerificationResult, WhoamiResponse, isCrawlbruleeError, verifyWebhookSignature };
1287
+ export { AntibotBlockedError, ApiErrorDetails, ApiErrorName, ApiErrorResponse, AsyncJobStatus, AsyncJobStatusResponse, AsyncScrapeRequest, AsyncScrapeResponse, AsyncScrapeWebhook, AuthenticationError, BillingEngine, Crawlbrulee, CrawlbruleeError, type CrawlbruleeOptions, DEFAULT_BASE_URL, DEFAULT_REQUEST_TIMEOUT_MS, DEFAULT_WEBHOOK_TOLERANCE_SECONDS, ENV_API_KEY, type HttpMethod, MapBillingEngine, MapCache, MapDiscoveryCapReason, MapLinkItem, MapLocation, MapPagination, MapRequest, MapResponse, MapResponseMeta, MapTruncation, MapTypes, MapUsage, NotFoundError, PageInlineImage, PageLink, PageTooLargeError, ProxyTier, RateLimitError, RateLimitErrorDetails, type RequestOptions, ResolvedProxyTier, ResponseMeta, ScrapeCache, ScrapeCleanup, ScrapeCompleteWebhook, ScrapeCompleteWebhookData, ScrapeExtract, ScrapeLocation, ScrapeMetadata, ScrapeRequest, ScrapeResponse, ScrapeWarningCode, ScrapeWebhookStatus, ScreenshotAfterAction, ScreenshotBeforeAction, ScreenshotDeviceMode, ScreenshotProperties, ScreenshotRequest, ScreenshotResult, ScreenshotScrollAction, ScreenshotSlice, ScreenshotSliceAction, ScreenshotType, ScreenshotViewport, ScreenshotViewportInfo, ScreenshotWaitAction, ServiceUnavailableError, TooManyRedirectsError, TransportError, Usage, UsageAllocationError, UsageAllocationErrorDetails, UsageAllocationReason, UsageLimitDetails, UsageResponse, ValidationError, type VerifyWebhookSignatureOptions, WEBHOOK_EVENT_ID_HEADER, WEBHOOK_SIGNATURE_HEADER, WEBHOOK_SIGNATURE_ROTATED_HEADER, type WaitForScrapeOptions, type WebhookSignatureSource, type WebhookVerificationFailureReason, type WebhookVerificationResult, WhoamiResponse, isCrawlbruleeError, verifyWebhookSignature };
1153
1288
  //# sourceMappingURL=index.d.ts.map