Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

API Reference

The Content Manager plugin exposes a REST API under /_plugins/_content_manager/. All endpoints require authentication.


YAML Content-Type Support

The Decoders, KVDBs, and Filters endpoints accept requests with Content-Type: application/yaml in addition to the standard Content-Type: application/json. When using YAML, the request body uses the same envelope structure as JSON — the only difference is the serialization format.

Envelope structure

Both JSON and YAML requests use the same envelope:

JSON example:

{
  "integration": "<uuid>",
  "resource": {
    "metadata": { "title": "My Decoder", "author": "Wazuh" },
    "name": "decoder/my-decoder/0",
    "enabled": true
  }
}

Equivalent YAML example:

---
integration: <uuid>
resource:
  metadata:
    title: "My Decoder"
    author: "Wazuh"
  name: decoder/my-decoder/0
  enabled: true

For resource types that do not require an integration field (e.g., Filters, which use space instead), the corresponding field appears at the top level of the envelope in both formats.

YAML field in responses

When a Decoder, KVDB, or Filter is created or updated, a yaml field is stored alongside the document in the indexed record. This field contains a YAML representation of the resource content:

  • YAML requests: The yaml field is generated from the resource subtree of the parsed envelope.
  • JSON requests: The yaml field is auto-generated from the resource content.

Type fidelity

YAML parsing preserves numeric type fidelity. Floating-point values like 5.0 are stored as 5.0 in both the yaml field and the document field — they are not coerced to integers.

Supported endpoints

EndpointMethodsYAML supported
/_plugins/_content_manager/decodersPOST, PUT
/_plugins/_content_manager/kvdbsPOST, PUT
/_plugins/_content_manager/filtersPOST, PUT
/_plugins/_content_manager/integrationsPOST, PUT
/_plugins/_content_manager/rulesPOST, PUT
/_plugins/_content_manager/policy/{space}PUT

Subscription Management

Store CTI Credentials

Stores the provided CTI access token in the .wazuh-cti-credentials hidden index and loads it into memory. If the index does not exist it is recreated automatically before writing.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/subscription

Request Body

FieldTypeRequiredDescription
access_tokenStringYesThe CTI access token used to authenticate against the CTI API

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/subscription" \
  -H 'Content-Type: application/json' \
  -d '{
    "access_token": "GmRhmhcxhwAzkoEqiMEg_DnyEysNkuNhszIySk9eS"
  }'

Example Response

{
  "message": "Credentials received",
  "status": 201
}

Status Codes

CodeDescription
201Credentials stored successfully
400Missing or empty access_token field
500Internal error

Get CTI Subscription Status

Returns the current subscription status and active plan. For registered instances the plan comes from the authenticated CTI endpoint; for unregistered instances, the public free plan is returned.

If the stored token is rejected by the CTI API (e.g. expired or revoked), the credentials document is deleted automatically, the in-memory token is cleared, and the response falls back to the public free plan as if the instance were unregistered.

Request

  • Method: GET
  • Path: /_plugins/_content_manager/subscription

Example Request

curl -sk -u admin:admin -X GET \
  "https://localhost:9200/_plugins/_content_manager/subscription"

Example Response (registered)

{
  "message": {
    "plan": {
      "name": "Premium Plan",
      "is_public": false
    },
    "is_registered": true
  },
  "status": 200
}

Example Response (unregistered)

{
  "message": {
    "plan": {
      "name": "Free",
      "is_public": true
    },
    "is_registered": false
  },
  "status": 200
}

Status Codes

CodeDescription
200Subscription status returned successfully
500Internal error

Delete CTI Credentials

Clears the stored CTI access token document from the credentials index and clears the in-memory token. The credentials index is preserved. After this operation the instance is unregistered. If the credentials index does not exist the operation succeeds without error.

Request

  • Method: DELETE
  • Path: /_plugins/_content_manager/subscription

Example Request

curl -sk -u admin:admin -X DELETE \
  "https://localhost:9200/_plugins/_content_manager/subscription"

Example Response

{
  "message": "Credentials removed",
  "status": 200
}

Status Codes

CodeDescription
200Credentials removed successfully
500Internal error

Content Updates

Trigger Manual Sync

Triggers an immediate content synchronization with the CTI API. Requires a valid subscription.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/update

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/update"

Example Response (accepted)

{
  "message": "The update request has been accepted for processing.",
  "status": 202
}

Example Response (no credentials)

{
  "message": "Token not found. Please create a subscription before attempting to update.",
  "status": 404
}

Example Response (update in progress)

{
  "message": "A content update is already in progress.",
  "status": 409
}

Status Codes

CodeDescription
202Update request accepted for processing
404No access token registered
409A content update is already in progress
500Internal error during sync

Logtest

Execute Logtest

Sends a log event to the Wazuh Engine for analysis. If an integration ID is provided, the integration’s Sigma rules are also evaluated against the normalized event via the Security Analytics Plugin (SAP). If integration is omitted, only the normalization step is performed and the detection section is returned with status: "skipped".

Note: A testing policy must be loaded in the Engine for logtest to execute successfully. Load a policy via the policy promotion endpoint. When an integration is specified, it must exist in the specified space.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/logtest

Request Body

FieldTypeRequiredDescription
integrationStringNoID of the integration to test against. If omitted, only normalization is performed.
spaceStringYes"test" or "standard"
queueIntegerYesQueue number for logtest execution
locationStringYesLog file path or logical source location
eventStringYesRaw log event to test
metadataObjectNoOptional metadata passed to the Engine
trace_levelStringNoTrace verbosity: NONE, ASSET_ONLY, or ALL

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/logtest" \
  -H 'Content-Type: application/json' \
  -d '{
    "integration": "a0b448c8-3d3c-47d4-b7b9-cbc3c175f509",
    "space": "test",
    "queue": 1,
    "location": "/var/log/cassandra/system.log",
    "event": "INFO  [main] 2026-03-31 10:00:00 StorageService.java:123 - Node is ready to serve",
    "trace_level": "NONE"
  }'

Example Response (success with rule match)

