Wazuh Server REST API - Authentication and Endpoints

The Wazuh REST API provides a programmatic interface for managing all platform components. The API operates over HTTPS on port 55000, authenticates via JWT tokens, and enforces role-based access control. Through the API you can manage agents, rules, decoders, groups, manager configuration, and cluster operations.

API Overview

Core Characteristics

ParameterValue
ProtocolHTTPS (TLS)
Default port55000
Data formatJSON
AuthenticationJWT (JSON Web Token)
AuthorizationRBAC (Role-Based Access Control)
HTTP methodsGET, POST, PUT, DELETE
Base URLhttps://<WAZUH_SERVER>:55000

Response Structure

All API responses follow a standardized format:

{
  "data": {
    "affected_items": [],
    "total_affected_items": 0,
    "failed_items": [],
    "total_failed_items": 0
  },
  "message": "Description of the result",
  "error": 0
}

Error codes in the error field:

  • 0 - operation completed successfully
  • 1 - operation failed
  • 2 - operation partially completed (some items processed, some failed)

Pagination Parameters

The API limits the number of returned records. The default maximum is 500 items. To retrieve more, use:

  • limit - maximum number of records per response
  • offset - offset from the beginning of the list
  • sort - sort results (e.g., +name or -id)

Authentication

Obtaining a JWT Token

Working with the API requires a JWT token obtained through the authentication endpoint using HTTP basic authentication:

TOKEN=$(curl -sk -u wazuh-wui:MyPassword \
  -X POST "https://localhost:55000/security/user/authenticate?raw=true")

The raw=true parameter returns the token in plain text without JSON wrapping.

Alternative approach with JSON response:

curl -sk -u wazuh-wui:MyPassword \
  -X POST "https://localhost:55000/security/user/authenticate" | jq -r '.data.token'

Using the Token

Include the token in the Authorization header of every request:

curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/?pretty=true"

Token Lifetime

JWT tokens have a limited lifetime configured in the API settings. When the token expires, a new one must be obtained. The default lifetime is 900 seconds (15 minutes).

Token Revocation

To forcibly end a session, use the revocation endpoint:

curl -sk -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://localhost:55000/security/user/authenticate"

Key Endpoint Groups

Agents

Agent management is one of the most frequently used API functions.

# List all agents
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/agents?pretty=true"

# List active agents with filtering
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/agents?status=active&limit=10&pretty=true"

# Information about a specific agent
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/agents?agents_list=001&pretty=true"

# Agent status summary
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/agents/summary/status?pretty=true"

# Restart an agent
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X PUT "https://localhost:55000/agents/001/restart?pretty=true"

# Upgrade an agent
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X PUT "https://localhost:55000/agents/001/upgrade?pretty=true"

# Delete an agent
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://localhost:55000/agents?agents_list=001&status=all&older_than=0s&pretty=true"

Rules

# List all rules
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/rules?pretty=true&limit=10"

# Get rule by ID
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/rules?rule_ids=100001&pretty=true"

# Rules by level
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/rules?level=12-15&pretty=true"

# Rules by group
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/rules?group=authentication_failed&pretty=true"

# List rule files
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/rules/files?pretty=true"

Decoders

# List all decoders
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/decoders?pretty=true&limit=10"

# Search decoder by name
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/decoders?search=sshd&pretty=true"

# List decoder files
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/decoders/files?pretty=true"

Manager

# Manager information
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/manager/info?pretty=true"

# Manager status
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/manager/status?pretty=true"

# Manager configuration
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/manager/configuration?pretty=true"

# Manager logs
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/manager/logs?pretty=true&limit=20"

# Restart manager
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X PUT "https://localhost:55000/manager/restart?pretty=true"

Cluster

# Cluster status
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/cluster/status?pretty=true"

# List cluster nodes
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/cluster/nodes?pretty=true"

# Information about a specific node
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/cluster/nodes/worker-01?pretty=true"

# Cluster configuration
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/cluster/configuration?pretty=true"

For details on cluster setup, see the Wazuh server cluster section.

Syscollector (Inventory)

# Agent hardware information
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/syscollector/001/hardware?pretty=true"

# Installed packages
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/syscollector/001/packages?pretty=true&limit=20"

# Network interfaces
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/syscollector/001/netiface?pretty=true"

# Open ports
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/syscollector/001/ports?pretty=true"

