Wappalyzer · AsyncAPI Specification
Wappalyzer Webhooks
Version
View Spec
View on GitHub
Technology DetectionTechnographicsWebsite AnalysisCMS DetectionFramework DetectionLead EnrichmentSales IntelligenceSubdomain DiscoveryEmail VerificationMarket ResearchAsyncAPIWebhooksEvents
AsyncAPI Specification
generated: '2026-08-14'
method: searched
source: https://www.wappalyzer.com/openapi/v2-public.yaml
sources:
- https://www.wappalyzer.com/openapi/v2-public.yaml
- https://www.wappalyzer.com/docs/api/v2/basics/
- https://www.wappalyzer.com/docs/api/v2/lookup/
spec_type: Webhooks
asyncapi_published: false
description: >-
Wappalyzer publishes no AsyncAPI document, but it does ship a real, machine-readable event
surface: two OpenAPI 3.1 `callbacks` blocks in its published contract. Long-running work —
a recursive live crawl, and lead-list generation — completes asynchronously and Wappalyzer
POSTs the result to a caller-supplied URL. Payloads are optionally signed. Both callbacks are
consumer-registered per request (no subscription API, no event catalogue, no replay).
delivery:
style: request-scoped callback
transport: HTTPS POST
registration: >-
Per request. There is no webhook subscription endpoint — the destination is supplied inline
as the `callback_url` query parameter (lookup) or the `callbackUrl` body field (lead lists).
retries: not documented
ordering: not documented
replay: not available
security:
signing:
supported: true
optional: true
header: wappalyzer-signature
algorithm: SHA256
formula: sha256(secret + rawRequestBody)
verification: >-
Verbatim from the provider docs — "create a SHA256 hash of the signing secret appended with
the raw JSON request body. The request is valid if the hash matches the value in the
wappalyzer-signature header."
secret_management: >-
A signing secret is created in the Wappalyzer account. Signing is opt-in; the callback
parameter is declared `required: false` in the spec, so an unsigned callback is valid and
the consumer must decide whether to trust it.
docs: https://www.wappalyzer.com/docs/api/v2/basics/
weaknesses:
- Plain SHA256 concatenation rather than an HMAC, so it is vulnerable to length-extension in principle.
- No timestamp in the signed material, so a captured callback can be replayed.
- Opt-in, not on by default.
note: >-
Recorded as the provider publishes it. These are observations about the published scheme,
not a claim that Wappalyzer has been exploited.
events:
- name: lookupCompleted
summary: Final asynchronous lookup result
trigger: >-
GET /lookup with recursive=true (and no cached record) accepts the request and returns
pending crawl markers; the completed technology profile is delivered here. Crawls take up
to 15 minutes.
method: POST
destination_expression: '{$request.query.callback_url}'
destination_source: callback_url query parameter on GET /lookup
payload_schema: LookupCompleted
spec: openapi/_original/wappalyzer-v2-public-openapi.yaml#/paths/~1lookup/get/callbacks/lookupCompleted
source_operation: lookupWebsites
consumer_responses:
- {status: 200, description: Callback accepted by the client.}
- {status: 400, description: Callback payload was rejected by the client.}
alternative: >-
Polling. The provider recommends re-querying the same lookup up to three times, five
minutes apart, if no callback destination is supplied.
- name: listReady
summary: Lead list ready callback
trigger: POST /lists — list generation is accepted and completes asynchronously.
method: POST
destination_expression: '{$request.body#/callbackUrl}'
destination_source: callbackUrl field on the CreateListRequest body
payload_schema: ListReadyCallback
payload_fields:
- {name: id, type: string, required: true, note: 'Lead list id, prefixed lst_'}
- {name: status, type: string, required: true, enum: [Ready]}
- {name: rows, type: object, note: Row counts keyed by segment.}
- {name: setRows, type: object, note: Row counts keyed by field set.}
- {name: totalCredits, type: integer, note: Credits the finalized list will cost.}
- {name: sampleUrl, type: string, format: uri, note: Download URL for the sample rows.}
spec: openapi/_original/wappalyzer-v2-public-openapi.yaml#/paths/~1lists/post/callbacks/listReady
source_operation: createLeadList
consumer_responses:
- {status: 200, description: Callback accepted by the client.}
- {status: 400, description: Callback payload was rejected by the client.}
summary:
event_count: 2
signed: true
asyncapi_document: null
subscription_api: false
streaming_surface: false
note: >-
No AsyncAPI, no event bus, no streaming. The event surface is exactly two request-scoped
completion callbacks. Recorded honestly rather than modelled as a fuller event platform.
x-evidence:
fetched: '2026-08-14'
evidence:
- {url: 'https://www.wappalyzer.com/openapi/v2-public.yaml', http_status: 200, detail: 'OpenAPI 3.1.0, two callbacks blocks'}
- {url: 'https://www.wappalyzer.com/docs/api/v2/basics/', http_status: 200, detail: 'Callback signatures section'}
- {url: 'https://www.wappalyzer.com/docs/integrations/webhooks/', http_status: 200, detail: 'SPA 404 shell — no standalone webhooks docs page exists'}