{
  "status": 200,
  "message": {
    "normalization": {
      "output": {
        "event": {
          "category": ["database"],
          "kind": "event",
          "original": "INFO  [main] 2026-03-31 10:00:00 StorageService.java:123 - Node is ready to serve"
        },
        "wazuh": {
          "integration": {
            "name": "test-integ",
            "category": "other",
            "decoders": ["decoder/cassandra-default/0"]
          }
        },
        "message": "Node is ready to serve"
      },
      "asset_traces": [],
      "validation": {
        "valid": true,
        "errors": []
      }
    },
    "detection": {
      "status": "success",
      "rules_evaluated": 2,
      "rules_matched": 1,
      "matches": [
        {
          "rule": {
            "id": "85bba177-a2e9-4468-9d59-26f4798906c9",
            "title": "Cassandra Database Event Detected",
            "level": "low",
            "tags": []
          },
          "matched_conditions": [
            "event.category matched 'database'",
            "event.kind matched 'event'"
          ]
        }
      ]
    }
  }
}

Example Response (Engine error, SAP skipped)

{
  "status": 200,
  "message": {
    "normalization": {
      "status": "error",
      "error": {
        "message": "Failed to parse protobuff json request: invalid value",
        "code": "ENGINE_ERROR"
      }
    },
    "detection": {
      "status": "skipped",
      "reason": "Engine processing failed"
    }
  }
}

Example Response (no rules in integration)

{
  "status": 200,
  "message": {
    "normalization": {
      "output": { "..." : "..." },
      "asset_traces": [],
      "validation": { "valid": true, "errors": [] }
    },
    "detection": {
      "status": "success",
      "rules_evaluated": 0,
      "rules_matched": 0,
      "matches": []
    }
  }
}

Example Request (normalization only, no integration)

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/logtest" \
  -H 'Content-Type: application/json' \
  -d '{
    "space": "test",
    "queue": 1,
    "location": "/var/log/syslog",
    "event": "Mar 31 10:00:00 myhost sshd[1234]: Accepted publickey for user from 192.168.1.1 port 22 ssh2",
    "trace_level": "NONE"
  }'

Example Response (normalization only)

{
  "status": 200,
  "message": {
    "normalization": {
      "output": {
        "event": {
          "original": "Mar 31 10:00:00 myhost sshd[1234]: Accepted publickey for user from 192.168.1.1 port 22 ssh2"
        }
      },
      "asset_traces": [],
      "validation": { "valid": true, "errors": [] }
    },
    "detection": {
      "status": "skipped",
      "reason": "No integration provided"
    }
  }
}

Response Fields

FieldTypeDescription
normalization.outputObjectEngine normalized event output
normalization.asset_tracesArrayList of decoders that processed the event
normalization.validationObjectValidation result (valid, errors)
normalization.statusStringPresent on error: "error"
normalization.errorObjectPresent on error: message and code
detection.statusString"success", "error", or "skipped"
detection.reasonStringPresent when status is "skipped"
detection.rules_evaluatedIntegerNumber of Sigma rules evaluated
detection.rules_matchedIntegerNumber of rules that matched
detection.matchesArrayList of matched rules with details
detection.matches[].ruleObjectRule metadata: id, title, level, tags
detection.matches[].matched_conditionsArrayHuman-readable descriptions of conditions that matched

Status Codes

CodeDescription
200Logtest executed (check inner status fields)
400Missing/invalid fields or integration not found
500Engine socket communication error or internal error

Normalization Only

Sends a log event to the Wazuh Engine for decoding and normalization without performing Sigma rule detection. Use this to validate that decoders correctly parse events before testing detection rules.

Note: A testing policy must be loaded in the Engine for normalization to execute successfully.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/logtest/normalization

Request Body

FieldTypeRequiredDescription
spaceStringYes"test" or "standard"
queueIntegerNoQueue number for logtest execution
locationStringNoLog file path or logical source location
inputStringNoRaw log event to normalize
metadataObjectNoOptional metadata passed to the Engine
trace_levelStringNoTrace verbosity: NONE, ASSET_ONLY, or ALL

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/logtest/normalization" \
  -H 'Content-Type: application/json' \
  -d '{
    "space": "test",
    "queue": 1,
    "location": "/var/log/cassandra/system.log",
    "metadata": {},
    "trace_level": "NONE",
    "input": "INFO  [CompactionExecutor-3] 2025-11-30 14:23:45 CassandraDaemon.java:250 - Some message - 7500 - 4"
  }'

Example Response

{
  "status": 200,
  "message": {
    "output": {
      "log": {
        "level": "INFO",
        "origin": {
          "file": {
            "name": "CassandraDaemon.java",
            "line": 250
          }
        }
      },
      "wazuh": {
        "space": { "name": "test" },
        "protocol": { "location": "/var/log/cassandra/system.log", "queue": 1 },
        "integration": {
          "decoders": ["decoder/cassandra-default/0"],
          "name": "my-integration",
          "category": "other"
        }
      },
      "message": "Some message",
      "event": {
        "duration": 7500,
        "category": ["database"],
        "kind": "event",
        "severity": 4
      },
      "source": { "ip": "10.42.3.15" },
      "process": {
        "thread": { "name": "CompactionExecutor-3" }
      }
    },
    "asset_traces": [],
    "validation": {
      "valid": true,
      "errors": []
    }
  }
}

Response Fields

FieldTypeDescription
message.outputObjectEngine normalized event output
message.asset_tracesArrayList of decoders that processed the event
message.validationObjectValidation result (valid, errors)

Status Codes

CodeDescription
200Normalization executed successfully
400Missing/invalid fields
500Engine socket communication error or internal error

Detection Only

Evaluates an already-normalized event against the Sigma rules of a given integration via the Security Analytics Plugin (SAP). This endpoint does not call the Wazuh Engine — the normalized event must be provided directly in the input field.

Use this after obtaining a normalized event from the /logtest/normalization endpoint, or when you already have a normalized event and want to test different integrations’ rules against it.

Note: The integration must exist in the specified space. The input field must be a JSON object (the normalized event), not a raw log string.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/logtest/detection

Request Body