# Running processes
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/syscollector/001/processes?pretty=true&limit=20"

# OS information
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/syscollector/001/os?pretty=true"

Vulnerabilities

# Detected vulnerabilities for an agent
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/vulnerability/001?pretty=true"

# Filter by severity
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/vulnerability/001?severity=Critical&pretty=true"

SCA (Security Configuration Assessment)

# List SCA policies for an agent
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/sca/001?pretty=true"

# Check results for a specific policy
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/sca/001/checks/cis_ubuntu22-04?pretty=true"

For more on the SCA module, see Security Configuration Assessment .

Agent Groups

# List groups
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/groups?pretty=true"

# Create a group
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X POST "https://localhost:55000/groups?pretty=true" \
  -H "Content-Type: application/json" \
  -d '{"group_id":"web-servers"}'

# Assign agent to group
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X PUT "https://localhost:55000/agents/001/group/web-servers?pretty=true"

# Agents in a group
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/groups/web-servers/agents?pretty=true"

# Delete a group
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X DELETE "https://localhost:55000/groups?groups_list=web-servers&pretty=true"

API Configuration (api.yaml)

The API configuration is stored in /var/ossec/api/configuration/api.yaml.

Core Parameters

host: 0.0.0.0
port: 55000

https:
  enabled: true
  key: /var/ossec/api/configuration/ssl/server.key
  cert: /var/ossec/api/configuration/ssl/server.crt

logging:
  level: info
  path: /var/ossec/logs/api.log

cors:
  enabled: false
  source_route: "*"
  expose_headers: "*"
  allow_headers: "*"
  allow_credentials: false

access:
  max_login_attempts: 50
  block_time: 300
  max_request_per_minute: 300

behind_proxy_server: false

Configuration Parameter Reference

ParameterDescriptionDefault
hostIP address on which the API accepts connections0.0.0.0
portAPI TCP port55000
https.enabledEnable HTTPStrue
https.keyPath to TLS private key/var/ossec/api/configuration/ssl/server.key
https.certPath to TLS certificate/var/ossec/api/configuration/ssl/server.crt
logging.levelLog level (debug, info, warning, error)info
cors.enabledEnable CORS headersfalse
behind_proxy_serverRunning behind a reverse proxy (trust X-Forwarded-For header)false
access.max_login_attemptsMaximum login attempts before lockout50
access.block_timeLockout duration after exceeding attempts (seconds)300
access.max_request_per_minuteRequest rate limit per minute300

Restart the API after configuration changes:

systemctl restart wazuh-manager

RBAC - Role-Based Access Control

RBAC Architecture

The Wazuh API implements a multi-level access control system:

  • Users - accounts with JWT authentication
  • Roles - sets of policies assigned to users
  • Policies - access rules defining permitted actions
  • Security rules - dynamic role assignment based on conditions

RBAC Modes

  • White list (default) - everything is denied unless explicitly allowed
  • Black list - everything is allowed unless explicitly denied

User Management

# Create a user
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X POST "https://localhost:55000/security/users" \
  -H "Content-Type: application/json" \
  -d '{"username":"analyst","password":"Analyst_Pass1"}'

# List users
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/security/users?pretty=true"

# Assign role to user
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X POST "https://localhost:55000/security/users/analyst/roles?role_ids=2"

Role Management

# List roles
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/security/roles?pretty=true"

# Create a role
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X POST "https://localhost:55000/security/roles" \
  -H "Content-Type: application/json" \
  -d '{"name":"readonly_agents"}'

# Assign policy to role
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X POST "https://localhost:55000/security/roles/100/policies?policy_ids=1"

Policy Management

# List policies
curl -sk -H "Authorization: Bearer $TOKEN" \
  "https://localhost:55000/security/policies?pretty=true"

# Create a policy (allow reading agents)
curl -sk -H "Authorization: Bearer $TOKEN" \
  -X POST "https://localhost:55000/security/policies" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "read_agents",
    "policy": {
      "actions": ["agent:read"],
      "resources": ["agent:id:*"],
      "effect": "allow"
    }
  }'

Rate Limiting

The API limits request frequency to protect against abuse:

  • Maximum max_request_per_minute requests per minute (default 300)
  • Maximum max_login_attempts authentication attempts (default 50)
  • IP lockout for block_time seconds after exceeding the attempt limit

When the limit is exceeded, the API returns HTTP 429 (Too Many Requests).

