@scrapa/sdk 0.2.2 → 0.4.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.
@@ -1,35 +1,63 @@
1
1
  /** Arguments for `scrape()`. */
2
2
  export interface ScrapeParams {
3
- /** The page to read. An http(s) URL — private and loopback hosts are refused. */
3
+ /** The page to read. An http(s) URL. Private and loopback hosts are refused. */
4
4
  url: string;
5
5
  /** How to read it. "fetch" is a plain HTTP request; "browser" renders the page in a real
6
- * Chromium; "auto" fetches first and escalates to the browser when the body turns out to be a
7
- * JavaScript shell, billing whichever engine answered. */
6
+ * Chromium; "auto" (the default) fetches first and escalates to the browser when the body
7
+ * turns out to be a JavaScript shell, billing whichever engine answered. A POST and "raw"
8
+ * always use "fetch", so leave it out for them. */
8
9
  engine?: "auto" | "fetch" | "browser";
9
- /** Whether to try again a different way when the first attempt is blocked. `false` stops after
10
- * one try — the site's refusal is your answer, and it costs nothing. It is how you bound a
11
- * call: with `auto`, trying again is what charges the browser price instead of the fetch one. */
10
+ /** Whether to try again a different way when the first attempt is blocked. On by default.
11
+ * `false` stops after one try. The site's refusal is your answer, and it costs nothing. It is
12
+ * how you bound a call: with `auto`, trying again is what charges the browser price instead of
13
+ * the fetch one. A POST is sent once, so it is off for a POST. */
12
14
  escalate?: boolean;
15
+ /** The HTTP method. "POST" sends `body` to the URL, for a search form or a JSON query. It is
16
+ * sent once: never retried and never sent again another way, because sending it twice could
17
+ * repeat what it did. */
18
+ method?: "GET" | "POST";
19
+ /** What a POST sends, at most 64 KB. Set its type in `headers`: `{"content-type":
20
+ * "application/json"}` for JSON, or `application/x-www-form-urlencoded` for a form. If the
21
+ * site redirects, a 301, 302 or 303 reads the next page with GET and without the body; a 307
22
+ * or 308 sends it again only if the protocol, host and port stay the same, and otherwise stops
23
+ * and names the new address. */
24
+ body?: string;
13
25
  /** How many extra tries to give a page the site blocks, each from a different address. 0 (the
14
26
  * default) takes the site's first no as the answer. A blocked page costs nothing, so a try
15
- * that is blocked again is free — but it takes as long as the first one did, so the call can
27
+ * that is blocked again is free, but it takes as long as the first one did, so the call can
16
28
  * run that many times longer. */
17
29
  retry?: number;
18
30
  /** What to hand back. "screenshot" and "pdf" come back as base64 and need the browser engine;
19
31
  * asking for both costs no more than one. "extract" is the page read into fields by a model,
20
- * and needs an `extract` block saying which ones. */
21
- formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract")[];
32
+ * and needs an `extract` block saying which ones. A link to a PDF or a Word (.docx) file is
33
+ * read into text, so the text formats work on it too. We read files up to 25 MB and the first
34
+ * 200 pages, at the fetch price. "raw" is the file exactly as the site sent it, as base64 with
35
+ * its content type: a PDF report, an image, a spreadsheet. It uses the fetch engine and holds
36
+ * up to 5 MB; a larger file answers FILE_TOO_LARGE at no charge, never cut short. */
37
+ formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract" | "raw")[];
38
+ /** Read only the page's main content into `markdown`, `text` and `extract`: the article or the
39
+ * product, without the menus, ads and related links around it. On by default. Set `false` for
40
+ * the whole page. When the main content is under 50 words, you get the whole page instead.
41
+ * `html` and `links` always hold the whole page. */
42
+ onlyMainContent?: boolean;
43
+ /** CSS selectors for the parts of the page to keep, such as `["h1", ".price"]`. `markdown`,
44
+ * `text` and `extract` then hold only what they match, in page order, and `onlyMainContent` no
45
+ * longer applies. Hidden parts are never kept. Up to 20 selectors, 256 characters each. */
46
+ includeTags?: string[];
47
+ /** CSS selectors for the parts of the page to leave out of `markdown`, `text` and `extract`,
48
+ * such as `[".comments", "#newsletter"]`. Up to 20 selectors, 256 characters each. */
49
+ excludeTags?: string[];
22
50
  /** What the page should answer with. Set `"json"` when you are reading an API: anything else
23
- * that comes back — a maintenance notice, a "checking your browser" page, a login form — is
24
- * then not your answer. It costs nothing, and we try again from another address instead of
25
- * handing you a page you cannot parse. Without it, whatever the page returns is your answer. */
51
+ * that comes back (a maintenance notice, a "checking your browser" page, a login form) is then
52
+ * not your answer. It costs nothing, and we try again from another address instead of handing
53
+ * you a page you cannot parse. Without it, whatever the page returns is your answer. */
26
54
  expect?: "json";
27
55
  /** What to pull out of the page, for the "extract" format. A model reads the page and fills in
28
- * the shape you asked for — give it a JSON Schema, a sentence, or both. It reads what the page
56
+ * the shape you asked for. Give it a JSON Schema, a sentence, or both. It reads what the page
29
57
  * says; it does not do arithmetic over it, so ask for the numbers and add them up in your own
30
58
  * code. */
31
59
  extract?: {
32
- /** The shape you want back, as JSON Schema — an object whose properties are the fields you
60
+ /** The shape you want back, as JSON Schema: an object whose properties are the fields you
33
61
  * need. A field the page does not mention comes back null; nothing is invented to fill it. */
34
62
  schema?: Record<string, unknown>;
35
63
  /** What to pull out, in your own words: `the price, the author and the date it was
@@ -40,7 +68,7 @@ export interface ScrapeParams {
40
68
  /** Where the request leaves from. Defaults to the managed residential pool. */
41
69
  proxy?: {
42
70
  /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
43
- * "custom" is your own proxy — free on every plan, bytes never billed. */
71
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
44
72
  pool?: "residential" | "custom";
45
73
  /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
46
74
  * for the managed one. */
@@ -60,7 +88,7 @@ export interface ScrapeParams {
60
88
  * charge; ask for the state or the country alone. */
61
89
  city?: string;
62
90
  };
63
- /** How to render it. Only the browser engine reads these — with `auto` they apply if the page
91
+ /** How to render it. Only the browser engine reads these. With `auto` they apply if the page
64
92
  * turns out to need one. */
65
93
  browser?: {
66
94
  /** When the page counts as loaded. "load" (the default) waits for images and stylesheets;
@@ -68,9 +96,9 @@ export interface ScrapeParams {
68
96
  * page stops asking for things. Every page gets a short settle after this whichever you
69
97
  * pick. */
70
98
  waitUntil?: "load" | "domcontentloaded" | "networkidle";
71
- /** Wait until this CSS selector is on the page — the dependable way to read something a
72
- * script draws. If it never shows up the call comes back as a timeout at no charge, rather
73
- * than the half-built page. */
99
+ /** Wait until this CSS selector is on the page. It is the dependable way to read something
100
+ * a script draws. If it never shows up, the call comes back as a timeout at no charge,
101
+ * rather than the half-built page. */
74
102
  waitForSelector?: string;
75
103
  /** Wait this many milliseconds after the page settles, for the scripts no selector
76
104
  * describes. It comes out of `timeoutMs`, never on top of it. */
@@ -82,11 +110,11 @@ export interface ScrapeParams {
82
110
  height: number;
83
111
  };
84
112
  /** Screenshot the whole scrollable page instead of just the window. A long page makes a
85
- * large answer — the image comes back as base64 inside the response. */
113
+ * large answer: the image comes back as base64 inside the response. */
86
114
  fullPage?: boolean;
87
115
  };
88
- /** Extra request headers to send to the page — an authorization token, a cookie, a custom user
89
- * agent. The connection's own headers cannot be set. */
116
+ /** Extra request headers to send to the page, such as an authorization token, a cookie or a
117
+ * custom user agent. The connection's own headers cannot be set. */
90
118
  headers?: Record<string, string>;
91
119
  /** How long to give the page before giving up, in milliseconds. A page that never arrives is a
92
120
  * free outcome. */
@@ -94,36 +122,64 @@ export interface ScrapeParams {
94
122
  }
95
123
  /** Arguments for `quote()`. */
96
124
  export interface QuoteScrapeParams {
97
- /** The page to read. An http(s) URL — private and loopback hosts are refused. */
125
+ /** The page to read. An http(s) URL. Private and loopback hosts are refused. */
98
126
  url: string;
99
127
  /** How to read it. "fetch" is a plain HTTP request; "browser" renders the page in a real
100
- * Chromium; "auto" fetches first and escalates to the browser when the body turns out to be a
101
- * JavaScript shell, billing whichever engine answered. */
128
+ * Chromium; "auto" (the default) fetches first and escalates to the browser when the body
129
+ * turns out to be a JavaScript shell, billing whichever engine answered. A POST and "raw"
130
+ * always use "fetch", so leave it out for them. */
102
131
  engine?: "auto" | "fetch" | "browser";
103
- /** Whether to try again a different way when the first attempt is blocked. `false` stops after
104
- * one try — the site's refusal is your answer, and it costs nothing. It is how you bound a
105
- * call: with `auto`, trying again is what charges the browser price instead of the fetch one. */
132
+ /** Whether to try again a different way when the first attempt is blocked. On by default.
133
+ * `false` stops after one try. The site's refusal is your answer, and it costs nothing. It is
134
+ * how you bound a call: with `auto`, trying again is what charges the browser price instead of
135
+ * the fetch one. A POST is sent once, so it is off for a POST. */
106
136
  escalate?: boolean;
137
+ /** The HTTP method. "POST" sends `body` to the URL, for a search form or a JSON query. It is
138
+ * sent once: never retried and never sent again another way, because sending it twice could
139
+ * repeat what it did. */
140
+ method?: "GET" | "POST";
141
+ /** What a POST sends, at most 64 KB. Set its type in `headers`: `{"content-type":
142
+ * "application/json"}` for JSON, or `application/x-www-form-urlencoded` for a form. If the
143
+ * site redirects, a 301, 302 or 303 reads the next page with GET and without the body; a 307
144
+ * or 308 sends it again only if the protocol, host and port stay the same, and otherwise stops
145
+ * and names the new address. */
146
+ body?: string;
107
147
  /** How many extra tries to give a page the site blocks, each from a different address. 0 (the
108
148
  * default) takes the site's first no as the answer. A blocked page costs nothing, so a try
109
- * that is blocked again is free — but it takes as long as the first one did, so the call can
149
+ * that is blocked again is free, but it takes as long as the first one did, so the call can
110
150
  * run that many times longer. */
111
151
  retry?: number;
112
152
  /** What to hand back. "screenshot" and "pdf" come back as base64 and need the browser engine;
113
153
  * asking for both costs no more than one. "extract" is the page read into fields by a model,
114
- * and needs an `extract` block saying which ones. */
115
- formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract")[];
154
+ * and needs an `extract` block saying which ones. A link to a PDF or a Word (.docx) file is
155
+ * read into text, so the text formats work on it too. We read files up to 25 MB and the first
156
+ * 200 pages, at the fetch price. "raw" is the file exactly as the site sent it, as base64 with
157
+ * its content type: a PDF report, an image, a spreadsheet. It uses the fetch engine and holds
158
+ * up to 5 MB; a larger file answers FILE_TOO_LARGE at no charge, never cut short. */
159
+ formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract" | "raw")[];
160
+ /** Read only the page's main content into `markdown`, `text` and `extract`: the article or the
161
+ * product, without the menus, ads and related links around it. On by default. Set `false` for
162
+ * the whole page. When the main content is under 50 words, you get the whole page instead.
163
+ * `html` and `links` always hold the whole page. */
164
+ onlyMainContent?: boolean;
165
+ /** CSS selectors for the parts of the page to keep, such as `["h1", ".price"]`. `markdown`,
166
+ * `text` and `extract` then hold only what they match, in page order, and `onlyMainContent` no
167
+ * longer applies. Hidden parts are never kept. Up to 20 selectors, 256 characters each. */
168
+ includeTags?: string[];
169
+ /** CSS selectors for the parts of the page to leave out of `markdown`, `text` and `extract`,
170
+ * such as `[".comments", "#newsletter"]`. Up to 20 selectors, 256 characters each. */
171
+ excludeTags?: string[];
116
172
  /** What the page should answer with. Set `"json"` when you are reading an API: anything else
117
- * that comes back — a maintenance notice, a "checking your browser" page, a login form — is
118
- * then not your answer. It costs nothing, and we try again from another address instead of
119
- * handing you a page you cannot parse. Without it, whatever the page returns is your answer. */
173
+ * that comes back (a maintenance notice, a "checking your browser" page, a login form) is then
174
+ * not your answer. It costs nothing, and we try again from another address instead of handing
175
+ * you a page you cannot parse. Without it, whatever the page returns is your answer. */
120
176
  expect?: "json";
121
177
  /** What to pull out of the page, for the "extract" format. A model reads the page and fills in
122
- * the shape you asked for — give it a JSON Schema, a sentence, or both. It reads what the page
178
+ * the shape you asked for. Give it a JSON Schema, a sentence, or both. It reads what the page
123
179
  * says; it does not do arithmetic over it, so ask for the numbers and add them up in your own
124
180
  * code. */
125
181
  extract?: {
126
- /** The shape you want back, as JSON Schema — an object whose properties are the fields you
182
+ /** The shape you want back, as JSON Schema: an object whose properties are the fields you
127
183
  * need. A field the page does not mention comes back null; nothing is invented to fill it. */
128
184
  schema?: Record<string, unknown>;
129
185
  /** What to pull out, in your own words: `the price, the author and the date it was
@@ -134,7 +190,7 @@ export interface QuoteScrapeParams {
134
190
  /** Where the request leaves from. Defaults to the managed residential pool. */
135
191
  proxy?: {
136
192
  /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
137
- * "custom" is your own proxy — free on every plan, bytes never billed. */
193
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
138
194
  pool?: "residential" | "custom";
139
195
  /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
140
196
  * for the managed one. */
@@ -154,7 +210,7 @@ export interface QuoteScrapeParams {
154
210
  * charge; ask for the state or the country alone. */
155
211
  city?: string;
156
212
  };
157
- /** How to render it. Only the browser engine reads these — with `auto` they apply if the page
213
+ /** How to render it. Only the browser engine reads these. With `auto` they apply if the page
158
214
  * turns out to need one. */
159
215
  browser?: {
160
216
  /** When the page counts as loaded. "load" (the default) waits for images and stylesheets;
@@ -162,9 +218,9 @@ export interface QuoteScrapeParams {
162
218
  * page stops asking for things. Every page gets a short settle after this whichever you
163
219
  * pick. */
164
220
  waitUntil?: "load" | "domcontentloaded" | "networkidle";
165
- /** Wait until this CSS selector is on the page — the dependable way to read something a
166
- * script draws. If it never shows up the call comes back as a timeout at no charge, rather
167
- * than the half-built page. */
221
+ /** Wait until this CSS selector is on the page. It is the dependable way to read something
222
+ * a script draws. If it never shows up, the call comes back as a timeout at no charge,
223
+ * rather than the half-built page. */
168
224
  waitForSelector?: string;
169
225
  /** Wait this many milliseconds after the page settles, for the scripts no selector
170
226
  * describes. It comes out of `timeoutMs`, never on top of it. */
@@ -176,22 +232,82 @@ export interface QuoteScrapeParams {
176
232
  height: number;
177
233
  };
178
234
  /** Screenshot the whole scrollable page instead of just the window. A long page makes a
179
- * large answer — the image comes back as base64 inside the response. */
235
+ * large answer: the image comes back as base64 inside the response. */
180
236
  fullPage?: boolean;
181
237
  };
182
- /** Extra request headers to send to the page — an authorization token, a cookie, a custom user
183
- * agent. The connection's own headers cannot be set. */
238
+ /** Extra request headers to send to the page, such as an authorization token, a cookie or a
239
+ * custom user agent. The connection's own headers cannot be set. */
184
240
  headers?: Record<string, string>;
185
241
  /** How long to give the page before giving up, in milliseconds. A page that never arrives is a
186
242
  * free outcome. */
187
243
  timeoutMs?: number;
188
244
  }
245
+ /** Arguments for `map()`. */
246
+ export interface MapSiteParams {
247
+ /** The site to map, as any http(s) URL on it. Private and loopback hosts are refused. */
248
+ url: string;
249
+ /** How many URLs to hand back at most, 1 to 30,000. The price is the same whatever you ask for. */
250
+ limit?: number;
251
+ /** Only URLs that contain this text, upper or lower case alike: `blog` keeps `/blog/` and
252
+ * `/Blog-post`. */
253
+ search?: string;
254
+ /** Also keep URLs on other hosts of the same domain, like `blog.example.com` for `example.com`.
255
+ * Off by default: only the host you named, with or without `www.`. */
256
+ includeSubdomains?: boolean;
257
+ /** Where to look. "include" reads the site's sitemaps and the links on the page you named;
258
+ * "only" reads the sitemaps alone; "skip" reads the page's links alone. */
259
+ sitemap?: "include" | "only" | "skip";
260
+ /** Where the map's requests leave from. Every file it reads goes through the same exit. */
261
+ proxy?: {
262
+ /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
263
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
264
+ pool?: "residential" | "custom";
265
+ /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
266
+ * for the managed one. */
267
+ server?: string;
268
+ /** Where the call should look like it comes from, ISO 3166-1 alpha-2 (`us`, `br`). Name one
269
+ * and the managed pool leaves from that country. Leave it out and the page sees a US
270
+ * browser, from an address we pick. The browser's clock and languages follow the country
271
+ * on every pool. */
272
+ country?: string;
273
+ };
274
+ }
275
+ /** Arguments for `quoteMap()`. */
276
+ export interface QuoteMapParams {
277
+ /** The site to map, as any http(s) URL on it. Private and loopback hosts are refused. */
278
+ url: string;
279
+ /** How many URLs to hand back at most, 1 to 30,000. The price is the same whatever you ask for. */
280
+ limit?: number;
281
+ /** Only URLs that contain this text, upper or lower case alike: `blog` keeps `/blog/` and
282
+ * `/Blog-post`. */
283
+ search?: string;
284
+ /** Also keep URLs on other hosts of the same domain, like `blog.example.com` for `example.com`.
285
+ * Off by default: only the host you named, with or without `www.`. */
286
+ includeSubdomains?: boolean;
287
+ /** Where to look. "include" reads the site's sitemaps and the links on the page you named;
288
+ * "only" reads the sitemaps alone; "skip" reads the page's links alone. */
289
+ sitemap?: "include" | "only" | "skip";
290
+ /** Where the map's requests leave from. Every file it reads goes through the same exit. */
291
+ proxy?: {
292
+ /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
293
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
294
+ pool?: "residential" | "custom";
295
+ /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
296
+ * for the managed one. */
297
+ server?: string;
298
+ /** Where the call should look like it comes from, ISO 3166-1 alpha-2 (`us`, `br`). Name one
299
+ * and the managed pool leaves from that country. Leave it out and the page sees a US
300
+ * browser, from an address we pick. The browser's clock and languages follow the country
301
+ * on every pool. */
302
+ country?: string;
303
+ };
304
+ }
189
305
  /** Arguments for `search()`. */
190
306
  export interface SearchParams {
191
- /** What to search for, in plain words — the same thing you would type. */
307
+ /** What to search for, in plain words: the same thing you would type. */
192
308
  query: string;
193
309
  /** How many results to hand back at most, 1–20. Billed per 10, so asking for more than 10 costs
194
- * a second row. Fewer can come back than you asked for — an index has what it has, and
310
+ * a second row. Fewer can come back than you asked for: an index has what it has, and
195
311
  * `includeDomains` filters what it returns. */
196
312
  limit?: number;
197
313
  /** What kind of results. "general" is the web; "news" is dated journalism, and the only topic
@@ -199,18 +315,18 @@ export interface SearchParams {
199
315
  topic?: "general" | "news";
200
316
  /** Only pages from the last day, week, month or year. Absent is any time. */
201
317
  timeRange?: "day" | "week" | "month" | "year";
202
- /** Only results on these hosts, bare (`linkedin.com`) — subdomains included. Asked of the
318
+ /** Only results on these hosts, bare (`linkedin.com`). Subdomains are included. Asked of the
203
319
  * search front AND enforced on the answer, so what comes back is on your list whatever the
204
320
  * front did with it. */
205
321
  includeDomains?: string[];
206
322
  /** Also write a short paragraph answering the query from the results, in the query's language.
207
323
  * Costs one extra credit; leave it off when your own model reads the snippets. */
208
324
  answer?: boolean;
209
- /** Where the search leaves from. `country` picks the exit AND the market the front answers for
210
- * — `br` gets Brazilian results in Portuguese. */
325
+ /** Where the search leaves from. `country` picks the exit AND the market the front answers for.
326
+ * `br` gets Brazilian results in Portuguese. */
211
327
  proxy?: {
212
328
  /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
213
- * "custom" is your own proxy — free on every plan, bytes never billed. */
329
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
214
330
  pool?: "residential" | "custom";
215
331
  /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
216
332
  * for the managed one. */
@@ -225,33 +341,51 @@ export interface SearchParams {
225
341
  /** Arguments for `batches.create()`. */
226
342
  export interface CreateBatchParams {
227
343
  /** How to read it. "fetch" is a plain HTTP request; "browser" renders the page in a real
228
- * Chromium; "auto" fetches first and escalates to the browser when the body turns out to be a
229
- * JavaScript shell, billing whichever engine answered. */
344
+ * Chromium; "auto" (the default) fetches first and escalates to the browser when the body
345
+ * turns out to be a JavaScript shell, billing whichever engine answered. A POST and "raw"
346
+ * always use "fetch", so leave it out for them. */
230
347
  engine?: "auto" | "fetch" | "browser";
231
- /** Whether to try again a different way when the first attempt is blocked. `false` stops after
232
- * one try — the site's refusal is your answer, and it costs nothing. It is how you bound a
233
- * call: with `auto`, trying again is what charges the browser price instead of the fetch one. */
348
+ /** Whether to try again a different way when the first attempt is blocked. On by default.
349
+ * `false` stops after one try. The site's refusal is your answer, and it costs nothing. It is
350
+ * how you bound a call: with `auto`, trying again is what charges the browser price instead of
351
+ * the fetch one. A POST is sent once, so it is off for a POST. */
234
352
  escalate?: boolean;
235
353
  /** How many extra tries to give a page the site blocks, each from a different address. 0 (the
236
354
  * default) takes the site's first no as the answer. A blocked page costs nothing, so a try
237
- * that is blocked again is free — but it takes as long as the first one did, so the call can
355
+ * that is blocked again is free, but it takes as long as the first one did, so the call can
238
356
  * run that many times longer. */
239
357
  retry?: number;
240
358
  /** What to hand back. "screenshot" and "pdf" come back as base64 and need the browser engine;
241
359
  * asking for both costs no more than one. "extract" is the page read into fields by a model,
242
- * and needs an `extract` block saying which ones. */
243
- formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract")[];
360
+ * and needs an `extract` block saying which ones. A link to a PDF or a Word (.docx) file is
361
+ * read into text, so the text formats work on it too. We read files up to 25 MB and the first
362
+ * 200 pages, at the fetch price. "raw" is the file exactly as the site sent it, as base64 with
363
+ * its content type: a PDF report, an image, a spreadsheet. It uses the fetch engine and holds
364
+ * up to 5 MB; a larger file answers FILE_TOO_LARGE at no charge, never cut short. */
365
+ formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract" | "raw")[];
366
+ /** Read only the page's main content into `markdown`, `text` and `extract`: the article or the
367
+ * product, without the menus, ads and related links around it. On by default. Set `false` for
368
+ * the whole page. When the main content is under 50 words, you get the whole page instead.
369
+ * `html` and `links` always hold the whole page. */
370
+ onlyMainContent?: boolean;
371
+ /** CSS selectors for the parts of the page to keep, such as `["h1", ".price"]`. `markdown`,
372
+ * `text` and `extract` then hold only what they match, in page order, and `onlyMainContent` no
373
+ * longer applies. Hidden parts are never kept. Up to 20 selectors, 256 characters each. */
374
+ includeTags?: string[];
375
+ /** CSS selectors for the parts of the page to leave out of `markdown`, `text` and `extract`,
376
+ * such as `[".comments", "#newsletter"]`. Up to 20 selectors, 256 characters each. */
377
+ excludeTags?: string[];
244
378
  /** What the page should answer with. Set `"json"` when you are reading an API: anything else
245
- * that comes back — a maintenance notice, a "checking your browser" page, a login form — is
246
- * then not your answer. It costs nothing, and we try again from another address instead of
247
- * handing you a page you cannot parse. Without it, whatever the page returns is your answer. */
379
+ * that comes back (a maintenance notice, a "checking your browser" page, a login form) is then
380
+ * not your answer. It costs nothing, and we try again from another address instead of handing
381
+ * you a page you cannot parse. Without it, whatever the page returns is your answer. */
248
382
  expect?: "json";
249
383
  /** What to pull out of the page, for the "extract" format. A model reads the page and fills in
250
- * the shape you asked for — give it a JSON Schema, a sentence, or both. It reads what the page
384
+ * the shape you asked for. Give it a JSON Schema, a sentence, or both. It reads what the page
251
385
  * says; it does not do arithmetic over it, so ask for the numbers and add them up in your own
252
386
  * code. */
253
387
  extract?: {
254
- /** The shape you want back, as JSON Schema — an object whose properties are the fields you
388
+ /** The shape you want back, as JSON Schema: an object whose properties are the fields you
255
389
  * need. A field the page does not mention comes back null; nothing is invented to fill it. */
256
390
  schema?: Record<string, unknown>;
257
391
  /** What to pull out, in your own words: `the price, the author and the date it was
@@ -262,7 +396,7 @@ export interface CreateBatchParams {
262
396
  /** Where the request leaves from. Defaults to the managed residential pool. */
263
397
  proxy?: {
264
398
  /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
265
- * "custom" is your own proxy — free on every plan, bytes never billed. */
399
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
266
400
  pool?: "residential" | "custom";
267
401
  /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
268
402
  * for the managed one. */
@@ -282,7 +416,7 @@ export interface CreateBatchParams {
282
416
  * charge; ask for the state or the country alone. */
283
417
  city?: string;
284
418
  };
285
- /** How to render it. Only the browser engine reads these — with `auto` they apply if the page
419
+ /** How to render it. Only the browser engine reads these. With `auto` they apply if the page
286
420
  * turns out to need one. */
287
421
  browser?: {
288
422
  /** When the page counts as loaded. "load" (the default) waits for images and stylesheets;
@@ -290,9 +424,9 @@ export interface CreateBatchParams {
290
424
  * page stops asking for things. Every page gets a short settle after this whichever you
291
425
  * pick. */
292
426
  waitUntil?: "load" | "domcontentloaded" | "networkidle";
293
- /** Wait until this CSS selector is on the page — the dependable way to read something a
294
- * script draws. If it never shows up the call comes back as a timeout at no charge, rather
295
- * than the half-built page. */
427
+ /** Wait until this CSS selector is on the page. It is the dependable way to read something
428
+ * a script draws. If it never shows up, the call comes back as a timeout at no charge,
429
+ * rather than the half-built page. */
296
430
  waitForSelector?: string;
297
431
  /** Wait this many milliseconds after the page settles, for the scripts no selector
298
432
  * describes. It comes out of `timeoutMs`, never on top of it. */
@@ -304,11 +438,11 @@ export interface CreateBatchParams {
304
438
  height: number;
305
439
  };
306
440
  /** Screenshot the whole scrollable page instead of just the window. A long page makes a
307
- * large answer — the image comes back as base64 inside the response. */
441
+ * large answer: the image comes back as base64 inside the response. */
308
442
  fullPage?: boolean;
309
443
  };
310
- /** Extra request headers to send to the page — an authorization token, a cookie, a custom user
311
- * agent. The connection's own headers cannot be set. */
444
+ /** Extra request headers to send to the page, such as an authorization token, a cookie or a
445
+ * custom user agent. The connection's own headers cannot be set. */
312
446
  headers?: Record<string, string>;
313
447
  /** How long to give the page before giving up, in milliseconds. A page that never arrives is a
314
448
  * free outcome. */
@@ -325,41 +459,59 @@ export interface CreateBatchParams {
325
459
  url: string;
326
460
  /** What to call about. "batch.completed" fires once: when every URL has a verdict, or when
327
461
  * we could not finish the batch. `batch.status` says which: `completed` or `failed`.
328
- * "batch.item.completed" fires per URL — one request from us per item, which is what makes
329
- * a long batch usable before it ends, so ask for it deliberately. */
462
+ * "batch.item.completed" fires per URL, with one request from us per item. That makes a
463
+ * long batch usable before it ends, so ask for it deliberately. */
330
464
  events?: ("batch.completed" | "batch.item.completed")[];
331
465
  };
332
466
  }
333
467
  /** Arguments for `batches.quote()`. */
334
468
  export interface QuoteBatchParams {
335
469
  /** How to read it. "fetch" is a plain HTTP request; "browser" renders the page in a real
336
- * Chromium; "auto" fetches first and escalates to the browser when the body turns out to be a
337
- * JavaScript shell, billing whichever engine answered. */
470
+ * Chromium; "auto" (the default) fetches first and escalates to the browser when the body
471
+ * turns out to be a JavaScript shell, billing whichever engine answered. A POST and "raw"
472
+ * always use "fetch", so leave it out for them. */
338
473
  engine?: "auto" | "fetch" | "browser";
339
- /** Whether to try again a different way when the first attempt is blocked. `false` stops after
340
- * one try — the site's refusal is your answer, and it costs nothing. It is how you bound a
341
- * call: with `auto`, trying again is what charges the browser price instead of the fetch one. */
474
+ /** Whether to try again a different way when the first attempt is blocked. On by default.
475
+ * `false` stops after one try. The site's refusal is your answer, and it costs nothing. It is
476
+ * how you bound a call: with `auto`, trying again is what charges the browser price instead of
477
+ * the fetch one. A POST is sent once, so it is off for a POST. */
342
478
  escalate?: boolean;
343
479
  /** How many extra tries to give a page the site blocks, each from a different address. 0 (the
344
480
  * default) takes the site's first no as the answer. A blocked page costs nothing, so a try
345
- * that is blocked again is free — but it takes as long as the first one did, so the call can
481
+ * that is blocked again is free, but it takes as long as the first one did, so the call can
346
482
  * run that many times longer. */
347
483
  retry?: number;
348
484
  /** What to hand back. "screenshot" and "pdf" come back as base64 and need the browser engine;
349
485
  * asking for both costs no more than one. "extract" is the page read into fields by a model,
350
- * and needs an `extract` block saying which ones. */
351
- formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract")[];
486
+ * and needs an `extract` block saying which ones. A link to a PDF or a Word (.docx) file is
487
+ * read into text, so the text formats work on it too. We read files up to 25 MB and the first
488
+ * 200 pages, at the fetch price. "raw" is the file exactly as the site sent it, as base64 with
489
+ * its content type: a PDF report, an image, a spreadsheet. It uses the fetch engine and holds
490
+ * up to 5 MB; a larger file answers FILE_TOO_LARGE at no charge, never cut short. */
491
+ formats?: ("markdown" | "html" | "text" | "links" | "screenshot" | "pdf" | "extract" | "raw")[];
492
+ /** Read only the page's main content into `markdown`, `text` and `extract`: the article or the
493
+ * product, without the menus, ads and related links around it. On by default. Set `false` for
494
+ * the whole page. When the main content is under 50 words, you get the whole page instead.
495
+ * `html` and `links` always hold the whole page. */
496
+ onlyMainContent?: boolean;
497
+ /** CSS selectors for the parts of the page to keep, such as `["h1", ".price"]`. `markdown`,
498
+ * `text` and `extract` then hold only what they match, in page order, and `onlyMainContent` no
499
+ * longer applies. Hidden parts are never kept. Up to 20 selectors, 256 characters each. */
500
+ includeTags?: string[];
501
+ /** CSS selectors for the parts of the page to leave out of `markdown`, `text` and `extract`,
502
+ * such as `[".comments", "#newsletter"]`. Up to 20 selectors, 256 characters each. */
503
+ excludeTags?: string[];
352
504
  /** What the page should answer with. Set `"json"` when you are reading an API: anything else
353
- * that comes back — a maintenance notice, a "checking your browser" page, a login form — is
354
- * then not your answer. It costs nothing, and we try again from another address instead of
355
- * handing you a page you cannot parse. Without it, whatever the page returns is your answer. */
505
+ * that comes back (a maintenance notice, a "checking your browser" page, a login form) is then
506
+ * not your answer. It costs nothing, and we try again from another address instead of handing
507
+ * you a page you cannot parse. Without it, whatever the page returns is your answer. */
356
508
  expect?: "json";
357
509
  /** What to pull out of the page, for the "extract" format. A model reads the page and fills in
358
- * the shape you asked for — give it a JSON Schema, a sentence, or both. It reads what the page
510
+ * the shape you asked for. Give it a JSON Schema, a sentence, or both. It reads what the page
359
511
  * says; it does not do arithmetic over it, so ask for the numbers and add them up in your own
360
512
  * code. */
361
513
  extract?: {
362
- /** The shape you want back, as JSON Schema — an object whose properties are the fields you
514
+ /** The shape you want back, as JSON Schema: an object whose properties are the fields you
363
515
  * need. A field the page does not mention comes back null; nothing is invented to fill it. */
364
516
  schema?: Record<string, unknown>;
365
517
  /** What to pull out, in your own words: `the price, the author and the date it was
@@ -370,7 +522,7 @@ export interface QuoteBatchParams {
370
522
  /** Where the request leaves from. Defaults to the managed residential pool. */
371
523
  proxy?: {
372
524
  /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
373
- * "custom" is your own proxy — free on every plan, bytes never billed. */
525
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
374
526
  pool?: "residential" | "custom";
375
527
  /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
376
528
  * for the managed one. */
@@ -390,7 +542,7 @@ export interface QuoteBatchParams {
390
542
  * charge; ask for the state or the country alone. */
391
543
  city?: string;
392
544
  };
393
- /** How to render it. Only the browser engine reads these — with `auto` they apply if the page
545
+ /** How to render it. Only the browser engine reads these. With `auto` they apply if the page
394
546
  * turns out to need one. */
395
547
  browser?: {
396
548
  /** When the page counts as loaded. "load" (the default) waits for images and stylesheets;
@@ -398,9 +550,9 @@ export interface QuoteBatchParams {
398
550
  * page stops asking for things. Every page gets a short settle after this whichever you
399
551
  * pick. */
400
552
  waitUntil?: "load" | "domcontentloaded" | "networkidle";
401
- /** Wait until this CSS selector is on the page — the dependable way to read something a
402
- * script draws. If it never shows up the call comes back as a timeout at no charge, rather
403
- * than the half-built page. */
553
+ /** Wait until this CSS selector is on the page. It is the dependable way to read something
554
+ * a script draws. If it never shows up, the call comes back as a timeout at no charge,
555
+ * rather than the half-built page. */
404
556
  waitForSelector?: string;
405
557
  /** Wait this many milliseconds after the page settles, for the scripts no selector
406
558
  * describes. It comes out of `timeoutMs`, never on top of it. */
@@ -412,11 +564,11 @@ export interface QuoteBatchParams {
412
564
  height: number;
413
565
  };
414
566
  /** Screenshot the whole scrollable page instead of just the window. A long page makes a
415
- * large answer — the image comes back as base64 inside the response. */
567
+ * large answer: the image comes back as base64 inside the response. */
416
568
  fullPage?: boolean;
417
569
  };
418
- /** Extra request headers to send to the page — an authorization token, a cookie, a custom user
419
- * agent. The connection's own headers cannot be set. */
570
+ /** Extra request headers to send to the page, such as an authorization token, a cookie or a
571
+ * custom user agent. The connection's own headers cannot be set. */
420
572
  headers?: Record<string, string>;
421
573
  /** How long to give the page before giving up, in milliseconds. A page that never arrives is a
422
574
  * free outcome. */
@@ -433,8 +585,8 @@ export interface QuoteBatchParams {
433
585
  url: string;
434
586
  /** What to call about. "batch.completed" fires once: when every URL has a verdict, or when
435
587
  * we could not finish the batch. `batch.status` says which: `completed` or `failed`.
436
- * "batch.item.completed" fires per URL — one request from us per item, which is what makes
437
- * a long batch usable before it ends, so ask for it deliberately. */
588
+ * "batch.item.completed" fires per URL, with one request from us per item. That makes a
589
+ * long batch usable before it ends, so ask for it deliberately. */
438
590
  events?: ("batch.completed" | "batch.item.completed")[];
439
591
  };
440
592
  }
@@ -469,7 +621,7 @@ export interface CreateSessionParams {
469
621
  * pool. */
470
622
  proxy?: {
471
623
  /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
472
- * "custom" is your own proxy — free on every plan, bytes never billed. */
624
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
473
625
  pool?: "residential" | "custom";
474
626
  /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
475
627
  * for the managed one. */
@@ -500,7 +652,7 @@ export interface QuoteSessionParams {
500
652
  * pool. */
501
653
  proxy?: {
502
654
  /** Which exit to leave through. "residential" is the managed pool, metered by the megabyte;
503
- * "custom" is your own proxy — free on every plan, bytes never billed. */
655
+ * "custom" is your own proxy, free on every plan, bytes never billed. */
504
656
  pool?: "residential" | "custom";
505
657
  /** Your own proxy, `http(s)://[user:pass@]host:port`. Required for pool "custom", refused
506
658
  * for the managed one. */