FieldTypeRequiredDescription
spaceStringYes"test" or "standard"
integrationStringYesUUID of the integration whose rules to evaluate
inputObjectYesNormalized event object to evaluate rules against

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/logtest/detection" \
  -H 'Content-Type: application/json' \
  -d '{
    "space": "test",
    "integration": "d3f3b0b8-4e25-4273-83ef-56a62003bcf7",
    "input": {
      "event": {
        "duration": 7500,
        "category": ["database"],
        "kind": "event",
        "severity": 4,
        "type": ["info"]
      },
      "source": { "ip": "10.42.3.15" },
      "process": {
        "thread": { "name": "CompactionExecutor-3" },
        "command_line": "/query tables"
      },
      "log": {
        "origin": {
          "file": { "name": "CassandraDaemon.java", "line": 250 }
        }
      }
    }
  }'

Example Response (matches found)

{
  "status": 200,
  "message": {
    "status": "success",
    "rules_evaluated": 12,
    "rules_matched": 6,
    "matches": [
      {
        "rule": {
          "id": "4e52f215-bccc-4c0f-a37c-70606022be8e",
          "title": "TEST: Numeric gte+lt only",
          "level": "high",
          "tags": ["attack.execution", "attack.t1059"]
        },
        "matched_conditions": [
          "event.duration matched '>= 5000'",
          "event.severity matched '< 10'"
        ]
      },
      {
        "rule": {
          "id": "1d489ded-7523-4329-8cd0-ebb21865a318",
          "title": "TEST: Exact match event.kind=event",
          "level": "low",
          "tags": ["attack.execution", "attack.t1059"]
        },
        "matched_conditions": [
          "event.kind matched 'event'"
        ]
      }
    ]
  }
}

Example Response (no rules in integration)

{
  "status": 200,
  "message": {
    "status": "success",
    "rules_evaluated": 0,
    "rules_matched": 0,
    "matches": []
  }
}

Response Fields

FieldTypeDescription
message.statusString"success" or "error"
message.rules_evaluatedIntegerNumber of Sigma rules evaluated
message.rules_matchedIntegerNumber of rules that matched
message.matchesArrayList of matched rules with details
message.matches[].ruleObjectRule metadata: id, title, level, tags
message.matches[].matched_conditionsArrayHuman-readable descriptions of matched conditions

Status Codes

CodeDescription
200Detection executed (check message.status)
400Missing/invalid fields or integration not found
500Internal error

Policy

Update Policy

Updates the routing policy in the specified space. The policy defines which integrations are active, the root decoder, enrichment types, and how events are routed through the Engine.

Note: The integrations and filters arrays allow reordering but do not allow adding or removing entries — membership is managed via their respective CRUD endpoints.

Space-specific behavior

  • Draft space (/policy/draft): All policy fields are accepted. The metadata fields author, description, documentation, and references are required in addition to the boolean fields.
  • Standard space (/policy/standard): Only enrichments, filters, enabled, index_unclassified_events, and index_discarded_events can be modified. All other fields are preserved from the existing standard policy document. If the update changes the space hash, the full standard policy is automatically loaded to the local Engine.

Request

  • Method: PUT
  • Path: /_plugins/_content_manager/policy/{space}

Path Parameters

ParameterTypeRequiredDescription
spaceStringYesTarget space (draft or standard)

Request Body

FieldTypeRequiredDescription
resourceObjectYesThe policy resource object

Fields within resource:

FieldTypeRequiredDescription
metadataObjectYes (draft)Policy metadata (see below)
root_decoderStringNoIdentifier of the root decoder for event processing
integrationsArrayNoList of integration IDs (reorder only, no add/remove)
filtersArrayNoList of filter UUIDs (reorder only, no add/remove)
enrichmentsArrayNoEnrichment types (no duplicates; values depend on engine capabilities)
enabledBooleanYesWhether the policy is active and synchronized by the Engine
index_unclassified_eventsBooleanYesWhether uncategorized events are indexed
index_discarded_eventsBooleanYesWhether discarded events are indexed

Fields within resource.metadata:

FieldTypeRequiredDescription
titleStringNoHuman-readable policy name
authorStringYes (draft)Author of the policy
descriptionStringYes (draft)Brief description
documentationStringYes (draft)Documentation text or URL
referencesArrayYes (draft)External reference URLs

Example Request (draft space)

curl -sk -u admin:admin -X PUT \
  "https://192.168.56.6:9200/_plugins/_content_manager/policy/draft" \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": {
      "metadata": {
        "title": "Draft policy",
        "author": "Wazuh Inc.",
        "description": "Custom policy",
        "documentation": "",
        "references": [
          "https://wazuh.com"
        ]
      },
      "root_decoder": "",
      "integrations": [
        "f16f33ec-a5ea-4dc4-bf33-616b1562323a"
      ],
      "filters": [],
      "enrichments": [],
      "enabled": true,
      "index_unclassified_events": false,
      "index_discarded_events": false
    }
  }'

Example Request (standard space)

curl -sk -u admin:admin -X PUT \
  "https://192.168.56.6:9200/_plugins/_content_manager/policy/standard" \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": {
      "enrichments": ["connection"],
      "filters": [],
      "enabled": true,
      "index_unclassified_events": false,
      "index_discarded_events": false
    }
  }'

Example Response

{
  "message": "kQPmV5wBi_TgruUn97RT",
  "status": 200
}

The message field contains the OpenSearch document ID of the updated policy.

Status Codes

CodeDescription
200Policy updated
400Invalid space, missing resource field, missing required fields, invalid enrichments, or disallowed modification of integrations/filters
500Internal error

Rules

Rules follow the Sigma format with Wazuh extensions. See Sigma Rules for the full format reference, including the mitre, compliance, and metadata blocks.

Validation notes:

  • The logsource.product field must exactly match the metadata.title of the parent integration.
  • Detection fields are validated against the Wazuh Common Schema (WCS); rules referencing unknown fields are rejected.
  • IPv6 addresses are supported in detection conditions (standard, compressed, and CIDR notation).

Create Rule

Creates a new detection rule in the draft space. The rule is linked to the specified parent integration and validated by the Security Analytics Plugin.

