@mendable/n8n-nodes-firecrawl 1.0.5 → 1.2.1

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.
Files changed (92) hide show
  1. package/README.md +122 -7
  2. package/dist/nodes/Firecrawl/Firecrawl.node.js +2 -1
  3. package/dist/nodes/Firecrawl/Firecrawl.node.js.map +1 -1
  4. package/dist/nodes/Firecrawl/api/{form → agent}/index.d.ts +2 -3
  5. package/dist/nodes/Firecrawl/api/agent/index.js +364 -0
  6. package/dist/nodes/Firecrawl/api/agent/index.js.map +1 -0
  7. package/dist/nodes/Firecrawl/api/agentAsync/index.d.ts +5 -0
  8. package/dist/nodes/Firecrawl/api/agentAsync/index.js +262 -0
  9. package/dist/nodes/Firecrawl/api/agentAsync/index.js.map +1 -0
  10. package/dist/nodes/Firecrawl/api/batchScrape/index.d.ts +7 -0
  11. package/dist/nodes/Firecrawl/api/batchScrape/index.js +173 -0
  12. package/dist/nodes/Firecrawl/api/batchScrape/index.js.map +1 -0
  13. package/dist/nodes/Firecrawl/api/batchScrapeErrors/index.d.ts +6 -0
  14. package/dist/nodes/Firecrawl/api/batchScrapeErrors/index.js +40 -0
  15. package/dist/nodes/Firecrawl/api/batchScrapeErrors/index.js.map +1 -0
  16. package/dist/nodes/Firecrawl/api/batchScrapeStatus/index.d.ts +6 -0
  17. package/dist/nodes/Firecrawl/api/batchScrapeStatus/index.js +40 -0
  18. package/dist/nodes/Firecrawl/api/batchScrapeStatus/index.js.map +1 -0
  19. package/dist/nodes/Firecrawl/api/cancelBatchScrape/index.d.ts +6 -0
  20. package/dist/nodes/Firecrawl/api/cancelBatchScrape/index.js +40 -0
  21. package/dist/nodes/Firecrawl/api/cancelBatchScrape/index.js.map +1 -0
  22. package/dist/nodes/Firecrawl/api/cancelCrawl/index.d.ts +6 -0
  23. package/dist/nodes/Firecrawl/api/cancelCrawl/index.js +40 -0
  24. package/dist/nodes/Firecrawl/api/cancelCrawl/index.js.map +1 -0
  25. package/dist/nodes/Firecrawl/api/common.d.ts +8 -5
  26. package/dist/nodes/Firecrawl/api/common.js +324 -35
  27. package/dist/nodes/Firecrawl/api/common.js.map +1 -1
  28. package/dist/nodes/Firecrawl/api/crawl/index.d.ts +2 -1
  29. package/dist/nodes/Firecrawl/api/crawl/index.js +24 -23
  30. package/dist/nodes/Firecrawl/api/crawl/index.js.map +1 -1
  31. package/dist/nodes/Firecrawl/api/crawlActive/index.d.ts +6 -0
  32. package/dist/nodes/Firecrawl/api/crawlActive/index.js +20 -0
  33. package/dist/nodes/Firecrawl/api/crawlActive/index.js.map +1 -0
  34. package/dist/nodes/Firecrawl/api/crawlParamsPreview/index.d.ts +6 -0
  35. package/dist/nodes/Firecrawl/api/crawlParamsPreview/index.js +42 -0
  36. package/dist/nodes/Firecrawl/api/crawlParamsPreview/index.js.map +1 -0
  37. package/dist/nodes/Firecrawl/api/creditUsageHistorical/index.d.ts +6 -0
  38. package/dist/nodes/Firecrawl/api/creditUsageHistorical/index.js +20 -0
  39. package/dist/nodes/Firecrawl/api/creditUsageHistorical/index.js.map +1 -0
  40. package/dist/nodes/Firecrawl/api/extract/index.d.ts +1 -0
  41. package/dist/nodes/Firecrawl/api/extract/index.js +20 -19
  42. package/dist/nodes/Firecrawl/api/extract/index.js.map +1 -1
  43. package/dist/nodes/Firecrawl/api/getAgentStatus/index.d.ts +5 -0
  44. package/dist/nodes/Firecrawl/api/getAgentStatus/index.js +52 -0
  45. package/dist/nodes/Firecrawl/api/getAgentStatus/index.js.map +1 -0
  46. package/dist/nodes/Firecrawl/api/getCrawlErrors/index.d.ts +6 -0
  47. package/dist/nodes/Firecrawl/api/getCrawlErrors/index.js +40 -0
  48. package/dist/nodes/Firecrawl/api/getCrawlErrors/index.js.map +1 -0
  49. package/dist/nodes/Firecrawl/api/getCrawlStatus/index.d.ts +1 -0
  50. package/dist/nodes/Firecrawl/api/getCrawlStatus/index.js +4 -3
  51. package/dist/nodes/Firecrawl/api/getCrawlStatus/index.js.map +1 -1
  52. package/dist/nodes/Firecrawl/api/getExtractStatus/index.d.ts +1 -0
  53. package/dist/nodes/Firecrawl/api/getExtractStatus/index.js +4 -3
  54. package/dist/nodes/Firecrawl/api/getExtractStatus/index.js.map +1 -1
  55. package/dist/nodes/Firecrawl/api/index.d.ts +62 -4
  56. package/dist/nodes/Firecrawl/api/index.js +241 -20
  57. package/dist/nodes/Firecrawl/api/index.js.map +1 -1
  58. package/dist/nodes/Firecrawl/api/map/index.d.ts +2 -1
  59. package/dist/nodes/Firecrawl/api/map/index.js +15 -14
  60. package/dist/nodes/Firecrawl/api/map/index.js.map +1 -1
  61. package/dist/nodes/Firecrawl/api/scrape/index.d.ts +2 -1
  62. package/dist/nodes/Firecrawl/api/scrape/index.js +56 -7
  63. package/dist/nodes/Firecrawl/api/scrape/index.js.map +1 -1
  64. package/dist/nodes/Firecrawl/api/search/index.d.ts +2 -1
  65. package/dist/nodes/Firecrawl/api/search/index.js +13 -9
  66. package/dist/nodes/Firecrawl/api/search/index.js.map +1 -1
  67. package/dist/nodes/Firecrawl/api/teamCreditUsage/index.d.ts +6 -0
  68. package/dist/nodes/Firecrawl/api/teamCreditUsage/index.js +20 -0
  69. package/dist/nodes/Firecrawl/api/teamCreditUsage/index.js.map +1 -0
  70. package/dist/nodes/Firecrawl/api/teamQueueStatus/index.d.ts +6 -0
  71. package/dist/nodes/Firecrawl/api/teamQueueStatus/index.js +20 -0
  72. package/dist/nodes/Firecrawl/api/teamQueueStatus/index.js.map +1 -0
  73. package/dist/nodes/Firecrawl/api/teamTokenUsage/index.d.ts +6 -0
  74. package/dist/nodes/Firecrawl/api/teamTokenUsage/index.js +20 -0
  75. package/dist/nodes/Firecrawl/api/teamTokenUsage/index.js.map +1 -0
  76. package/dist/nodes/Firecrawl/api/teamTokenUsageHistorical/index.d.ts +6 -0
  77. package/dist/nodes/Firecrawl/api/teamTokenUsageHistorical/index.js +20 -0
  78. package/dist/nodes/Firecrawl/api/teamTokenUsageHistorical/index.js.map +1 -0
  79. package/dist/nodes/Firecrawl/methods.js +17 -2
  80. package/dist/nodes/Firecrawl/methods.js.map +1 -1
  81. package/dist/nodes/Firecrawl/properties.js +40 -63
  82. package/dist/nodes/Firecrawl/properties.js.map +1 -1
  83. package/dist/package.json +3 -3
  84. package/dist/tsconfig.tsbuildinfo +1 -1
  85. package/package.json +3 -3
  86. package/dist/nodes/Firecrawl/api/form/index.js +0 -163
  87. package/dist/nodes/Firecrawl/api/form/index.js.map +0 -1
  88. package/dist/nodes/Firecrawl/helpers/http/debug.d.ts +0 -2
  89. package/dist/nodes/Firecrawl/helpers/http/debug.js +0 -18
  90. package/dist/nodes/Firecrawl/helpers/http/debug.js.map +0 -1
  91. package/dist/nodes/Firecrawl/openapi.json +0 -2744
  92. package/dist/nodes/Firecrawl/v1-openapi.json +0 -1915
