Webhook

Anchore uses outgoing webhooks to send event notifications to external services. When a webhook is triggered, Anchore makes a POST request to the registered URL.

Request Format

Method: POST

Headers:

Content-Type: application/json Authorization: Basic (if configured) User-Agent: python-requests/x.x.x Accept: /

Body

{
  "id": "string",
  "type": "string",
  "level": "string",
  "message": "string",
  "details": {
    "msg": "string"
  },
  "timestamp": "ISO-8601 string",
  "resource": {
    "account_name": "string",
    "type": "string",
    "id": "string | null"
  },
  "source": {
    "request_id": "string | null",
    "service_name": "string",
    "host_id": "string",
    "base_url": "string"
  }
}

Body Field Details

id → Unique identifier of the webhook event.

type → Event type (e.g., system.test.random_wisdom, policy_eval, analysis_update).

level → Severity level (info, warn, error).

message → Human-readable description of the event.

details → Object containing additional event-specific data.

timestamp → Event timestamp in ISO-8601 format.

Resource

account_name → Anchore account where the event originated.

type → Type of resource (e.g., wisdom, image, policy).

id → Identifier for the resource (nullable).

source

request_id → ID of the request (nullable).

service_name → Anchore service that generated the event.

host_id → Pod or container identifier.

base_url → Base URL of the Anchore API.

Example Payload for a system test

{
  "id": "211c5fff5641456d935e60f905c46a66",
  "type": "system.test.random_wisdom",
  "level": "info",
  "message": "Unsolicited random wisdom of the moment",
  "details": {
    "msg": "It is better to keep your mouth closed and let people think you are a fool than to open it and remove all doubt - Mark Twain"
  },
  "timestamp": "2025-10-01T09:08:54.749806",
  "resource": {
    "account_name": "admin",
    "type": "wisdom",
    "id": null
  },
  "source": {
    "request_id": null,
    "service_name": "apiext",
    "host_id": "anchore-enterprise-api-b7d8c686b-p6wbr",
    "base_url": "http://anchore-enterprise-api.anchore.svc.cluster.local:8228"
  }
}

Here is an example of ClamAV database sync completion update

{
  "id": "82821ca97cce4121a798b9e7738f5251",
  "source": {
    "service_name": "analyzer",
    "host_id": "anchore-enterprise-analyzer-5899ff77dc-g9zt4",
    "base_url": "http://anchore-enterprise-analyzer.anchore.svc.cluster.local:8084",
    "request_id": null
  },
  "resource": {
    "account_name": "admin",
    "id": null,
    "type": "clamav"
  },
  "type": "system.analyzer.clamav_sync.completed",
  "level": "info",
  "message": "Analyzer ClamAV database sync completed",
  "details": {
    "msg": "No new ClamAV DB available"
  },
  "timestamp": "2025-10-01T10:42:16.811688Z"
}

Here is an example of failed analysis notification due to image not found in registry

{
  "id": "5fb694f3c245447cb1302ec412b490fe",
  "source": {
    "service_name": "catalog",
    "host_id": "anchore-enterprise-catalog-5654fb8d84-5ln8r",
    "base_url": "http://anchore-enterprise-catalog.anchore.svc.cluster.local:8082",
    "request_id": null
  },
  "resource": {
    "account_name": "admin",
    "id": "docker.io/sopuru24/alpine:latest",
    "type": "image_reference"
  },
  "type": "system.image_analysis.registry_lookup_failed",
  "level": "error",
  "message": "Referenced image not found in registry",
  "details": {
    "anchore_error_json": {
      "message": "cannot fetch image digest/manifest from registry",
      "detail": {
        "raw_exception_message": "could not get manifest/digest for image (docker.io/sopuru24/alpine:latest) from registry (https://index.docker.io) - error: Error encountered in skopeo operation. cmd=/bin/sh -c skopeo inspect --raw   --tls-verify=true --creds \"${SKOPUSER}\":\"${SKOPPASS}\" docker://docker.io/sopuru24/alpine:latest, rc=2, stdout=None, stderr=b'time=\"2025-10-01T10:43:27Z\" level=fatal msg=\"Error parsing image name \\\\\"docker://docker.io/sopuru24/alpine:latest\\\\\": reading manifest latest in docker.io/sopuru24/alpine: manifest unknown\"\\n', error_code=REGISTRY_IMAGE_NOT_FOUND",
        "error_codes": []
      },
      "httpcode": 400
    }
  },
  "timestamp": "2025-10-01T10:43:27.011960Z"
}

You can also send notifications about the status of an Image. Here is an example notification of the status of an image

{
  "id": "ba43f06006c54a01b7a9ba59d3355e00",
  "source": {
    "service_name": "analyzer",
    "host_id": "anchore-enterprise-analyzer-5899ff77dc-g9zt4",
    "base_url": "http://anchore-enterprise-analyzer.anchore.svc.cluster.local:8084",
    "request_id": null
  },
  "resource": {
    "account_name": "admin",
    "id": "docker.io/anchore/enterprise-ui:v5.21.0",
    "type": "image_tag"
  },
  "type": "user.image.analysis.processing",
  "level": "info",
  "message": "Image has entered analyzing state and is being analyzed",
  "details": {
    "image_digest": "sha256:969af599c28331c76d9142ed60b2f972e0da6cf025b46a48142b7688accfd67a"
  },
  "timestamp": "2025-10-01T10:55:32.980352Z"
}

Here is an example of a complete analysis

{
  "id": "a5455bf5d3034e579f8ebc001e67b01b",
  "source": {
    "service_name": "analyzer",
    "host_id": "anchore-enterprise-analyzer-5899ff77dc-g9zt4",
    "base_url": "http://anchore-enterprise-analyzer.anchore.svc.cluster.local:8084",
    "request_id": null
  },
  "resource": {
    "account_name": "admin",
    "id": "docker.io/alpine:latest",
    "type": "image_tag"
  },
  "type": "user.image.analysis.completed",
  "level": "info",
  "message": "Image analysis available",
  "details": {
    "last_eval": {
      "image_digest": "sha256:eafc1edb577d2e9b458664a15f23ea1c370214193226069eb22921169fc7e43f",
      "analysis_status": "analyzing",
      "annotations": {}
    },
    "curr_eval": {
      "image_digest": "sha256:eafc1edb577d2e9b458664a15f23ea1c370214193226069eb22921169fc7e43f",
      "analysis_status": "analyzed",
      "annotations": {}
    },
    "subscription_type": "analysis_update",
    "annotations": {}
  },
  "timestamp": "2025-10-01T10:55:32.474019Z"
}
Last modified October 1, 2025