The rule is also synchronized to the SAP, where a separate document is created with its own auto-generated UUID. The SAP document stores the CTI document UUID in a document.id field and the space in a source field (e.g., “Draft”) for cross-reference.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/rules

Request Body

FieldTypeRequiredDescription
integrationStringYesUUID of the parent integration (must be in draft space)
resourceObjectYesThe rule definition

Fields within resource:

FieldTypeRequiredDescription
metadataObjectYesRule metadata (see below)
sigma_idStringNoSigma rule ID
enabledBooleanNoWhether the rule is enabled
statusStringYesRule status (e.g., experimental, stable)
levelStringYesAlert level (e.g., low, medium, high, critical)
logsourceObjectNoLog source definition (product, category)
detectionObjectYesSigma detection logic with condition and selection fields
mitreObjectNoMITRE ATT&CK mapping (see Sigma Rules)
complianceObjectNoCompliance framework mapping (see Sigma Rules)

Fields within resource.metadata:

FieldTypeRequiredDescription
titleStringYesRule title (must be unique within the draft space)
authorStringNoRule author
descriptionStringNoRule description
referencesArrayNoReference URLs
documentationStringNoDocumentation text or URL

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/rules" \
  -H 'Content-Type: application/json' \
  -d '{
    "integration": "6b7b7645-00da-44d0-a74b-cffa7911e89c",
    "resource": {
      "metadata": {
        "title": "Test Rule",
        "description": "A Test rule",
        "author": "Tester",
        "references": [
          "https://wazuh.com"
        ]
      },
      "sigma_id": "19aefed0-ffd4-47dc-a7fc-f8b1425e84f9",
      "enabled": true,
      "status": "experimental",
      "logsource": {
        "product": "system",
        "category": "system"
      },
      "detection": {
        "condition": "selection",
        "selection": {
          "event.action": [
            "hash_test_event"
          ]
        }
      },
      "level": "low",
      "mitre": {
        "tactic": ["TA0001"],
        "technique": ["T1190"],
        "subtechnique": []
      },
      "compliance": {
        "pci_dss": ["6.5.1"]
      }
    }
  }'

Example Response

{
  "message": "6e1c43f1-f09b-4cec-bb59-00e3a52b7930",
  "status": 201
}

The message field contains the UUID of the created rule.

Status Codes

CodeDescription
201Rule created
400Missing fields, duplicate title, integration not in draft space, or validation failure
500Internal error or SAP unavailable

Update Rule

Updates an existing rule in the draft space.

Request

  • Method: PUT
  • Path: /_plugins/_content_manager/rules/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesRule document ID

Request Body

FieldTypeRequiredDescription
resourceObjectYesUpdated rule definition (same fields as create)

Note: On update, enabled, metadata.title, and metadata.author are required. The detection and logsource fields are also required.

Example Request

curl -sk -u admin:admin -X PUT \
  "https://192.168.56.6:9200/_plugins/_content_manager/rules/6e1c43f1-f09b-4cec-bb59-00e3a52b7930" \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": {
      "metadata": {
        "title": "Test Hash Generation Rule",
        "description": "A rule to verify that SHA-256 hashes are calculated correctly upon creation.",
        "author": "Tester"
      },
      "enabled": true,
      "status": "experimental",
      "logsource": {
        "product": "system",
        "category": "system"
      },
      "detection": {
        "condition": "selection",
        "selection": {
          "event.action": [
            "hash_test_event"
          ]
        }
      },
      "level": "low"
    }
  }'

Example Response

{
  "message": "6e1c43f1-f09b-4cec-bb59-00e3a52b7930",
  "status": 200
}

Status Codes

CodeDescription
200Rule updated
400Invalid request, not in draft space, or validation failure
404Rule not found
500Internal error

Delete Rule

Deletes a rule from the draft space. The rule is also removed from any integrations that reference it.

Request

  • Method: DELETE
  • Path: /_plugins/_content_manager/rules/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesRule document ID

Example Request

curl -sk -u admin:admin -X DELETE \
  "https://192.168.56.6:9200/_plugins/_content_manager/rules/6e1c43f1-f09b-4cec-bb59-00e3a52b7930"

Example Response

{
  "message": "6e1c43f1-f09b-4cec-bb59-00e3a52b7930",
  "status": 200
}

Status Codes

CodeDescription
200Rule deleted
404Rule not found
500Internal error

Decoders

Create Decoder

Creates a new log decoder in the draft space. The decoder is validated against the Wazuh Engine before being stored, and automatically linked to the specified integration.

Note: A testing policy must be loaded in the Engine for decoder validation to succeed.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/decoders

Request Body

FieldTypeRequiredDescription
integrationStringYesUUID of the parent integration (must be in draft space)
resourceObjectYesThe decoder definition

Fields within resource:

FieldTypeDescription
nameStringDecoder name identifier (e.g., decoder/core-wazuh-message/0)
enabledBooleanWhether the decoder is enabled
checkArrayDecoder check logic — array of condition objects
normalizeArrayNormalization rules — array of mapping objects
metadataObjectDecoder metadata (see below)

Fields within metadata:

FieldTypeDescription
titleStringHuman-readable decoder title
descriptionStringDecoder description
moduleStringModule name
compatibilityStringCompatibility description
authorObjectAuthor info (name, email, url)
referencesArrayReference URLs
versionsArraySupported versions

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/decoders" \
  -H 'Content-Type: application/json' \
  -d '{
    "integration": "0aa4fc6f-1cfd-4a7c-b30b-643f32950f1f",
    "resource": {
      "enabled": true,
      "metadata": {
        "author": {
          "name": "Wazuh, Inc."
        },
        "compatibility": "All wazuh events.",
        "description": "Base decoder to process Wazuh message format.",
        "module": "wazuh",
        "references": [
          "https://documentation.wazuh.com/"
        ],
        "title": "Wazuh message decoder",
        "versions": [
          "Wazuh 5.*"
        ]
      },
      "name": "decoder/core-wazuh-message/0",
      "check": [
        {
          "tmp_json.event.action": "string_equal(\"netflow_flow\")"
        }
      ],
      "normalize": [
        {
          "map": [
            {
              "@timestamp": "get_date()"
            }
          ]
        }
      ]
    }
  }'

