Part of #338. Depends on gap #1 (per-parameter flags).
Today
Many APIs have a webhook config nested inside the request body:
webhook:
type: object
properties:
url: { type: string, format: uri }
headers: { type: object, additionalProperties: { type: string } }
metadata: { type: object }
events: { type: array, items: { type: string, enum: [...] } }
Per-property flattening (gap #1) skips nested objects today. Firecrawl hand-writes BuildCrawlWebhookAsync / BuildBatchWebhookAsync to compose flags like --webhook-url, --webhook-header k=v, --webhook-metadata k=v, --webhook-event ... into a single webhook struct. ~150 lines, repeated twice with cosmetic differences.
Target
firecrawl crawl https://example.com \
--webhook-url https://my.app/hook \
--webhook-header authorization=Bearer\\ xyz \
--webhook-header x-request-id=abc \
--webhook-metadata customer-id=42 \
--webhook-event completed --webhook-event errored
Proposed approach
- Detection heuristic: a nested object property is webhook-shaped when it has:
- a property of
string/format: uri (any name; url/endpoint/callback/webhook preferred)
- AT LEAST ONE of: a string-map (
headers), a generic-object (metadata), an enum-array (events)
- Generate
--<prefix>-* flag set where <prefix> is the property's kebab-cased name (webhook, notification-url, etc.):
- URL → single
--<prefix>-url (string)
- headers map → repeatable
--<prefix>-header KEY=VALUE (Option<Dictionary<string,string>> with custom parser)
- metadata map → repeatable
--<prefix>-metadata KEY=VALUE
- events array → repeatable
--<prefix>-event with FromAmong(...) for enum constraint
- Composite builder in generated invocation: when
--<prefix>-url is present, construct the nested object from all --<prefix>-* flags and assign to the request body.
- Add helpers to
CliRuntime: ParseKeyValueAsync(IEnumerable<string> tokens) -> Dictionary<string,string>.
- Vendor extension
x-cli-webhook: false to opt out (fall back to nested --<prop>-json).
Acceptance criteria
- Firecrawl
crawl and batch-scrape expose --webhook-url, --webhook-header, --webhook-metadata, --webhook-event after regen.
- Repeated flags accumulate (
--webhook-header a=1 --webhook-header b=2).
- Without any
--webhook-* flag, the webhook field stays unset in the request.
- Snapshot test covers an operation with a webhook-shaped property.
Part of #338. Depends on gap #1 (per-parameter flags).
Today
Many APIs have a webhook config nested inside the request body:
Per-property flattening (gap #1) skips nested objects today. Firecrawl hand-writes
BuildCrawlWebhookAsync/BuildBatchWebhookAsyncto compose flags like--webhook-url,--webhook-header k=v,--webhook-metadata k=v,--webhook-event ...into a single webhook struct. ~150 lines, repeated twice with cosmetic differences.Target
Proposed approach
string/format: uri(any name;url/endpoint/callback/webhookpreferred)headers), a generic-object (metadata), an enum-array (events)--<prefix>-*flag set where<prefix>is the property's kebab-cased name (webhook,notification-url, etc.):--<prefix>-url(string)--<prefix>-header KEY=VALUE(Option<Dictionary<string,string>>with custom parser)--<prefix>-metadata KEY=VALUE--<prefix>-eventwithFromAmong(...)for enum constraint--<prefix>-urlis present, construct the nested object from all--<prefix>-*flags and assign to the request body.CliRuntime:ParseKeyValueAsync(IEnumerable<string> tokens) -> Dictionary<string,string>.x-cli-webhook: falseto opt out (fall back to nested--<prop>-json).Acceptance criteria
crawlandbatch-scrapeexpose--webhook-url,--webhook-header,--webhook-metadata,--webhook-eventafter regen.--webhook-header a=1 --webhook-header b=2).--webhook-*flag, the webhook field stays unset in the request.