@@ -1,7 +1,111 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.buildApiProperties = exports.createOperationOption = exports.createScrapeOptionsProperty = exports.createExcludeTagsProperty = exports.createIncludeTagsProperty = exports.createLocationProperty = exports.createActionsProperty = exports.createUrlProperty = exports.createOperationNotice = exports.formatOperationName = void 0;
3
+ exports.buildApiProperties = exports.createOperationOption = exports.createScrapeOptionsProperty = exports.createExcludeTagsProperty = exports.createBatchUrlsProperty = exports.createIncludeTagsProperty = exports.createLocationProperty = exports.createActionsProperty = exports.createUrlProperty = exports.createOperationNotice = exports.formatOperationName = exports.convertToSchema = exports.extractUrls = void 0;
4
4
  const helpers_1 = require("../helpers");
5
+ function normalizeUrl(url) {
6
+ const trimmed = url.trim();
7
+ if (!trimmed)
8
+ return '';
9
+ if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) {
10
+ return trimmed;
11
+ }
12
+ return `https://${trimmed}`;
13
+ }
14
+ function looksLikeUrl(str) {
15
+ const trimmed = str.trim();
16
+ if (!trimmed)
17
+ return false;
18
+ if (trimmed.startsWith('http://') || trimmed.startsWith('https://')) {
19
+ return true;
20
+ }
21
+ return trimmed.includes('.') && !trimmed.includes(' ');
22
+ }
23
+ function extractUrls(val) {
24
+ if (Array.isArray(val)) {
25
+ return val.flatMap(extractUrls);
26
+ }
27
+ if (typeof val === 'string') {
28
+ const trimmed = val.trim();
29
+ if (!trimmed)
30
+ return [];
31
+ if (trimmed.startsWith('[')) {
32
+ try {
33
+ const parsed = JSON.parse(trimmed);
34
+ return extractUrls(parsed);
35
+ }
36
+ catch {
37
+ }
38
+ }
39
+ if (trimmed.includes('\n')) {
40
+ return trimmed
41
+ .split('\n')
42
+ .map((u) => u.trim())
43
+ .filter(looksLikeUrl)
44
+ .map(normalizeUrl);
45
+ }
46
+ if (trimmed.includes(',')) {
47
+ return trimmed
48
+ .split(',')
49
+ .map((u) => u.trim())
50
+ .filter(looksLikeUrl)
51
+ .map(normalizeUrl);
52
+ }
53
+ if (trimmed.includes(' http')) {
54
+ return trimmed
55
+ .split(/\s+/)
56
+ .map((u) => u.trim())
57
+ .filter(looksLikeUrl)
58
+ .map(normalizeUrl);
59
+ }
60
+ if (looksLikeUrl(trimmed)) {
61
+ return [normalizeUrl(trimmed)];
62
+ }
63
+ return [];
64
+ }
65
+ if (typeof val === 'object' && val !== null && 'url' in val) {
66
+ const urlVal = val.url;
67
+ if (typeof urlVal === 'string' && looksLikeUrl(urlVal)) {
68
+ return [normalizeUrl(urlVal)];
69
+ }
70
+ }
71
+ return [];
72
+ }
73
+ exports.extractUrls = extractUrls;
74
+ function convertToSchema(value) {
75
+ if (value === null) {
76
+ return { type: 'null' };
77
+ }
78
+ if (Array.isArray(value)) {
79
+ if (value.length === 0) {
80
+ return { type: 'array', items: {} };
81
+ }
82
+ return {
83
+ type: 'array',
84
+ items: convertToSchema(value[0]),
85
+ };
86
+ }
87
+ switch (typeof value) {
88
+ case 'string':
89
+ return { type: 'string' };
90
+ case 'number':
91
+ return Number.isInteger(value) ? { type: 'integer' } : { type: 'number' };
92
+ case 'boolean':
93
+ return { type: 'boolean' };
94
+ case 'object': {
95
+ const properties = {};
96
+ for (const [key, val] of Object.entries(value)) {
97
+ properties[key] = convertToSchema(val);
98
+ }
99
+ return {
100
+ type: 'object',
101
+ properties,
102
+ };
103
+ }
104
+ default:
105
+ return {};
106
+ }
107
+ }
108
+ exports.convertToSchema = convertToSchema;
5
109
  function formatOperationName(name) {
6
110
  return name
7
111
  .split(/(?=[A-Z])/)
@@ -29,10 +133,12 @@ function createOperationNotice(resourceName, operationName, method = 'POST') {
29
133
  exports.createOperationNotice = createOperationNotice;
30
134
  function createUrlProperty(operationName, defaultUrl = 'https://firecrawl.dev', resourceName = 'Default') {
31
135
  return {
32
- displayName: 'Url',
136
+ displayName: 'URL',
33
137
  name: 'url',
34
138
  type: 'string',
35
139
  default: defaultUrl,
140
+ required: true,
141
+ description: 'The target webpage URL to scrape or crawl. Must be a valid HTTP/HTTPS URL (e.g., https://example.com). The URL should be publicly accessible or behind authentication configured in headers.',
36
142
  routing: {
37
143
  request: {
38
144
  body: {
@@ -49,7 +155,7 @@ function createUrlProperty(operationName, defaultUrl = 'https://firecrawl.dev',
49
155
  };
50
156
  }
51
157
  exports.createUrlProperty = createUrlProperty;
52
- function createActionsProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true) {
158
+ function createActionsProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true, resourceName = 'Scraping') {
53
159
  return {
54
160
  displayName: 'Actions',
55
161
  name: 'actions',
@@ -58,8 +164,8 @@ function createActionsProperty(operationName, omitDisplayOptions = false, useNes
58
164
  typeOptions: {
59
165
  multipleValues: true,
60
166
  },
61
- description: 'List of actions to interact with dynamic content before scraping',
62
- placeholder: 'Add item',
167
+ description: 'Pre-scraping automation actions to interact with dynamic content. Use these to handle JavaScript-rendered pages, click buttons, fill forms, scroll to load more content, or wait for elements. Actions execute in order before content extraction.',
168
+ placeholder: 'Add action',
63
169
  options: [
64
170
  {
65
171
  displayName: 'Items',
@@ -101,7 +207,7 @@ function createActionsProperty(operationName, omitDisplayOptions = false, useNes
101
207
  displayName: 'Selector',
102
208
  type: 'string',
103
209
  default: '',
104
- description: 'The CSS selector for `click` and `write` actions',
210
+ description: 'CSS selector to target an element (e.g., "#submit-btn", ".load-more", "[data-testid=login]"). Used for click, write, and scroll actions.',
105
211
  name: 'selector',
106
212
  displayOptions: {
107
213
  show: {
@@ -113,7 +219,7 @@ function createActionsProperty(operationName, omitDisplayOptions = false, useNes
113
219
  displayName: 'Milliseconds',
114
220
  type: 'number',
115
221
  default: 1000,
116
- description: 'Milliseconds to wait for `wait` action',
222
+ description: 'Time to wait in milliseconds. Use this to allow JavaScript content to load or animations to complete. Typical values: 1000-3000ms for most pages, 5000ms+ for heavy SPAs.',
117
223
  name: 'milliseconds',
118
224
  displayOptions: {
119
225
  show: {
@@ -137,7 +243,7 @@ function createActionsProperty(operationName, omitDisplayOptions = false, useNes
137
243
  displayName: 'Text',
138
244
  type: 'string',
139
245
  default: '',
140
- description: 'Text for `write` action',
246
+ description: 'Text to type into an input field. Use with selector to target the input element. Useful for search boxes, login forms, or any text input.',
141
247
  name: 'text',
142
248
  displayOptions: {
143
249
  show: {
@@ -149,7 +255,7 @@ function createActionsProperty(operationName, omitDisplayOptions = false, useNes
149
255
  displayName: 'Key',
150
256
  type: 'string',
151
257
  default: '',
152
- description: 'Key for `press` action',
258
+ description: 'Keyboard key to press (e.g., "Enter", "Tab", "Escape", "ArrowDown"). Use for form submission, navigation, or triggering keyboard shortcuts.',
153
259
  name: 'key',
154
260
  displayOptions: {
155
261
  show: {
@@ -202,20 +308,20 @@ function createActionsProperty(operationName, omitDisplayOptions = false, useNes
202
308
  useCustomBody: [true],
203
309
  },
204
310
  show: {
205
- resource: ['Default'],
311
+ resource: [resourceName],
206
312
  operation: [operationName],
207
313
  },
208
314
  },
209
315
  };
210
316
  }
211
317
  exports.createActionsProperty = createActionsProperty;
212
- function createLocationProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true) {
318
+ function createLocationProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true, resourceName = 'Scraping') {
213
319
  return {
214
320
  displayName: 'Location',
215
321
  name: 'location',
216
322
  type: 'fixedCollection',
217
323
  default: {},
218
- description: 'Location settings for the request',
324
+ description: 'Geographic location settings for the request. Use this to access geo-restricted content or see region-specific versions of websites. Affects IP geolocation and Accept-Language headers.',
219
325
  options: [
220
326
  {
221
327
  displayName: 'Location Settings',
@@ -294,14 +400,14 @@ function createLocationProperty(operationName, omitDisplayOptions = false, useNe
294
400
  useCustomBody: [true],
295
401
  },
296
402
  show: {
297
- resource: ['Default'],
403
+ resource: [resourceName],
298
404
  operation: [operationName],
299
405
  },
300
406
  },
301
407
  };
302
408
  }
303
409
  exports.createLocationProperty = createLocationProperty;
304
- function createIncludeTagsProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true) {
410
+ function createIncludeTagsProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true, resourceName = 'Scraping') {
305
411
  return {
306
412
  displayName: 'Include Tags',
307
413
  name: 'includeTags',
@@ -310,7 +416,7 @@ function createIncludeTagsProperty(operationName, omitDisplayOptions = false, us
310
416
  typeOptions: {
311
417
  multipleValues: true,
312
418
  },
313
- description: 'Specifies tags to include in the output',
419
+ description: 'HTML tags to retain in the output. Only content within these tags will be included. Useful for extracting specific sections like article content, product details, or main content areas.',
314
420
  placeholder: 'Add tag to include',
315
421
  options: [
316
422
  {
@@ -348,14 +454,62 @@ function createIncludeTagsProperty(operationName, omitDisplayOptions = false, us
348
454
  useCustomBody: [true],
349
455
  },
350
456
  show: {
351
- resource: ['Default'],
457
+ resource: [resourceName],
352
458
  operation: [operationName],
353
459
  },
354
460
  },
355
461
  };
356
462
  }
357
463
  exports.createIncludeTagsProperty = createIncludeTagsProperty;
358
- function createExcludeTagsProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true) {
464
+ function createBatchUrlsProperty(operationName, defaultUrl = 'https://firecrawl.dev', resourceName = 'Default') {
465
+ return {
466
+ displayName: 'URLs',
467
+ name: 'urls',
468
+ type: 'string',
469
+ typeOptions: {
470
+ rows: 4,
471
+ },
472
+ default: defaultUrl,
473
+ required: true,
474
+ description: 'URLs to scrape in batch. Accepts multiple formats: a single URL, multiple URLs separated by commas or newlines, a JSON array like ["url1", "url2"], or an array expression from a previous node. Each URL is scraped independently with the same settings. Example: "https://example.com/page1, https://example.com/page2" or paste one URL per line.',
475
+ placeholder: 'https://example.com/page1\nhttps://example.com/page2',
476
+ routing: {
477
+ request: {
478
+ body: {
479
+ urls: '={{ $value }}',
480
+ },
481
+ },
482
+ send: {
483
+ preSend: [
484
+ async function (requestOptions) {
485
+ if (typeof requestOptions.body !== 'object' || !requestOptions.body) {
486
+ return requestOptions;
487
+ }
488
+ const body = requestOptions.body;
489
+ if (body.urls !== undefined) {
490
+ const rawValue = body.urls;
491
+ const urlsArray = extractUrls(rawValue);
492
+ const uniqueUrls = [...new Set(urlsArray)].filter(Boolean);
493
+ if (uniqueUrls.length === 0) {
494
+ throw new Error('At least one valid URL is required. Provide URLs as a single URL, comma-separated list, one per line, or a JSON array.');
495
+ }
496
+ body.urls = uniqueUrls;
497
+ }
498
+ return requestOptions;
499
+ },
500
+ ],
501
+ },
502
+ },
503
+ displayOptions: {
504
+ show: {
505
+ resource: [resourceName],
506
+ operation: [operationName],
507
+ },
508
+ },
509
+ };
510
+ }
511
+ exports.createBatchUrlsProperty = createBatchUrlsProperty;
512
+ function createExcludeTagsProperty(operationName, omitDisplayOptions = false, useNestedScrapeOptions = true, resourceName = 'Scraping') {
359
513
  return {
360
514
  displayName: 'Exclude Tags',
361
515
  name: 'excludeTags',
@@ -364,7 +518,7 @@ function createExcludeTagsProperty(operationName, omitDisplayOptions = false, us
364
518
  typeOptions: {
365
519
  multipleValues: true,
366
520
  },
367
- description: 'Specifies tags to exclude from the output',
521
+ description: 'HTML tags to remove from the output. Content within these tags will be excluded. Common uses: removing navigation (nav), sidebars (aside), footers, ads, or cookie banners.',
368
522
  placeholder: 'Add tag to exclude',
369
523
  options: [
370
524
  {
@@ -402,23 +556,149 @@ function createExcludeTagsProperty(operationName, omitDisplayOptions = false, us
402
556
  useCustomBody: [true],
403
557
  },
404
558
  show: {
405
- resource: ['Default'],
559
+ resource: [resourceName],
406
560
  operation: [operationName],
407
561
  },
408
562
  },
409
563
  };
410
564
  }
411
565
  exports.createExcludeTagsProperty = createExcludeTagsProperty;
412
- function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = true) {
566
+ function createBatchSpecificProperties() {
567
+ return [
568
+ {
569
+ displayName: 'Webhook',
570
+ name: 'webhook',
571
+ type: 'fixedCollection',
572
+ default: {},
573
+ description: 'Configure webhook notifications for batch job progress. Receive real-time updates when scraping starts, completes each page, finishes, or fails. Ideal for monitoring long-running jobs.',
574
+ options: [
575
+ {
576
+ displayName: 'Webhook Settings',
577
+ name: 'settings',
578
+ values: [
579
+ {
580
+ displayName: 'URL',
581
+ name: 'url',
582
+ type: 'string',
583
+ required: true,
584
+ default: '',
585
+ description: 'The URL to send the webhook to. Triggers for batchScrape.started, batchScrape.page, batchScrape.completed, or batchScrape.failed events.',
586
+ },
587
+ {
588
+ displayName: 'Headers',
589
+ name: 'headers',
590
+ type: 'fixedCollection',
591
+ default: {},
592
+ typeOptions: {
593
+ multipleValues: true,
594
+ },
595
+ description: 'Headers to send to the webhook URL',
596
+ options: [
597
+ {
598
+ displayName: 'Header',
599
+ name: 'header',
600
+ values: [
601
+ {
602
+ displayName: 'Key',
603
+ name: 'key',
604
+ type: 'string',
605
+ default: '',
606
+ description: 'Header key',
607
+ },
608
+ {
609
+ displayName: 'Value',
610
+ name: 'value',
611
+ type: 'string',
612
+ default: '',
613
+ description: 'Header value',
614
+ },
615
+ ],
616
+ },
617
+ ],
618
+ },
619
+ {
620
+ displayName: 'Metadata',
621
+ name: 'metadata',
622
+ type: 'json',
623
+ default: '{}',
624
+ description: 'Custom metadata that will be included in all webhook payloads for this crawl',
625
+ },
626
+ {
627
+ displayName: 'Events',
628
+ name: 'events',
629
+ type: 'multiOptions',
630
+ options: [
631
+ {
632
+ name: 'Started',
633
+ value: 'started',
634
+ },
635
+ {
636
+ name: 'Page',
637
+ value: 'page',
638
+ },
639
+ {
640
+ name: 'Completed',
641
+ value: 'completed',
642
+ },
643
+ {
644
+ name: 'Failed',
645
+ value: 'failed',
646
+ },
647
+ ],
648
+ default: ['completed', 'page', 'failed', 'started'],
649
+ description: 'Type of events that should be sent to the webhook URL',
650
+ },
651
+ ],
652
+ },
653
+ ],
654
+ routing: {
655
+ request: {
656
+ body: {
657
+ webhook: '={{$value.settings ? { url: $value.settings.url, headers: $value.settings.headers?.header?.reduce((acc, h) => ({ ...acc, [h.key]: h.value }), {}) || {}, metadata: $value.settings.metadata ? JSON.parse($value.settings.metadata) : {}, events: $value.settings.events || [] } : undefined}}',
658
+ },
659
+ },
660
+ },
661
+ },
662
+ {
663
+ displayName: 'Max Concurrency',
664
+ name: 'maxConcurrency',
665
+ type: 'number',
666
+ default: 100,
667
+ description: 'Maximum number of URLs to scrape simultaneously. Higher values speed up batch jobs but may trigger rate limits. Leave at default to use your team\'s plan limit.',
668
+ },
669
+ {
670
+ displayName: 'Ignore Invalid URLs',
671
+ name: 'ignoreInvalidURLs',
672
+ type: 'boolean',
673
+ default: true,
674
+ description: 'Whether to continue processing valid URLs even if some are malformed or inaccessible. When disabled, the entire batch fails if any URL is invalid.',
675
+ },
676
+ {
677
+ displayName: 'Store In Cache',
678
+ name: 'storeInCache',
679
+ type: 'boolean',
680
+ default: true,
681
+ description: 'Whether to cache scraped pages for faster subsequent requests. Disable for privacy-sensitive scraping or when you need fresh data on every request.',
682
+ },
683
+ {
684
+ displayName: 'Zero Data Retention',
685
+ name: 'zeroDataRetention',
686
+ type: 'boolean',
687
+ default: false,
688
+ description: 'Whether to delete all scraped data from Firecrawl servers immediately after returning results. Enable for maximum privacy compliance (GDPR, HIPAA). Requires special account access.',
689
+ },
690
+ ];
691
+ }
692
+ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = true, batchMode = false, resourceName = 'Scraping') {
413
693
  const scrapeOptionsBody = useNestedScrapeOptions
414
694
  ? { scrapeOptions: '={{$value.options}}' }
415
- : '={{$value.options}}';
695
+ : '={{Object.fromEntries(Object.entries($value.options || {}).filter(([k]) => k !== "webhook"))}}';
416
696
  return {
417
697
  displayName: 'Scrape Options',
418
698
  name: 'scrapeOptions',
419
699
  type: 'fixedCollection',
420
700
  default: {},
421
- description: 'Options for scraping content during the crawl',
701
+ description: 'Configure how content is extracted from pages. Control output formats (markdown, HTML, JSON), content filtering, timing, caching, and browser emulation settings.',
422
702
  options: [
423
703
  {
424
704
  displayName: 'Options',
@@ -432,7 +712,7 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
432
712
  typeOptions: {
433
713
  multipleValues: true,
434
714
  },
435
- description: 'Output format(s) for the scraped data',
715
+ description: 'Output format(s) for scraped content. Use "Summary" when user wants a brief overview or summary of the page. Use "Markdown" for full content (best for AI/LLM). HTML preserves structure. JSON enables structured data extraction. Screenshot captures visual representation.',
436
716
  placeholder: 'Add format',
437
717
  options: [
438
718
  {
@@ -444,39 +724,47 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
444
724
  name: 'type',
445
725
  type: 'options',
446
726
  default: 'markdown',
447
- description: 'The type of format',
727
+ description: 'Output format for scraped content. Use "Summary" when user asks for a summary, overview, or condensed version of page content. Use "Markdown" for full content in AI-readable format.',
448
728
  options: [
449
729
  {
450
730
  name: 'Change Tracking',
451
731
  value: 'changeTracking',
732
+ description: 'Track changes between page versions over time',
452
733
  },
453
734
  {
454
735
  name: 'HTML',
455
736
  value: 'html',
737
+ description: 'Clean HTML with scripts and styles removed',
456
738
  },
457
739
  {
458
740
  name: 'JSON',
459
741
  value: 'json',
742
+ description: 'Extract structured data using AI with a schema',
460
743
  },
461
744
  {
462
745
  name: 'Links',
463
746
  value: 'links',
747
+ description: 'Extract all links from the page',
464
748
  },
465
749
  {
466
750
  name: 'Markdown',
467
751
  value: 'markdown',
752
+ description: 'Full page content as markdown - best for AI/LLM processing and reading full content',
468
753
  },
469
754
  {
470
755
  name: 'Raw HTML',
471
756
  value: 'rawHtml',
757
+ description: 'Original HTML including scripts and styles',
472
758
  },
473
759
  {
474
760
  name: 'Screenshot',
475
761
  value: 'screenshot',
762
+ description: 'Visual screenshot of the page as base64 image',
476
763
  },
477
764
  {
478
765
  name: 'Summary',
479
766
  value: 'summary',
767
+ description: 'AI-generated concise summary of page content - USE THIS when user asks for a summary, overview, brief description, or wants to quickly understand what a page is about',
480
768
  },
481
769
  ],
482
770
  },
@@ -636,7 +924,7 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
636
924
  name: 'onlyMainContent',
637
925
  type: 'boolean',
638
926
  default: true,
639
- description: 'Whether to only return the main content of the page excluding headers, navs, footers, etc',
927
+ description: 'Whether to automatically remove navigation, headers, footers, sidebars, and other boilerplate content. Best for extracting article text or primary page content. Disable to capture the full page.',
640
928
  },
641
929
  createIncludeTagsProperty(operationName, true, useNestedScrapeOptions),
642
930
  createExcludeTagsProperty(operationName, true, useNestedScrapeOptions),
@@ -645,7 +933,7 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
645
933
  name: 'headers',
646
934
  type: 'collection',
647
935
  default: {},
648
- description: 'Headers to send with the request',
936
+ description: 'Custom HTTP headers to send with the request. Use for authentication tokens, cookies, custom user-agents, or API keys required by the target website.',
649
937
  options: [
650
938
  {
651
939
  displayName: 'Key',
@@ -668,28 +956,28 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
668
956
  name: 'waitFor',
669
957
  type: 'number',
670
958
  default: 0,
671
- description: 'Wait milliseconds for the page to load before fetching content',
959
+ description: 'Additional wait time in milliseconds after page load before extracting content. Use for JavaScript-heavy sites where content renders dynamically. 0 uses intelligent auto-detection.',
672
960
  },
673
961
  {
674
962
  displayName: 'Mobile',
675
963
  name: 'mobile',
676
964
  type: 'boolean',
677
965
  default: false,
678
- description: 'Whether to emulate scraping from a mobile device',
966
+ description: 'Whether to emulate a mobile device when scraping. Useful for sites with mobile-specific content, responsive layouts, or mobile-only features. Changes viewport and user-agent.',
679
967
  },
680
968
  {
681
969
  displayName: 'Skip TLS Verification',
682
970
  name: 'skipTlsVerification',
683
971
  type: 'boolean',
684
972
  default: false,
685
- description: 'Whether to skip TLS certificate verification when making requests',
973
+ description: 'Whether to bypass SSL/TLS certificate validation. Enable for sites with self-signed or expired certificates. Use with caution as it reduces security.',
686
974
  },
687
975
  {
688
976
  displayName: 'Timeout (Ms)',
689
977
  name: 'timeout',
690
978
  type: 'number',
691
979
  default: 30000,
692
- description: 'Timeout in milliseconds for the request',
980
+ description: 'Maximum time in milliseconds to wait for the page to load. Increase for slow sites or complex pages. Default 30000ms (30 seconds).',
693
981
  },
694
982
  createActionsProperty(operationName, true, useNestedScrapeOptions),
695
983
  createLocationProperty(operationName, true, useNestedScrapeOptions),
@@ -698,28 +986,28 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
698
986
  name: 'removeBase64Images',
699
987
  type: 'boolean',
700
988
  default: true,
701
- description: 'Whether to remove base64 encoded images from the output',
989
+ description: 'Whether to strip embedded base64 images from output while preserving alt text. Reduces output size significantly. Disable if you need inline image data.',
702
990
  },
703
991
  {
704
992
  displayName: 'Block Ads',
705
993
  name: 'blockAds',
706
994
  type: 'boolean',
707
995
  default: true,
708
- description: 'Whether to enables ad-blocking and cookie popup blocking',
996
+ description: 'Whether to enable ad-blocking and cookie consent popup blocking for cleaner content extraction. Recommended for most scraping tasks.',
709
997
  },
710
998
  {
711
999
  displayName: 'Store In Cache',
712
1000
  name: 'storeInCache',
713
1001
  type: 'boolean',
714
1002
  default: true,
715
- description: 'Whether to store the page in the Firecrawl index and cache. Disable for data protection concerns or when using sensitive scraping parameters.',
1003
+ description: 'Whether to cache the scraped page for faster subsequent requests. Disable for real-time data needs, sensitive content, or when privacy is a concern.',
716
1004
  },
717
1005
  {
718
1006
  displayName: 'Proxy',
719
1007
  name: 'proxy',
720
1008
  type: 'options',
721
1009
  default: 'basic',
722
- description: 'Specifies the type of proxy to use',
1010
+ description: 'Proxy strategy for bypassing anti-bot measures. Basic is faster and cheaper. Stealth uses residential proxies for better success on protected sites.',
723
1011
  options: [
724
1012
  {
725
1013
  name: 'Basic',
@@ -731,6 +1019,7 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
731
1019
  },
732
1020
  ],
733
1021
  },
1022
+ ...(batchMode ? createBatchSpecificProperties() : []),
734
1023
  ],
735
1024
  },
736
1025
  ],
@@ -744,7 +1033,7 @@ function createScrapeOptionsProperty(operationName, useNestedScrapeOptions = tru
744
1033
  useCustomBody: [true],
745
1034
  },
746
1035
  show: {
747
- resource: ['Default'],
1036
+ resource: [resourceName],
748
1037
  operation: [operationName],
749
1038
  },
750
1039
  },