Example Response

{
  "message": "d_0a6aaebe-dd0b-44cc-a787-ffefd4aac175",
  "status": 201
}

The message field contains the UUID of the created decoder (prefixed with d_).

Example Request (YAML)

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/decoders" \
  -H 'Content-Type: application/yaml' \
  --data-binary '---
integration: 0aa4fc6f-1cfd-4a7c-b30b-643f32950f1f
resource:
  enabled: true
  metadata:
    author:
      name: "Wazuh, Inc."
    compatibility: "All wazuh events."
    description: "Base decoder to process Wazuh message format."
    module: wazuh
    references:
      - "https://documentation.wazuh.com/"
    title: "Wazuh message decoder"
    versions:
      - "Wazuh 5.*"
  name: decoder/core-wazuh-message/0
  check:
    - tmp_json.event.action: "string_equal(\"netflow_flow\")"
  normalize:
    - map:
        - "@timestamp": "get_date()"
'

Note: See YAML Content-Type Support for details on the YAML envelope format and type fidelity.

Status Codes

CodeDescription
201Decoder created
400Missing integration field, integration not in draft space, or Engine validation failure
500Engine unavailable or internal error

Update Decoder

Updates an existing decoder in the draft space. The decoder is re-validated against the Wazuh Engine.

Request

  • Method: PUT
  • Path: /_plugins/_content_manager/decoders/{id}

Parameters

NameInTypeRequiredDescription
idPathStringYesDecoder document ID

Request Body

FieldTypeRequiredDescription
resourceObjectYesUpdated decoder definition (same fields as create)

Example Request

curl -sk -u admin:admin -X PUT \
  "https://192.168.56.6:9200/_plugins/_content_manager/decoders/bb6d0245-8c1d-42d1-8edb-4e0907cf45e0" \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": {
      "name": "decoder/test-decoder/0",
      "enabled": false,
      "metadata": {
        "title": "Test Decoder UPDATED",
        "description": "Updated description",
        "author": {
          "name": "Hello there"
        }
      },
      "check": [],
      "normalize": []
    }
  }'

Example Response

{
  "message": "bb6d0245-8c1d-42d1-8edb-4e0907cf45e0",
  "status": 200
}

Status Codes

CodeDescription
200Decoder updated
400Invalid request, not in draft space, or Engine validation failure
404Decoder not found
500Internal error

Delete Decoder

Deletes a decoder from the draft space. The decoder is also removed from any integrations that reference it. A decoder cannot be deleted if it is currently set as the root decoder in the draft policy.

Request

  • Method: DELETE
  • Path: /_plugins/_content_manager/decoders/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesDecoder document ID

Example Request

curl -sk -u admin:admin -X DELETE \
  "https://192.168.56.6:9200/_plugins/_content_manager/decoders/acbdba85-09c4-45a0-a487-61c8eeec58e6"

Example Response

{
  "message": "acbdba85-09c4-45a0-a487-61c8eeec58e6",
  "status": 200
}

Example Response (set as root decoder)

{
  "message": "Cannot remove decoder [acbdba85-09c4-45a0-a487-61c8eeec58e6] as it is set as root decoder.",
  "status": 400
}

Status Codes

CodeDescription
200Decoder deleted
400Decoder is set as root decoder
404Decoder not found
500Internal error

Filters

Create Filter

Creates a new filter in the draft or standard space. The filter is validated against the Wazuh Engine before being stored and automatically linked to the specified space’s policy.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/filters

Request Body

FieldTypeRequiredDescription
spaceStringYesTarget space: draft or standard
resourceObjectYesThe filter definition

Fields within resource:

FieldTypeDescription
nameStringFilter name identifier (e.g., filter/prefilter/0)
enabledBooleanWhether the filter is enabled
checkStringFilter check expression
typeStringFilter type (e.g., pre-filter)
metadataObjectFilter metadata (see below)

Fields within metadata:

FieldTypeDescription
descriptionStringFilter description
authorObjectAuthor info (name, email, url)

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/filters" \
  -H 'Content-Type: application/json' \
  -d '{
    "space": "draft",
    "resource": {
      "name": "filter/prefilter/0",
      "enabled": true,
      "metadata": {
        "description": "Default filter to allow all events (for default ruleset)",
        "author": {
          "email": "info@wazuh.com",
          "name": "Wazuh, Inc.",
          "url": "https://wazuh.com"
        }
      },
      "check": "$host.os.platform == '\''ubuntu'\''",
      "type": "pre-filter"
    }
  }'

Example Response

{
  "message": "f_a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6",
  "status": 201
}

The message field contains the UUID of the created filter (prefixed with f_).

Example Request (YAML)

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/filters" \
  -H 'Content-Type: application/yaml' \
  --data-binary '---
space: draft
resource:
  name: filter/prefilter/0
  enabled: true
  metadata:
    description: "Default filter to allow all events (for default ruleset)"
    author:
      email: info@wazuh.com
      name: "Wazuh, Inc."
      url: "https://wazuh.com"
  check: "$host.os.platform == '\''ubuntu'\''"
  type: pre-filter
'

Note: See YAML Content-Type Support for details on the YAML envelope format and type fidelity.

Status Codes

CodeDescription
201Filter created
400Missing space field, invalid space, or Engine validation failure
500Engine unavailable or internal error

Update Filter

Updates an existing filter in the draft or standard space. The filter is re-validated against the Wazuh Engine.

Request

  • Method: PUT
  • Path: /_plugins/_content_manager/filters/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesFilter document ID

Request Body

FieldTypeRequiredDescription
spaceStringYesTarget space: draft or standard
resourceObjectYesUpdated filter definition (same fields as create)

Example Request

curl -sk -u admin:admin -X PUT \
  "https://192.168.56.6:9200/_plugins/_content_manager/filters/a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6" \
  -H 'Content-Type: application/json' \
  -d '{
    "space": "draft",
    "resource": {
      "name": "filter/prefilter/0",
      "enabled": true,
      "metadata": {
        "description": "Updated filter description",
        "author": {
          "email": "info@wazuh.com",
          "name": "Wazuh, Inc.",
          "url": "https://wazuh.com"
        }
      },
      "check": "$host.os.platform == '\''ubuntu'\''",
      "type": "pre-filter"
    }
  }'

