Malwarebytes · AsyncAPI Specification
Malwarebytes Threatdown Webhooks
Version
View Spec
View on GitHub
CompanySecurityCybersecurityEndpoint SecurityAnti-MalwareEndpoint Detection and ResponseThreat DetectionVulnerability ManagementPatch ManagementManaged Service ProvidersDNS FilteringWebhooksAsyncAPIWebhooksEvents
AsyncAPI Specification
generated: '2026-08-04'
method: derived
source: >-
openapi/malwarebytes-threatdown-nebula-openapi.json — the "Webhooks" tag description,
which is the provider's own webhook documentation, verbatim in substance
summary: >-
ThreatDown publishes a real, well-specified webhook surface: 18 event types, an
HMAC-SHA256 signature scheme, an explicit delivery envelope, and documented retry
semantics. It does NOT publish an AsyncAPI document — the whole event contract lives
in prose inside the OpenAPI tag description. This artifact captures that catalog so
the event surface is machine-addressable; it is a Webhooks catalog, not a fabricated
AsyncAPI.
asyncapi_published: false
webhooks:
published: true
transport: HTTP POST to a subscriber-supplied URL
payload_format: application/json
subscription_management: API-only
subscription_note: >-
"ThreatDown provides you with REST APIs for creating, retrieving, and deleting
subscriptions. Currently, subscriptions can be registered only through APIs." There
is no console UI for webhook subscriptions.
multiple_handlers_per_event: true
subscription_operations:
- api: nebula
operationId: api.v2.nebula.post.webhooks.subscriptions
method: POST
path: /nebula/v1/webhooks/subscriptions
summary: Create subscription
scope: write
user_permission: notifications.createOwn
- api: nebula
operationId: api.v2.nebula.webhooks.subscriptions.get
method: GET
path: /nebula/v1/webhooks/subscriptions
summary: Get all subscriptions
scope: read
user_permission: notifications.viewOwn
- api: nebula
operationId: api.v2.nebula.webhooks.subscriptions.get.id
method: GET
path: /nebula/v1/webhooks/subscriptions/{id}
summary: Get a subscription
scope: read
user_permission: notifications.viewOwn
- api: nebula
operationId: api.v2.nebula.post.webhooks.subscriptions.update
method: PUT
path: /nebula/v1/webhooks/subscriptions/{id}
summary: Update a subscription
scope: write
user_permission: notifications.editOwn
- api: nebula
operationId: api.v2.nebula.post.webhooks.subscriptions.delete
method: DELETE
path: /nebula/v1/webhooks/subscriptions/{id}
summary: Delete subscription
scope: write
user_permission: notifications.deleteOwn
- api: oneview
operationId: api.v2.rmm.post.webhooks.subscriptions
method: POST
path: /oneview/v1/accounts/{account_id}/webhooks/subscriptions
summary: Create webhook subscription
scope: write
user_permission: notifications.createOwn
- api: oneview
operationId: api.v2.rmm.webhooks.subscriptions.get
method: GET
path: /oneview/v1/accounts/{account_id}/webhooks/subscriptions
summary: Get all webhook subscriptions
scope: read
user_permission: notifications.viewOwn
- api: oneview
operationId: api.v2.rmm.webhooks.subscriptions.get.id
method: GET
path: /oneview/v1/accounts/{account_id}/webhooks/subscriptions/{id}
summary: Get webhook subscription
scope: read
user_permission: notifications.viewOwn
- api: oneview
operationId: api.v2.rmm.post.webhooks.subscriptions.update
method: PUT
path: /oneview/v1/accounts/{account_id}/webhooks/subscriptions/{id}
summary: Update a subscription
scope: write
user_permission: notifications.editOwn
- api: oneview
operationId: api.v2.rmm.post.webhooks.subscriptions.delete
method: DELETE
path: /oneview/v1/accounts/{account_id}/webhooks/subscriptions/{id}
summary: Delete webhook subscription
scope: write
user_permission: notifications.deleteOwn
envelope:
description: Every notification is wrapped in a common envelope carrying metadata.
fields:
- name: event
type: string
description: The event type — one of the supported events below.
- name: subscription_id
type: string
description: Unique identifier of the subscription that matched this event.
- name: account_id
type: string
description: Nebula account id (site) generating this event.
- name: payload
type: object
description: Event-specific data; its model varies by the value of `event`.
dispatch_note: >-
Consumers switch processing on `event` and interpret `payload` accordingly.
events:
- name: job_status_change
description: >-
Sent when a job issued through the Jobs APIs changes status — the way to track scan,
isolate, remediate and reboot completion without polling.
payload_fields:
- name: id
type: string
description: Unique identifier of the job
- name: machine_id
type: string
description: Unique identifier of the endpoint
- name: command
type: string
description: Type of command (see the Jobs API)
- name: issued_by
type: string
description: User issuing the job
- name: status
type: string
description: Job status, including PENDING, STARTED, TIMED_OUT and COMPLETED
- name: detection
description: A threat detection was reported by the ThreatDown Endpoint Agent.
- name: machine_events
description: Endpoint/machine lifecycle events.
- name: threat_events
description: Threat-related events.
- name: agent_events
description: ThreatDown Endpoint Agent events.
- name: quarantine_events
description: Quarantine add/restore/delete events.
- name: edr_events
description: Endpoint Detection and Response events.
- name: syslog_events
description: Syslog forwarding events.
- name: exclusion_events
description: Exclusion created, edited or deleted.
- name: scheduled_events
description: Scheduled task events.
- name: policy_events
description: Policy created, edited or deleted.
- name: user_events
description: User administration events.
- name: drive_events
description: Drive encryption events.
- name: cve_events
description: Vulnerability (CVE) events, including vulnerability-resolved.
- name: dns_events
description: DNS filtering events.
- name: license_events
description: Licensing events.
- name: appblock_events
description: Application block events.
- name: endpoint_events
description: Endpoint events.
event_count: 18
subscription_payload:
source: POST /nebula/v1/webhooks/subscriptions requestBody schema
required: [url, enabled, events]
fields:
- name: url
type: string
constraint: 'must match ^https://.{4,}$ — HTTPS only'
- name: enabled
type: boolean
- name: events
type: array
min_items: 1
enum_note: >-
The schema enum carries the 18 event names above PLUS the wildcard value "all",
which subscribes to every event type in one subscription.
- name: description
type: string
- name: custom_headers
type: array
description: Key/value headers ThreatDown will include on each delivery to your endpoint.
- name: max_retries
type: integer
default: 10
maximum: 10
exclusive_minimum: 0
- name: secret_token
type: string
description: The signing key used to compute the HMAC of the payload.
security:
signature_header: X-MWB-Signature
algorithm: HMAC-SHA256
computation: HMAC_SHA256(secret_token, webhookPayload)
secret: >-
A `secret_token` parameter supplied by the subscriber when creating the subscription;
used as the signing key.
verification: >-
Compute the HMAC over the raw request body and compare with X-MWB-Signature. A match
establishes ThreatDown as the sender.
quoted: >-
"ThreatDown will sign the webhook events it sends to your server. We do so by
including a signature in each event's `X-MWB-Signature` header."
delivery:
acknowledgement: Return any 2xx HTTP status code.
failure_definition: >-
Any response outside 2xx — explicitly including 3xx — is treated as a failure.
retry_strategy: exponential backoff
default_max_retries: 5
configurable: true
configuration_param: max_retries
discrepancy: >-
The Webhooks prose states "The default maximum number of retries is `5`", but the
request schema for POST /nebula/v1/webhooks/subscriptions declares max_retries with
default 10, exclusiveMinimum 0 and maximum 10. The narrative and the machine-readable
contract disagree on the default. Report upstream.
give_up_behaviour: >-
After the maximum attempts the notification is dropped. "You will be responsible for
reconciling your data by querying our API endpoints for potentially missed events."
at_least_once: true
consumer_requirement: >-
"We recommend you design idempotent event processing because you might receive the
same event more than once."
positioning:
provider_guidance: >-
ThreatDown actively steers integrators off polling: "The alternative to registering
webhooks is performing polling, but this is deeply discouraged: besides involving
more complicated code on your side, you may exceed your quota." Webhooks are also
listed first among the remedies for a 429.
gaps:
- >-
No AsyncAPI document. The event contract is prose in an OpenAPI tag description, so no
event-driven tooling can generate consumers or validate payloads.
- >-
Only the job_status_change payload model is fully specified. The other 17 event types
are named with a one-line description and no payload schema.
- >-
No published event catalog page outside the API reference, and no event versioning or
schema-evolution policy.
- No replay/redelivery API for events dropped after max retries — reconciliation is manual.
- No timestamp or delivery-id field documented in the envelope for ordering or dedup.