firecrawl 4.16.0 → 4.18.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/README.md CHANGED
@@ -110,6 +110,28 @@ const mapResult = await app.map('https://example.com');
110
110
  console.log(mapResult);
111
111
  ```
112
112
 
113
+ ### Scrape-bound interactive browsing (v2)
114
+
115
+ Use a scrape job ID to keep interacting with the replayed browser context:
116
+
117
+ ```js
118
+ const doc = await app.scrape('https://example.com', {
119
+ actions: [{ type: 'click', selector: 'a[href="/pricing"]' }],
120
+ });
121
+
122
+ const scrapeJobId = doc?.metadata?.scrapeId;
123
+ if (!scrapeJobId) throw new Error('Missing scrapeId');
124
+
125
+ const run = await app.interact(scrapeJobId, {
126
+ code: 'console.log(await page.url())',
127
+ language: 'node',
128
+ timeout: 60,
129
+ });
130
+ console.log(run.stdout);
131
+
132
+ await app.stopInteraction(scrapeJobId);
133
+ ```
134
+
113
135
  ### Crawl a website with real‑time updates
114
136
 
115
137
  To receive real‑time updates, start a crawl and attach a watcher.
@@ -8,7 +8,7 @@ var require_package = __commonJS({
8
8
  "package.json"(exports, module) {
9
9
  module.exports = {
10
10
  name: "@mendable/firecrawl-js",
11
- version: "4.16.0",
11
+ version: "4.18.0",
12
12
  description: "JavaScript SDK for Firecrawl API",
13
13
  main: "dist/index.js",
14
14
  types: "dist/index.d.ts",
@@ -35,7 +35,7 @@ var require_package = __commonJS({
35
35
  license: "MIT",
36
36
  dependencies: {
37
37
  axios: "^1.13.5",
38
- firecrawl: "4.15.2",
38
+ firecrawl: "4.16.0",
39
39
  "typescript-event-target": "^1.1.1",
40
40
  zod: "^3.23.8",
41
41
  "zod-to-json-schema": "^3.23.0"
package/dist/index.cjs CHANGED
@@ -35,7 +35,7 @@ var require_package = __commonJS({
35
35
  "package.json"(exports2, module2) {
36
36
  module2.exports = {
37
37
  name: "@mendable/firecrawl-js",
38
- version: "4.16.0",
38
+ version: "4.18.0",
39
39
  description: "JavaScript SDK for Firecrawl API",
40
40
  main: "dist/index.js",
41
41
  types: "dist/index.d.ts",
@@ -62,7 +62,7 @@ var require_package = __commonJS({
62
62
  license: "MIT",
63
63
  dependencies: {
64
64
  axios: "^1.13.5",
65
- firecrawl: "4.15.2",
65
+ firecrawl: "4.16.0",
66
66
  "typescript-event-target": "^1.1.1",
67
67
  zod: "^3.23.8",
68
68
  "zod-to-json-schema": "^3.23.0"
@@ -408,6 +408,48 @@ async function scrape(http, url, options) {
408
408
  throw err;
409
409
  }
410
410
  }
411
+ async function interact(http, jobId, args) {
412
+ if (!jobId || !jobId.trim()) {
413
+ throw new Error("Job ID cannot be empty");
414
+ }
415
+ const hasCode = args?.code && args.code.trim();
416
+ const hasPrompt = args?.prompt && args.prompt.trim();
417
+ if (!hasCode && !hasPrompt) {
418
+ throw new Error("Either 'code' or 'prompt' must be provided");
419
+ }
420
+ const body = {};
421
+ if (hasCode) body.code = args.code;
422
+ if (hasPrompt) body.prompt = args.prompt;
423
+ body.language = args.language ?? "node";
424
+ if (args.timeout != null) body.timeout = args.timeout;
425
+ if (args.origin) body.origin = args.origin;
426
+ try {
427
+ const res = await http.post(
428
+ `/v2/scrape/${jobId}/interact`,
429
+ body
430
+ );
431
+ if (res.status !== 200) throwForBadResponse(res, "interact with scrape browser");
432
+ return res.data;
433
+ } catch (err) {
434
+ if (err?.isAxiosError) return normalizeAxiosError(err, "interact with scrape browser");
435
+ throw err;
436
+ }
437
+ }
438
+ async function stopInteraction(http, jobId) {
439
+ if (!jobId || !jobId.trim()) {
440
+ throw new Error("Job ID cannot be empty");
441
+ }
442
+ try {
443
+ const res = await http.delete(
444
+ `/v2/scrape/${jobId}/interact`
445
+ );
446
+ if (res.status !== 200) throwForBadResponse(res, "stop interaction");
447
+ return res.data;
448
+ } catch (err) {
449
+ if (err?.isAxiosError) return normalizeAxiosError(err, "stop interaction");
450
+ throw err;
451
+ }
452
+ }
411
453
 
412
454
  // src/v2/methods/search.ts
413
455
  function prepareSearchPayload(req) {
@@ -1322,6 +1364,40 @@ var FirecrawlClient = class {
1322
1364
  async scrape(url, options) {
1323
1365
  return scrape(this.http, url, options);
1324
1366
  }
1367
+ /**
1368
+ * Interact with the browser session associated with a scrape job.
1369
+ * @param jobId Scrape job id.
1370
+ * @param args Code or prompt to execute, with language/timeout options.
1371
+ * @returns Execution result including output, stdout, stderr, exitCode, and killed status.
1372
+ */
1373
+ async interact(jobId, args) {
1374
+ return interact(this.http, jobId, args);
1375
+ }
1376
+ /**
1377
+ * Stop the interaction session associated with a scrape job.
1378
+ * @param jobId Scrape job id.
1379
+ */
1380
+ async stopInteraction(jobId) {
1381
+ return stopInteraction(this.http, jobId);
1382
+ }
1383
+ /**
1384
+ * @deprecated Use interact().
1385
+ */
1386
+ async scrapeExecute(jobId, args) {
1387
+ return this.interact(jobId, args);
1388
+ }
1389
+ /**
1390
+ * @deprecated Use stopInteraction().
1391
+ */
1392
+ async stopInteractiveBrowser(jobId) {
1393
+ return this.stopInteraction(jobId);
1394
+ }
1395
+ /**
1396
+ * @deprecated Use stopInteraction().
1397
+ */
1398
+ async deleteScrapeBrowser(jobId) {
1399
+ return this.stopInteraction(jobId);
1400
+ }
1325
1401
  // Search
1326
1402
  /**
1327
1403
  * Search the web and optionally scrape each result.
package/dist/index.d.cts CHANGED
@@ -4,7 +4,7 @@ import { AxiosResponse, AxiosRequestHeaders } from 'axios';
4
4
  import { EventEmitter } from 'events';
5
5
  import { TypedEventTarget } from 'typescript-event-target';
6
6
 
7
- type FormatString = 'markdown' | 'html' | 'rawHtml' | 'links' | 'images' | 'screenshot' | 'summary' | 'changeTracking' | 'json' | 'attributes' | 'branding';
7
+ type FormatString = 'markdown' | 'html' | 'rawHtml' | 'links' | 'images' | 'screenshot' | 'summary' | 'changeTracking' | 'json' | 'attributes' | 'branding' | 'audio';
8
8
  interface Viewport {
9
9
  width: number;
10
10
  height: number;
@@ -119,6 +119,10 @@ interface ScrapeOptions {
119
119
  maxAge?: number;
120
120
  minAge?: number;
121
121
  storeInCache?: boolean;
122
+ profile?: {
123
+ name: string;
124
+ saveChanges?: boolean;
125
+ };
122
126
  integration?: string;
123
127
  origin?: string;
124
128
  }
@@ -316,6 +320,7 @@ interface Document {
316
320
  links?: string[];
317
321
  images?: string[];
318
322
  screenshot?: string;
323
+ audio?: string;
319
324
  attributes?: Array<{
320
325
  selector: string;
321
326
  attribute: string;
@@ -578,6 +583,9 @@ interface BrowserCreateResponse {
578
583
  }
579
584
  interface BrowserExecuteResponse {
580
585
  success: boolean;
586
+ liveViewUrl?: string;
587
+ interactiveLiveViewUrl?: string;
588
+ output?: string;
581
589
  stdout?: string;
582
590
  result?: string;
583
591
  stderr?: string;
@@ -591,6 +599,15 @@ interface BrowserDeleteResponse {
591
599
  creditsBilled?: number;
592
600
  error?: string;
593
601
  }
602
+ interface ScrapeExecuteRequest {
603
+ code?: string;
604
+ prompt?: string;
605
+ language?: "python" | "node" | "bash";
606
+ timeout?: number;
607
+ origin?: string;
608
+ }
609
+ type ScrapeExecuteResponse = BrowserExecuteResponse;
610
+ type ScrapeBrowserDeleteResponse = BrowserDeleteResponse;
594
611
  interface BrowserSession {
595
612
  id: string;
596
613
  status: string;
@@ -753,6 +770,30 @@ declare class FirecrawlClient {
753
770
  json?: InferredJsonFromOptions<Opts>;
754
771
  }>;
755
772
  scrape(url: string, options?: ScrapeOptions): Promise<Document>;
773
+ /**
774
+ * Interact with the browser session associated with a scrape job.
775
+ * @param jobId Scrape job id.
776
+ * @param args Code or prompt to execute, with language/timeout options.
777
+ * @returns Execution result including output, stdout, stderr, exitCode, and killed status.
778
+ */
779
+ interact(jobId: string, args: ScrapeExecuteRequest): Promise<ScrapeExecuteResponse>;
780
+ /**
781
+ * Stop the interaction session associated with a scrape job.
782
+ * @param jobId Scrape job id.
783
+ */
784
+ stopInteraction(jobId: string): Promise<ScrapeBrowserDeleteResponse>;
785
+ /**
786
+ * @deprecated Use interact().
787
+ */
788
+ scrapeExecute(jobId: string, args: ScrapeExecuteRequest): Promise<ScrapeExecuteResponse>;
789
+ /**
790
+ * @deprecated Use stopInteraction().
791
+ */
792
+ stopInteractiveBrowser(jobId: string): Promise<ScrapeBrowserDeleteResponse>;
793
+ /**
794
+ * @deprecated Use stopInteraction().
795
+ */
796
+ deleteScrapeBrowser(jobId: string): Promise<ScrapeBrowserDeleteResponse>;
756
797
  /**
757
798
  * Search the web and optionally scrape each result.
758
799
  * @param query Search query string.
@@ -1849,4 +1890,4 @@ declare class Firecrawl extends FirecrawlClient {
1849
1890
  get v1(): FirecrawlApp;
1850
1891
  }
1851
1892
 
1852
- export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentStatusResponse, type AgentWebhookConfig, type AgentWebhookEvent, type AttributesFormat, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type Document, type DocumentMetadata, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, JobTimeoutError, type JsonFormat, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type PDFAction, type PaginationConfig, type PressAction, type QueryFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ScrapeAction, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default };
1893
+ export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentStatusResponse, type AgentWebhookConfig, type AgentWebhookEvent, type AttributesFormat, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type Document, type DocumentMetadata, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, JobTimeoutError, type JsonFormat, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type PDFAction, type PaginationConfig, type PressAction, type QueryFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ScrapeAction, type ScrapeBrowserDeleteResponse, type ScrapeExecuteRequest, type ScrapeExecuteResponse, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default };
package/dist/index.d.ts CHANGED
@@ -4,7 +4,7 @@ import { AxiosResponse, AxiosRequestHeaders } from 'axios';
4
4
  import { EventEmitter } from 'events';
5
5
  import { TypedEventTarget } from 'typescript-event-target';
6
6
 
7
- type FormatString = 'markdown' | 'html' | 'rawHtml' | 'links' | 'images' | 'screenshot' | 'summary' | 'changeTracking' | 'json' | 'attributes' | 'branding';
7
+ type FormatString = 'markdown' | 'html' | 'rawHtml' | 'links' | 'images' | 'screenshot' | 'summary' | 'changeTracking' | 'json' | 'attributes' | 'branding' | 'audio';
8
8
  interface Viewport {
9
9
  width: number;
10
10
  height: number;
@@ -119,6 +119,10 @@ interface ScrapeOptions {
119
119
  maxAge?: number;
120
120
  minAge?: number;
121
121
  storeInCache?: boolean;
122
+ profile?: {
123
+ name: string;
124
+ saveChanges?: boolean;
125
+ };
122
126
  integration?: string;
123
127
  origin?: string;
124
128
  }
@@ -316,6 +320,7 @@ interface Document {
316
320
  links?: string[];
317
321
  images?: string[];
318
322
  screenshot?: string;
323
+ audio?: string;
319
324
  attributes?: Array<{
320
325
  selector: string;
321
326
  attribute: string;
@@ -578,6 +583,9 @@ interface BrowserCreateResponse {
578
583
  }
579
584
  interface BrowserExecuteResponse {
580
585
  success: boolean;
586
+ liveViewUrl?: string;
587
+ interactiveLiveViewUrl?: string;
588
+ output?: string;
581
589
  stdout?: string;
582
590
  result?: string;
583
591
  stderr?: string;
@@ -591,6 +599,15 @@ interface BrowserDeleteResponse {
591
599
  creditsBilled?: number;
592
600
  error?: string;
593
601
  }
602
+ interface ScrapeExecuteRequest {
603
+ code?: string;
604
+ prompt?: string;
605
+ language?: "python" | "node" | "bash";
606
+ timeout?: number;
607
+ origin?: string;
608
+ }
609
+ type ScrapeExecuteResponse = BrowserExecuteResponse;
610
+ type ScrapeBrowserDeleteResponse = BrowserDeleteResponse;
594
611
  interface BrowserSession {
595
612
  id: string;
596
613
  status: string;
@@ -753,6 +770,30 @@ declare class FirecrawlClient {
753
770
  json?: InferredJsonFromOptions<Opts>;
754
771
  }>;
755
772
  scrape(url: string, options?: ScrapeOptions): Promise<Document>;
773
+ /**
774
+ * Interact with the browser session associated with a scrape job.
775
+ * @param jobId Scrape job id.
776
+ * @param args Code or prompt to execute, with language/timeout options.
777
+ * @returns Execution result including output, stdout, stderr, exitCode, and killed status.
778
+ */
779
+ interact(jobId: string, args: ScrapeExecuteRequest): Promise<ScrapeExecuteResponse>;
780
+ /**
781
+ * Stop the interaction session associated with a scrape job.
782
+ * @param jobId Scrape job id.
783
+ */
784
+ stopInteraction(jobId: string): Promise<ScrapeBrowserDeleteResponse>;
785
+ /**
786
+ * @deprecated Use interact().
787
+ */
788
+ scrapeExecute(jobId: string, args: ScrapeExecuteRequest): Promise<ScrapeExecuteResponse>;
789
+ /**
790
+ * @deprecated Use stopInteraction().
791
+ */
792
+ stopInteractiveBrowser(jobId: string): Promise<ScrapeBrowserDeleteResponse>;
793
+ /**
794
+ * @deprecated Use stopInteraction().
795
+ */
796
+ deleteScrapeBrowser(jobId: string): Promise<ScrapeBrowserDeleteResponse>;
756
797
  /**
757
798
  * Search the web and optionally scrape each result.
758
799
  * @param query Search query string.
@@ -1849,4 +1890,4 @@ declare class Firecrawl extends FirecrawlClient {
1849
1890
  get v1(): FirecrawlApp;
1850
1891
  }
1851
1892
 
1852
- export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentStatusResponse, type AgentWebhookConfig, type AgentWebhookEvent, type AttributesFormat, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type Document, type DocumentMetadata, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, JobTimeoutError, type JsonFormat, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type PDFAction, type PaginationConfig, type PressAction, type QueryFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ScrapeAction, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default };
1893
+ export { type ActionOption, type ActiveCrawl, type ActiveCrawlsResponse, type AgentOptions$1 as AgentOptions, type AgentResponse, type AgentStatusResponse, type AgentWebhookConfig, type AgentWebhookEvent, type AttributesFormat, type BatchScrapeJob, type BatchScrapeOptions, type BatchScrapeResponse$1 as BatchScrapeResponse, type BrandingProfile, type BrowserCreateResponse, type BrowserDeleteResponse, type BrowserExecuteResponse, type BrowserListResponse, type BrowserSession, type CategoryOption, type ChangeTrackingFormat, type ClickAction, type ConcurrencyCheck, type CrawlErrorsResponse$1 as CrawlErrorsResponse, type CrawlJob, type CrawlOptions, type CrawlResponse$1 as CrawlResponse, type CreditUsage, type CreditUsageHistoricalPeriod, type CreditUsageHistoricalResponse, type Document, type DocumentMetadata, type ErrorDetails, type ExecuteJavascriptAction, type ExtractResponse$1 as ExtractResponse, Firecrawl, FirecrawlApp as FirecrawlAppV1, FirecrawlClient, type FirecrawlClientOptions, type Format, type FormatOption, type FormatString, JobTimeoutError, type JsonFormat, type LocationConfig$1 as LocationConfig, type MapData, type MapOptions, type PDFAction, type PaginationConfig, type PressAction, type QueryFormat, type QueueStatusResponse$1 as QueueStatusResponse, type ScrapeAction, type ScrapeBrowserDeleteResponse, type ScrapeExecuteRequest, type ScrapeExecuteResponse, type ScrapeOptions, type ScreenshotAction, type ScreenshotFormat, type ScrollAction, SdkError, type SearchData, type SearchRequest, type SearchResultImages, type SearchResultNews, type SearchResultWeb, type TokenUsage, type TokenUsageHistoricalPeriod, type TokenUsageHistoricalResponse, type Viewport, type WaitAction, Watcher, type WatcherOptions, type WebhookConfig, type WriteAction, Firecrawl as default };
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  require_package
3
- } from "./chunk-OM7BT4QE.js";
3
+ } from "./chunk-XGTDFUXH.js";
4
4
 
5
5
  // src/v2/utils/httpClient.ts
6
6
  import axios from "axios";
@@ -289,6 +289,48 @@ async function scrape(http, url, options) {
289
289
  throw err;
290
290
  }
291
291
  }
292
+ async function interact(http, jobId, args) {
293
+ if (!jobId || !jobId.trim()) {
294
+ throw new Error("Job ID cannot be empty");
295
+ }
296
+ const hasCode = args?.code && args.code.trim();
297
+ const hasPrompt = args?.prompt && args.prompt.trim();
298
+ if (!hasCode && !hasPrompt) {
299
+ throw new Error("Either 'code' or 'prompt' must be provided");
300
+ }
301
+ const body = {};
302
+ if (hasCode) body.code = args.code;
303
+ if (hasPrompt) body.prompt = args.prompt;
304
+ body.language = args.language ?? "node";
305
+ if (args.timeout != null) body.timeout = args.timeout;
306
+ if (args.origin) body.origin = args.origin;
307
+ try {
308
+ const res = await http.post(
309
+ `/v2/scrape/${jobId}/interact`,
310
+ body
311
+ );
312
+ if (res.status !== 200) throwForBadResponse(res, "interact with scrape browser");
313
+ return res.data;
314
+ } catch (err) {
315
+ if (err?.isAxiosError) return normalizeAxiosError(err, "interact with scrape browser");
316
+ throw err;
317
+ }
318
+ }
319
+ async function stopInteraction(http, jobId) {
320
+ if (!jobId || !jobId.trim()) {
321
+ throw new Error("Job ID cannot be empty");
322
+ }
323
+ try {
324
+ const res = await http.delete(
325
+ `/v2/scrape/${jobId}/interact`
326
+ );
327
+ if (res.status !== 200) throwForBadResponse(res, "stop interaction");
328
+ return res.data;
329
+ } catch (err) {
330
+ if (err?.isAxiosError) return normalizeAxiosError(err, "stop interaction");
331
+ throw err;
332
+ }
333
+ }
292
334
 
293
335
  // src/v2/methods/search.ts
294
336
  function prepareSearchPayload(req) {
@@ -1203,6 +1245,40 @@ var FirecrawlClient = class {
1203
1245
  async scrape(url, options) {
1204
1246
  return scrape(this.http, url, options);
1205
1247
  }
1248
+ /**
1249
+ * Interact with the browser session associated with a scrape job.
1250
+ * @param jobId Scrape job id.
1251
+ * @param args Code or prompt to execute, with language/timeout options.
1252
+ * @returns Execution result including output, stdout, stderr, exitCode, and killed status.
1253
+ */
1254
+ async interact(jobId, args) {
1255
+ return interact(this.http, jobId, args);
1256
+ }
1257
+ /**
1258
+ * Stop the interaction session associated with a scrape job.
1259
+ * @param jobId Scrape job id.
1260
+ */
1261
+ async stopInteraction(jobId) {
1262
+ return stopInteraction(this.http, jobId);
1263
+ }
1264
+ /**
1265
+ * @deprecated Use interact().
1266
+ */
1267
+ async scrapeExecute(jobId, args) {
1268
+ return this.interact(jobId, args);
1269
+ }
1270
+ /**
1271
+ * @deprecated Use stopInteraction().
1272
+ */
1273
+ async stopInteractiveBrowser(jobId) {
1274
+ return this.stopInteraction(jobId);
1275
+ }
1276
+ /**
1277
+ * @deprecated Use stopInteraction().
1278
+ */
1279
+ async deleteScrapeBrowser(jobId) {
1280
+ return this.stopInteraction(jobId);
1281
+ }
1206
1282
  // Search
1207
1283
  /**
1208
1284
  * Search the web and optionally scrape each result.
@@ -1483,7 +1559,7 @@ var FirecrawlApp = class {
1483
1559
  if (typeof process !== "undefined" && process.env && process.env.npm_package_version) {
1484
1560
  return process.env.npm_package_version;
1485
1561
  }
1486
- const packageJson = await import("./package-KOMYCNXX.js");
1562
+ const packageJson = await import("./package-ELVD4RJL.js");
1487
1563
  return packageJson.default.version;
1488
1564
  } catch (error) {
1489
1565
  const isTest = typeof process !== "undefined" && (process.env.JEST_WORKER_ID != null || false);
@@ -1,4 +1,4 @@
1
1
  import {
2
2
  require_package
3
- } from "./chunk-OM7BT4QE.js";
3
+ } from "./chunk-XGTDFUXH.js";
4
4
  export default require_package();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "firecrawl",
3
- "version": "4.16.0",
3
+ "version": "4.18.0",
4
4
  "description": "JavaScript SDK for Firecrawl API",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -0,0 +1,104 @@
1
+ import { describe, test, expect, jest } from "@jest/globals";
2
+ import { interact, stopInteraction } from "../../../v2/methods/scrape";
3
+ import { SdkError } from "../../../v2/types";
4
+
5
+ describe("JS SDK v2 scrape-browser methods", () => {
6
+ test("interact posts to scrape interact endpoint", async () => {
7
+ const post = jest.fn(async () => ({
8
+ status: 200,
9
+ data: {
10
+ success: true,
11
+ stdout: "ok",
12
+ exitCode: 0,
13
+ },
14
+ }));
15
+
16
+ const http = { post } as any;
17
+ const response = await interact(http, "job-123", { code: "console.log('ok')" });
18
+
19
+ expect(post).toHaveBeenCalledWith("/v2/scrape/job-123/interact", {
20
+ code: "console.log('ok')",
21
+ language: "node",
22
+ });
23
+ expect(response.success).toBe(true);
24
+ expect(response.exitCode).toBe(0);
25
+ });
26
+
27
+ test("interact with prompt posts prompt to endpoint", async () => {
28
+ const post = jest.fn(async () => ({
29
+ status: 200,
30
+ data: {
31
+ success: true,
32
+ output: "Clicked the button",
33
+ liveViewUrl: "https://live.example.com/view",
34
+ interactiveLiveViewUrl: "https://live.example.com/interactive",
35
+ stdout: "",
36
+ exitCode: 0,
37
+ },
38
+ }));
39
+
40
+ const http = { post } as any;
41
+ const response = await interact(http, "job-456", { prompt: "Click the login button" });
42
+
43
+ expect(post).toHaveBeenCalledWith("/v2/scrape/job-456/interact", {
44
+ prompt: "Click the login button",
45
+ language: "node",
46
+ });
47
+ expect(response.success).toBe(true);
48
+ expect(response.output).toBe("Clicked the button");
49
+ expect(response.liveViewUrl).toBe("https://live.example.com/view");
50
+ expect(response.interactiveLiveViewUrl).toBe("https://live.example.com/interactive");
51
+ });
52
+
53
+ test("interact throws when neither code nor prompt provided", async () => {
54
+ const http = { post: jest.fn() } as any;
55
+ await expect(interact(http, "job-123", {})).rejects.toThrow(
56
+ "Either 'code' or 'prompt' must be provided"
57
+ );
58
+ });
59
+
60
+ test("interact throws on non-200 response", async () => {
61
+ const post = jest.fn(async () => ({
62
+ status: 400,
63
+ data: {
64
+ success: false,
65
+ error: "Invalid job ID format",
66
+ },
67
+ }));
68
+
69
+ const http = { post } as any;
70
+ await expect(
71
+ interact(http, "bad-id", { code: "console.log('ok')" })
72
+ ).rejects.toBeInstanceOf(SdkError);
73
+ });
74
+
75
+ test("stopInteraction calls delete endpoint", async () => {
76
+ const del = jest.fn(async () => ({
77
+ status: 200,
78
+ data: {
79
+ success: true,
80
+ },
81
+ }));
82
+
83
+ const http = { delete: del } as any;
84
+ const response = await stopInteraction(http, "job-123");
85
+
86
+ expect(del).toHaveBeenCalledWith("/v2/scrape/job-123/interact");
87
+ expect(response.success).toBe(true);
88
+ });
89
+
90
+ test("stopInteraction throws on non-200 response", async () => {
91
+ const del = jest.fn(async () => ({
92
+ status: 404,
93
+ data: {
94
+ success: false,
95
+ error: "Browser session not found.",
96
+ },
97
+ }));
98
+
99
+ const http = { delete: del } as any;
100
+ await expect(stopInteraction(http, "job-123")).rejects.toBeInstanceOf(
101
+ SdkError
102
+ );
103
+ });
104
+ });
package/src/v2/client.ts CHANGED
@@ -1,5 +1,9 @@
1
1
  import { HttpClient } from "./utils/httpClient";
2
- import { scrape } from "./methods/scrape";
2
+ import {
3
+ scrape,
4
+ interact as interactMethod,
5
+ stopInteraction as stopInteractionMethod,
6
+ } from "./methods/scrape";
3
7
  import { search } from "./methods/search";
4
8
  import { map as mapMethod } from "./methods/map";
5
9
  import {
@@ -50,6 +54,9 @@ import type {
50
54
  BrowserExecuteResponse,
51
55
  BrowserDeleteResponse,
52
56
  BrowserListResponse,
57
+ ScrapeExecuteRequest,
58
+ ScrapeExecuteResponse,
59
+ ScrapeBrowserDeleteResponse,
53
60
  } from "./types";
54
61
  import { Watcher } from "./watcher";
55
62
  import type { WatcherOptions } from "./watcher";
@@ -129,6 +136,46 @@ export class FirecrawlClient {
129
136
  async scrape(url: string, options?: ScrapeOptions): Promise<Document> {
130
137
  return scrape(this.http, url, options);
131
138
  }
139
+ /**
140
+ * Interact with the browser session associated with a scrape job.
141
+ * @param jobId Scrape job id.
142
+ * @param args Code or prompt to execute, with language/timeout options.
143
+ * @returns Execution result including output, stdout, stderr, exitCode, and killed status.
144
+ */
145
+ async interact(
146
+ jobId: string,
147
+ args: ScrapeExecuteRequest
148
+ ): Promise<ScrapeExecuteResponse> {
149
+ return interactMethod(this.http, jobId, args);
150
+ }
151
+ /**
152
+ * Stop the interaction session associated with a scrape job.
153
+ * @param jobId Scrape job id.
154
+ */
155
+ async stopInteraction(jobId: string): Promise<ScrapeBrowserDeleteResponse> {
156
+ return stopInteractionMethod(this.http, jobId);
157
+ }
158
+ /**
159
+ * @deprecated Use interact().
160
+ */
161
+ async scrapeExecute(
162
+ jobId: string,
163
+ args: ScrapeExecuteRequest
164
+ ): Promise<ScrapeExecuteResponse> {
165
+ return this.interact(jobId, args);
166
+ }
167
+ /**
168
+ * @deprecated Use stopInteraction().
169
+ */
170
+ async stopInteractiveBrowser(jobId: string): Promise<ScrapeBrowserDeleteResponse> {
171
+ return this.stopInteraction(jobId);
172
+ }
173
+ /**
174
+ * @deprecated Use stopInteraction().
175
+ */
176
+ async deleteScrapeBrowser(jobId: string): Promise<ScrapeBrowserDeleteResponse> {
177
+ return this.stopInteraction(jobId);
178
+ }
132
179
 
133
180
  // Search
134
181
  /**
@@ -1,4 +1,10 @@
1
- import { type Document, type ScrapeOptions } from "../types";
1
+ import {
2
+ type Document,
3
+ type ScrapeBrowserDeleteResponse,
4
+ type ScrapeExecuteRequest,
5
+ type ScrapeExecuteResponse,
6
+ type ScrapeOptions,
7
+ } from "../types";
2
8
  import { HttpClient } from "../utils/httpClient";
3
9
  import { ensureValidScrapeOptions } from "../utils/validation";
4
10
  import { throwForBadResponse, normalizeAxiosError } from "../utils/errorHandler";
@@ -24,3 +30,82 @@ export async function scrape(http: HttpClient, url: string, options?: ScrapeOpti
24
30
  }
25
31
  }
26
32
 
33
+ export async function interact(
34
+ http: HttpClient,
35
+ jobId: string,
36
+ args: ScrapeExecuteRequest
37
+ ): Promise<ScrapeExecuteResponse> {
38
+ if (!jobId || !jobId.trim()) {
39
+ throw new Error("Job ID cannot be empty");
40
+ }
41
+ const hasCode = args?.code && args.code.trim();
42
+ const hasPrompt = args?.prompt && args.prompt.trim();
43
+ if (!hasCode && !hasPrompt) {
44
+ throw new Error("Either 'code' or 'prompt' must be provided");
45
+ }
46
+
47
+ const body: Record<string, unknown> = {};
48
+ if (hasCode) body.code = args.code;
49
+ if (hasPrompt) body.prompt = args.prompt;
50
+ body.language = args.language ?? "node";
51
+ if (args.timeout != null) body.timeout = args.timeout;
52
+ if (args.origin) body.origin = args.origin;
53
+
54
+ try {
55
+ const res = await http.post<ScrapeExecuteResponse>(
56
+ `/v2/scrape/${jobId}/interact`,
57
+ body
58
+ );
59
+ if (res.status !== 200) throwForBadResponse(res, "interact with scrape browser");
60
+ return res.data;
61
+ } catch (err: any) {
62
+ if (err?.isAxiosError) return normalizeAxiosError(err, "interact with scrape browser");
63
+ throw err;
64
+ }
65
+ }
66
+
67
+ export async function stopInteraction(
68
+ http: HttpClient,
69
+ jobId: string
70
+ ): Promise<ScrapeBrowserDeleteResponse> {
71
+ if (!jobId || !jobId.trim()) {
72
+ throw new Error("Job ID cannot be empty");
73
+ }
74
+
75
+ try {
76
+ const res = await http.delete<ScrapeBrowserDeleteResponse>(
77
+ `/v2/scrape/${jobId}/interact`
78
+ );
79
+ if (res.status !== 200) throwForBadResponse(res, "stop interaction");
80
+ return res.data;
81
+ } catch (err: any) {
82
+ if (err?.isAxiosError) return normalizeAxiosError(err, "stop interaction");
83
+ throw err;
84
+ }
85
+ }
86
+
87
+ /** @deprecated Use interact(). */
88
+ export async function scrapeExecute(
89
+ http: HttpClient,
90
+ jobId: string,
91
+ args: ScrapeExecuteRequest
92
+ ): Promise<ScrapeExecuteResponse> {
93
+ return interact(http, jobId, args);
94
+ }
95
+
96
+ /** @deprecated Use stopInteraction(). */
97
+ export async function stopInteractiveBrowser(
98
+ http: HttpClient,
99
+ jobId: string
100
+ ): Promise<ScrapeBrowserDeleteResponse> {
101
+ return stopInteraction(http, jobId);
102
+ }
103
+
104
+ /** @deprecated Use stopInteraction(). */
105
+ export async function deleteScrapeBrowser(
106
+ http: HttpClient,
107
+ jobId: string
108
+ ): Promise<ScrapeBrowserDeleteResponse> {
109
+ return stopInteraction(http, jobId);
110
+ }
111
+
package/src/v2/types.ts CHANGED
@@ -12,7 +12,8 @@ export type FormatString =
12
12
  | 'changeTracking'
13
13
  | 'json'
14
14
  | 'attributes'
15
- | 'branding';
15
+ | 'branding'
16
+ | 'audio';
16
17
 
17
18
  export interface Viewport {
18
19
  width: number;
@@ -163,6 +164,10 @@ export interface ScrapeOptions {
163
164
  maxAge?: number;
164
165
  minAge?: number;
165
166
  storeInCache?: boolean;
167
+ profile?: {
168
+ name: string;
169
+ saveChanges?: boolean;
170
+ };
166
171
  integration?: string;
167
172
  origin?: string;
168
173
  }
@@ -388,6 +393,7 @@ export interface Document {
388
393
  links?: string[];
389
394
  images?: string[];
390
395
  screenshot?: string;
396
+ audio?: string;
391
397
  attributes?: Array<{
392
398
  selector: string;
393
399
  attribute: string;
@@ -711,6 +717,9 @@ export interface BrowserCreateResponse {
711
717
 
712
718
  export interface BrowserExecuteResponse {
713
719
  success: boolean;
720
+ liveViewUrl?: string;
721
+ interactiveLiveViewUrl?: string;
722
+ output?: string;
714
723
  stdout?: string;
715
724
  result?: string;
716
725
  stderr?: string;
@@ -726,6 +735,17 @@ export interface BrowserDeleteResponse {
726
735
  error?: string;
727
736
  }
728
737
 
738
+ export interface ScrapeExecuteRequest {
739
+ code?: string;
740
+ prompt?: string;
741
+ language?: "python" | "node" | "bash";
742
+ timeout?: number;
743
+ origin?: string;
744
+ }
745
+
746
+ export type ScrapeExecuteResponse = BrowserExecuteResponse;
747
+ export type ScrapeBrowserDeleteResponse = BrowserDeleteResponse;
748
+
729
749
  export interface BrowserSession {
730
750
  id: string;
731
751
  status: string;