Example Response

{
  "message": "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6",
  "status": 200
}

Status Codes

CodeDescription
200Filter updated
400Invalid request, invalid space, or Engine validation failure
404Filter not found
500Internal error

Delete Filter

Deletes a filter from the draft or standard space. The filter is also removed from the associated policy.

Request

  • Method: DELETE
  • Path: /_plugins/_content_manager/filters/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesFilter document ID

Example Request

curl -sk -u admin:admin -X DELETE \
  "https://192.168.56.6:9200/_plugins/_content_manager/filters/a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6"

Example Response

{
  "message": "a1b2c3d4-e5f6-47a8-b9c0-d1e2f3a4b5c6",
  "status": 200
}

Status Codes

CodeDescription
200Filter deleted
404Filter not found
500Internal error

Integrations

Create Integration

Creates a new integration in the draft space. An integration is a logical grouping of related rules, decoders, and KVDBs. The integration is validated against the Engine and registered in the Security Analytics Plugin.

The integration is also synchronized to the SAP, where a separate document is created with its own auto-generated UUID. The SAP document stores the CTI document UUID in a document.id field and the space in a source field (e.g., “Draft”) for cross-reference.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/integrations

Request Body

FieldTypeRequiredDescription
resourceObjectYesThe integration definition

Fields within resource:

FieldTypeRequiredDescription
metadataObjectYesIntegration metadata (see below)
categoryStringYesCategory (e.g., cloud-services, network-activity, security, system-activity)
enabledBooleanNoWhether the integration is enabled

Fields within resource.metadata:

FieldTypeRequiredDescription
titleStringYesIntegration title (must be unique in draft space)
authorStringYesAuthor of the integration
descriptionStringNoDescription
documentationStringNoDocumentation text or URL
referencesArrayNoReference URLs

Note: Do not include the id field — it is auto-generated by the Indexer.

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/integrations" \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": {
      "metadata": {
        "title": "azure-functions",
        "author": "Wazuh Inc.",
        "description": "This integration supports Azure Functions app logs.",
        "documentation": "https://docs.wazuh.com/integrations/azure-functions",
        "references": [
          "https://wazuh.com"
        ]
      },
      "category": "cloud-services",
      "enabled": true
    }
  }'

Example Response

{
  "message": "94e5a2af-505e-4164-ab62-576a71873308",
  "status": 201
}

The message field contains the UUID of the created integration.

Status Codes

CodeDescription
201Integration created
400Missing required fields (title, author, category), duplicate title, or validation failure
500Internal error or SAP/Engine unavailable

Update Integration

Updates an existing integration in the draft space. Only integrations in the draft space can be updated.

Request

  • Method: PUT
  • Path: /_plugins/_content_manager/integrations/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesIntegration document ID

Request Body

FieldTypeRequiredDescription
resourceObjectYesUpdated integration definition

Fields within resource (all required for update):

FieldTypeRequiredDescription
metadataObjectYesIntegration metadata (see below)
categoryStringYesCategory
enabledBooleanYesWhether the integration is enabled
rulesArrayYesOrdered list of rule IDs
decodersArrayYesOrdered list of decoder IDs
kvdbsArrayYesOrdered list of KVDB IDs

Fields within resource.metadata:

FieldTypeRequiredDescription
titleStringYesIntegration title
authorStringYesAuthor
descriptionStringYesDescription
documentationStringYesDocumentation text or URL
referencesArrayYesReference URLs

Note: The rules, decoders, and kvdbs arrays are mandatory on update to allow reordering. Pass empty arrays [] if the integration has none.

Example Request

curl -sk -u admin:admin -X PUT \
  "https://192.168.56.6:9200/_plugins/_content_manager/integrations/94e5a2af-505e-4164-ab62-576a71873308" \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": {
      "metadata": {
        "title": "azure-functions-update",
        "author": "Wazuh Inc.",
        "description": "This integration supports Azure Functions app logs.",
        "documentation": "updated documentation",
        "references": []
      },
      "category": "cloud-services",
      "enabled": true,
      "rules": [],
      "decoders": [],
      "kvdbs": []
    }
  }'

Example Response

{
  "message": "94e5a2af-505e-4164-ab62-576a71873308",
  "status": 200
}

Status Codes

CodeDescription
200Integration updated
400Invalid request, missing required fields, not in draft space, or duplicate title
404Integration not found
500Internal error

Delete Integration

Deletes an integration from the draft space. The integration must have no attached decoders, rules, or KVDBs — delete those first.

Request

  • Method: DELETE
  • Path: /_plugins/_content_manager/integrations/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesIntegration document ID

Example Request

curl -sk -u admin:admin -X DELETE \
  "https://192.168.56.6:9200/_plugins/_content_manager/integrations/94e5a2af-505e-4164-ab62-576a71873308"

Example Response

{
  "message": "94e5a2af-505e-4164-ab62-576a71873308",
  "status": 200
}

Example Response (has dependencies)

{
  "message": "Cannot delete integration because it has decoders attached",
  "status": 400
}

Status Codes

CodeDescription
200Integration deleted
400Integration has dependent resources (decoders/rules/kvdbs)
404Integration not found
500Internal error

KVDBs

Create KVDB

Creates a new key-value database in the draft space, linked to the specified integration.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/kvdbs

Request Body

FieldTypeRequiredDescription
integrationStringYesUUID of the parent integration (must be in draft space)
resourceObjectYesThe KVDB definition

Fields within resource:

FieldTypeRequiredDescription
metadataObjectYesKVDB metadata (see below)
contentObjectYesKey-value data (at least one entry required)
nameStringNoKVDB identifier name
enabledBooleanNoWhether the KVDB is enabled

Fields within resource.metadata:

FieldTypeRequiredDescription
titleStringYesKVDB title
authorStringYesAuthor
descriptionStringNoDescription
documentationStringNoDocumentation
referencesArrayNoReference URLs

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/kvdbs" \
  -H 'Content-Type: application/json' \
  -d '{
    "integration": "f16f33ec-a5ea-4dc4-bf33-616b1562323a",
    "resource": {
      "metadata": {
        "title": "non_standard_timezones",
        "author": "Wazuh Inc.",
        "description": "",
        "documentation": "",
        "references": [
          "https://wazuh.com"
        ]
      },
      "name": "non_standard_timezones",
      "enabled": true,
      "content": {
        "non_standard_timezones": {
          "AEST": "Australia/Sydney",
          "CEST": "Europe/Berlin",
          "CST": "America/Chicago",
          "EDT": "America/New_York",
          "EST": "America/New_York",
          "IST": "Asia/Kolkata",
          "MST": "America/Denver",
          "PKT": "Asia/Karachi",
          "SST": "Asia/Singapore",
          "WEST": "Europe/London"
        }
      }
    }
  }'

Example Response

{
  "message": "9d4ec6d5-8e30-4ea3-be05-957968c02dae",
  "status": 201
}

The message field contains the UUID of the created KVDB.

Example Request (YAML)

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/kvdbs" \
  -H 'Content-Type: application/yaml' \
  --data-binary '---
integration: f16f33ec-a5ea-4dc4-bf33-616b1562323a
resource:
  metadata:
    title: non_standard_timezones
    author: "Wazuh Inc."
    description: ""
    documentation: ""
    references:
      - "https://wazuh.com"
  name: non_standard_timezones
  enabled: true
  content:
    non_standard_timezones:
      AEST: Australia/Sydney
      CEST: Europe/Berlin
      CST: America/Chicago
      EDT: America/New_York
      EST: America/New_York
      IST: Asia/Kolkata
      MST: America/Denver
      PKT: Asia/Karachi
      SST: Asia/Singapore
      WEST: Europe/London
'

Note: See YAML Content-Type Support for details on the YAML envelope format and type fidelity.

Status Codes

CodeDescription
201KVDB created
400Missing integration or required resource fields, integration not in draft space
500Internal error

Update KVDB

Updates an existing KVDB in the draft space.

Request

  • Method: PUT
  • Path: /_plugins/_content_manager/kvdbs/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesKVDB document ID

Request Body

FieldTypeRequiredDescription
resourceObjectYesUpdated KVDB definition

Fields within resource (all required for update):

FieldTypeRequiredDescription
metadataObjectYesKVDB metadata (see below)
contentObjectYesKey-value data
nameStringNoKVDB identifier name
enabledBooleanNoWhether the KVDB is enabled

Fields within resource.metadata:

FieldTypeRequiredDescription
titleStringYesKVDB title
authorStringYesAuthor
descriptionStringYesDescription
documentationStringYesDocumentation
referencesArrayYesReference URLs

Example Request

curl -sk -u admin:admin -X PUT \
  "https://192.168.56.6:9200/_plugins/_content_manager/kvdbs/9d4ec6d5-8e30-4ea3-be05-957968c02dae" \
  -H 'Content-Type: application/json' \
  -d '{
    "resource": {
      "metadata": {
        "title": "non_standard_timezones-2",
        "author": "Wazuh.",
        "description": "UPDATE",
        "documentation": "UPDATE.doc",
        "references": [
          "https://wazuh.com"
        ]
      },
      "name": "test-UPDATED",
      "enabled": true,
      "content": {
        "non_standard_timezones": {
          "AEST": "Australia/Sydney",
          "CEST": "Europe/Berlin",
          "CST": "America/Chicago",
          "EDT": "America/New_York",
          "EST": "America/New_York",
          "IST": "Asia/Kolkata",
          "MST": "America/Denver",
          "PKT": "Asia/Karachi",
          "SST": "Asia/Singapore",
          "WEST": "Europe/London"
        }
      }
    }
  }'

Example Response

{
  "message": "9d4ec6d5-8e30-4ea3-be05-957968c02dae",
  "status": 200
}

Status Codes

CodeDescription
200KVDB updated
400Invalid request, missing required fields, or not in draft space
404KVDB not found
500Internal error

Delete KVDB

Deletes a KVDB from the draft space. The KVDB is also removed from any integrations that reference it.

Request

  • Method: DELETE
  • Path: /_plugins/_content_manager/kvdbs/{id}

Parameters

NameInTypeRequiredDescription
idPathString (UUID)YesKVDB document ID

Example Request

curl -sk -u admin:admin -X DELETE \
  "https://192.168.56.6:9200/_plugins/_content_manager/kvdbs/9d4ec6d5-8e30-4ea3-be05-957968c02dae"

Example Response

{
  "message": "9d4ec6d5-8e30-4ea3-be05-957968c02dae",
  "status": 200
}

Status Codes

CodeDescription
200KVDB deleted
404KVDB not found
500Internal error

Promotion

Preview Promotion Changes

Returns a preview of changes that would be applied when promoting from the specified space. This is a dry-run operation that does not modify any content.

Request

  • Method: GET
  • Path: /_plugins/_content_manager/promote

Parameters

NameInTypeRequiredDescription
spaceQueryStringYesSource space to preview: draft or test

Example Request

curl -sk -u admin:admin \
  "https://192.168.56.6:9200/_plugins/_content_manager/promote?space=draft"

Example Response

{
  "changes": {
    "kvdbs": [
      {
        "operation": "add",
        "id": "4441d331-847a-43ed-acc6-4e09d8d6abb9"
      }
    ],
    "rules": [],
    "decoders": [],
    "filters": [],
    "integrations": [
      {
        "operation": "add",
        "id": "f16f33ec-a5ea-4dc4-bf33-616b1562323a"
      }
    ],
    "policy": [
      {
        "operation": "update",
        "id": "f75bda3d-1926-4a8d-9c75-66382109ab04"
      }
    ]
  }
}

The response lists changes grouped by content type. Each change includes:

  • operation: add, update, or remove
  • id: Document ID of the affected resource

Status Codes

CodeDescription
200Preview returned successfully
400Invalid or missing space parameter
500Internal error

Execute Promotion

Promotes content from the source space to the next space in the promotion chain (Draft → Test → Custom). The request body must include the source space and the changes to apply (typically obtained from the preview endpoint).