Using the API from Dashboard Dev Tools

Wazuh Dashboard provides a built-in Dev Tools console for executing API requests without the command line. The console is accessible under Server management > Dev Tools.

Request format in Dev Tools:

GET /agents?status=active&limit=5

GET /manager/info

POST /security/user/authenticate

Dev Tools automatically handles authentication and the base URL.

Python Examples

Authentication and Agent Retrieval

import requests
import urllib3
from base64 import b64encode

urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)

WAZUH_API = "https://localhost:55000"
USER = "wazuh-wui"
PASSWORD = "MyPassword"


def get_token() -> str:
    """Obtain JWT token from Wazuh API."""
    auth_header = b64encode(f"{USER}:{PASSWORD}".encode()).decode()
    headers = {"Authorization": f"Basic {auth_header}"}
    response = requests.post(
        f"{WAZUH_API}/security/user/authenticate",
        headers=headers,
        verify=False,
    )
    response.raise_for_status()
    return response.json()["data"]["token"]


def get_active_agents(token: str) -> list[dict]:
    """Retrieve list of active agents."""
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(
        f"{WAZUH_API}/agents",
        headers=headers,
        params={"status": "active", "limit": 500},
        verify=False,
    )
    response.raise_for_status()
    return response.json()["data"]["affected_items"]


token = get_token()
agents = get_active_agents(token)
for agent in agents:
    print(f"Agent {agent['id']}: {agent['name']} ({agent['status']})")

Vulnerability Monitoring

def get_critical_vulnerabilities(token: str, agent_id: str) -> list[dict]:
    """Get critical vulnerabilities for a specific agent."""
    headers = {"Authorization": f"Bearer {token}"}
    response = requests.get(
        f"{WAZUH_API}/vulnerability/{agent_id}",
        headers=headers,
        params={"severity": "Critical", "limit": 100},
        verify=False,
    )
    response.raise_for_status()
    return response.json()["data"]["affected_items"]

Comparison with Other SIEM Platform APIs

FeatureWazuh APISplunk REST APIElastic Security APIQRadar API
ProtocolHTTPS (port 55000)HTTPS (port 8089)HTTPS (port 9200/5601)HTTPS (port 443)
AuthenticationJWT tokenSession key / Bearer tokenAPI key / Basic authSEC token
AuthorizationRBACCapabilitiesRBAC / SpacesUser roles
Response formatJSONJSON/XMLJSONJSON
DocumentationOpenAPI / ReDocREST API ReferenceOpenAPIInteractive
CostFreeCommercialFree (Basic) / CommercialCommercial
SDKPython (requests)splunk-sdkelasticsearch-pyPython SDK
Rate limitingConfigurableNot by defaultNot by defaultYes

Key Differences

Splunk REST API provides configuration access through namespace-based endpoints (/servicesNS/) with a hierarchical namespace structure. The Wazuh API uses a flat endpoint structure grouped by functionality.

Elastic Security API splits its API across Elasticsearch (indices, search) and Kibana (rules, alerts) layers. Wazuh consolidates all management functions into a single API.

QRadar API uses static authorization tokens that do not expire. Wazuh uses JWT with a limited lifetime, providing a higher level of security.

Troubleshooting

API Not Responding

Checks:

  1. Confirm the manager is running:
systemctl status wazuh-manager
  1. Verify the API is listening on the expected port:
ss -tlnp | grep 55000
  1. Review the API log:
tail -f /var/ossec/logs/api.log

Authentication Error (HTTP 401)

  • Verify that credentials are correct
  • Check whether the JWT token has expired (default lifetime is 15 minutes)
  • Obtain a new token through the authentication endpoint

Authorization Error (HTTP 403)

  • Review the roles and policies assigned to the user
  • Confirm that the policy allows the requested action and resource
  • Check the RBAC mode (white list / black list)

Rate Limit Exceeded (HTTP 429)

  • Reduce request frequency
  • Increase the max_request_per_minute parameter in api.yaml
  • Use limit and offset parameters to retrieve data in batches instead of multiple requests

TLS Certificate Errors

  • For self-signed certificates, add the -k flag in curl or verify=False in Python
  • For production environments, replace self-signed certificates with certificates from a trusted CA
  • Verify certificate paths in api.yaml

For a general infrastructure overview, see the Wazuh infrastructure section . Information on cluster interaction through the API is available in the server cluster section.

Last updated on