For Draft → Test promotions, the changeset is forwarded to the local Wazuh Engine for validation only when it includes decoders, kvdbs, or filters. Promotions limited to integrations, rules, or the policy skip the engine call entirely. Test → Custom promotions never invoke the engine.

In addition to copying documents across CTI indices, promotion also synchronizes integrations and rules with the Security Analytics Plugin (SAP). For each promoted resource, a new SAP document is created in the target space with:

  • A newly generated UUID as the SAP document primary ID.
  • A document.id field storing the original CTI document UUID for cross-reference.
  • A source field indicating the target space (e.g., “Test”, “Custom”).

New resources (ADD operations) use POST to create SAP documents; existing resources (UPDATE operations) use PUT to update them in-place.

This ensures that the same CTI resource can exist in multiple spaces with independent SAP documents.

Rollback on Failure

If any Content Manager index mutation fails during the consolidation phase, the endpoint automatically performs a LIFO rollback to restore the system to its pre-promotion state:

  1. Pre-promotion snapshots are captured before any writes — old versions for adds/updates, full documents for deletes.
  2. CM rollback: Each completed mutation is undone in reverse order. ADDs are deleted, UPDATEs are restored to their previous version, DELETEs are re-indexed from the snapshot.
  3. SAP reconciliation (best-effort): Rules and integrations synced to SAP during the forward pass are reverted — new SAP documents are deleted, updated ones are restored, and deleted ones are re-created from snapshots.

Individual rollback or SAP reconciliation step failures are logged but do not prevent remaining steps from executing. On rollback, the endpoint returns a 500 status.

Request

  • Method: POST
  • Path: /_plugins/_content_manager/promote

Request Body

FieldTypeRequiredDescription
spaceStringYesSource space: draft or test
changesObjectYesChanges to promote (from preview response)

The changes object contains arrays for each content type (policy, integrations, kvdbs, decoders, rules, filters), each with operation and id fields.

Example Request

curl -sk -u admin:admin -X POST \
  "https://192.168.56.6:9200/_plugins/_content_manager/promote" \
  -H 'Content-Type: application/json' \
  -d '{
    "space": "draft",
    "changes": {
      "kvdbs": [],
      "decoders": [
        {
          "operation": "add",
          "id": "f56f3865-2827-464b-8335-30561b0f381b"
        }
      ],
      "rules": [],
      "filters": [],
      "integrations": [
        {
          "operation": "add",
          "id": "0aa4fc6f-1cfd-4a7c-b30b-643f32950f1f"
        }
      ],
      "policy": [
        {
          "operation": "update",
          "id": "baf9b03f-5872-4409-ab02-507b7f93d0c8"
        }
      ]
    }
  }'

Example Response

{
  "message": "Promotion completed successfully",
  "status": 200
}

Status Codes

CodeDescription
200Promotion successful
400Invalid request body or missing space field
500Engine communication error or validation failure

Spaces

Reset Space

Resets a user space (draft) to its initial state.

When resetting the draft space, this operation will:

  • Remove all documents (integrations, rules, decoders, kvdbs) that belong to the given space.
  • Re-generate the default policy for the given space.

Note: Only draft space can be reset.

Request

  • Method: DELETE
  • Path: /_plugins/_content_manager/space/{space}

Parameters

NameInTypeRequiredDescription
spacePathStringYesThe name of the user space to reset (draft)

Example Request

curl -sk -u admin:admin -X DELETE \
  "https://192.168.56.6:9200/_plugins/_content_manager/space/draft"

Example Response

{
  "message": "Space reset successfully",
  "status": 200
}

Status Codes

CodeDescription
200Space reset successfully
400Invalid space identifier, or attempted to reset a space different from draft
500Internal error (e.g., Engine unavailable or deletion failure)

Version Check

Check Available Updates

Returns whether there are newer versions of Wazuh available for download. The endpoint reads the current installed version from VERSION.json and queries the CTI API for available updates. The response includes the latest available major, minor, and patch updates when available.

Request

  • Method: GET
  • Path: /_plugins/_content_manager/version/check

Example Request

curl -sk -u admin:admin \
  "https://192.168.56.6:9200/_plugins/_content_manager/version/check"

Example Response (updates available)

{
  "message": {
    "uuid": "bd7f0db0-d094-48ca-b883-7019484ce71f",
    "last_check_date": "2026-04-14T15:28:41.347387+00:00",
    "current_version": "v5.0.0",
    "last_available_major": {
      "tag": "v6.0.0",
      "title": "Wazuh v6.0.0",
      "description": "Major release with new features...",
      "published_date": "2026-03-01T10:00:00Z",
      "semver": { "major": 6, "minor": 0, "patch": 0 }
    },
    "last_available_minor": {
      "tag": "v5.1.0",
      "title": "Wazuh v5.1.0",
      "description": "Minor improvements and enhancements...",
      "published_date": "2026-02-15T10:00:00Z",
      "semver": { "major": 5, "minor": 1, "patch": 0 }
    },
    "last_available_patch": {
      "tag": "v5.0.1",
      "title": "Wazuh v5.0.1",
      "description": "Bug fixes and stability improvements...",
      "published_date": "2026-01-20T10:00:00Z",
      "semver": { "major": 5, "minor": 0, "patch": 1 }
    }
  },
  "status": 200
}

Example Response (no updates)

{
  "message": {
    "uuid": "bd7f0db0-d094-48ca-b883-7019484ce71f",
    "last_check_date": "2026-04-14T15:28:41.347387+00:00",
    "current_version": "v5.0.0",
    "last_available_major": {},
    "last_available_minor": {},
    "last_available_patch": {}
  },
  "status": 200
}

Example Response (version not found)

{
  "message": "Unable to determine current Wazuh version.",
  "status": 500
}

Status Codes

CodeDescription
200Version check completed (may include updates or empty)
500Unable to determine version or internal error
502CTI API returned an error

Note: Categories with no available updates are represented as empty objects {}.


Documentation Maintenance

To maintain technical consistency, any modification, addition or removal
of endpoints in the REST API source code must be reflected in the openapi.yml
specification and this api.md reference guide.