QRadar API
Authoritative QRadar REST API mechanics for real-world SIEM work: authentication, Ariel search orchestration, offense pulls, asset queries, and JSON shaping.
The QRadar REST API uses SEC header authentication, not Bearer token authentication.
This is non-standard and differs from most REST APIs.
Secrets are sourced via dsec d001 dev/network, which exports QRADAR_TOKEN and QRADAR_HOST into the shell environment.
All Ariel searches are asynchronous: submit, poll, fetch. There is no synchronous query path via the API.
Authentication Model
The SEC header is QRadar-specific. Do not substitute Authorization: Bearer; it will not authenticate.
|
Authorized Services are only visible to roles with full admin access. Read-only configuration roles cannot create tokens. If the option is not visible under the Admin tab, open a ticket for token provisioning.
# Header: SEC: <authorized_service_token>
# Generated under Admin -> Authorized Services
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/help/capabilities"
# Accept: application/json is required on every request
# Content-Type: application/json β only when sending JSON body
Ariel Search Model
Ariel searches follow a three-step asynchronous pattern:
-
Submit -
POST /api/ariel/searchesreturns asearch_idand initial status ofWAIT -
Poll -
GET /api/ariel/searches/{search_id}untilcompletedistrue -
Fetch -
GET /api/ariel/searches/{search_id}/resultsto retrieve data
Results are returned as JSON.
The events array contains the result rows.
Redirect to a file with > for downstream processing with jq or pandas.
In QRadar 7.5.0 UP13, submitting the query as a JSON body via --data returns error 1005.
Use query_expression= as a URL parameter instead.
|
curl -k -X POST \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches?query_expression=SELECT+sourceip+FROM+events+LIMIT+5"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID/results" \
> /tmp/qradar_results.json
Error Semantics
# Standard success response, no special handling needed
# Write query to a file or use URL encoding to avoid escaping issues
# Wrong: --data '{"query_expression": "SELECT ..."}'
# Right: ?query_expression=SELECT+...
# QRadar 7.5.0 UP13 rejects JSON body for Ariel searches
# Regenerate via Admin -> Authorized Services
# Verify with: curl -k -H "SEC: $QRADAR_TOKEN" "https://$QRADAR_HOST/api/help/capabilities"
# Search results expire after 86400000 ms (24 hours)
# Re-submit the query if the search has expired
Operational Gotchas
|
Production-verified against QRadar 7.5.0 UP13 at CHLA. Validate behavior against your specific version before using in automation. |
# QRadar 7.5.0 UP13 rejects --data JSON body for Ariel searches
# Use query_expression= as a URL parameter
curl -k -X POST \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches?query_expression=SELECT+*+FROM+events+LIMIT+5"
# Write the query to a file or switch to URL parameter format
# URL-encode special characters: spaces as +, quotes as %22
# GET /api/ariel/searches returns existing search IDs
# Use /api/help/capabilities for endpoint discovery
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/help/capabilities"
# Wrong: -H "Authorization: Bearer $TOKEN"
# Right: -H "SEC: $QRADAR_TOKEN"
# Read-only configuration access cannot create tokens
# Open a ticket if the option is not visible under Admin tab
# Results are gone after 24 hours and must be re-queried
# Save results immediately: > /tmp/qradar_results.json
# QRadar 7.5.0 UP13 at CHLA had roughly 3 days of Ariel data
# For longer windows, extend retention or pull from archive
Command Patterns
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/help/capabilities"
# Query must be URL-encoded and passed as query parameter.
# JSON body POST returns error 1005 in QRadar 7.5.0 UP13.
curl -k -X POST \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches?query_expression=SELECT+sourceip+FROM+events+LIMIT+5"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID/results" \
> /tmp/qradar_results.json
# Full automated submit -> poll -> fetch workflow
# Usage: pass URL-encoded query as $1
SEARCH_ID=$(curl -s -k -X POST \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches?query_expression=$1" \
| jq -r '.search_id')
printf 'Search submitted: %s\n' "$SEARCH_ID"
while true; do
STATUS=$(curl -s -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID" \
| jq -r '.status')
printf 'Status: %s\n' "$STATUS"
[ "$STATUS" = "COMPLETED" ] && break
sleep 3
done
curl -s -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID/results" \
> /tmp/qradar_results.json
printf 'Results: %s\n' /tmp/qradar_results.json
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/siem/offenses?fields=id,description,magnitude,status,offense_source"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/siem/offenses?filter=status%3DOPEN&sort=-magnitude"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/siem/offenses/$OFFENSE_ID/rules"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/asset_model/assets?limit=100&offset=0"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/config/event_sources/log_source_management/log_sources"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/config/event_sources/log_source_management/log_source_types"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/config/event_retention_buckets"
cat /tmp/qradar_results.json | jq '.events | length'
cat /tmp/qradar_results.json | jq '.'
cat /tmp/qradar_results.json | jq '.events[] | {source: .LogSource, count: .EventCount}'
cat /tmp/qradar_results.json | jq '.events[] | select(.severity >= 7)'
cat /tmp/qradar_results.json | jq -r '.events[] | [.LogSource, .EventCount] | @csv'
cat /tmp/submit_response.json | jq -r '.search_id'
cat /tmp/poll_response.json | jq -r '.status'
Credential Setup
dsec d001 dev/network
Token Validation
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/help/capabilities"
Ariel Search Workflow
curl -k -X POST \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches?query_expression=SELECT+..."
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/ariel/searches/$SEARCH_ID/results" \
> /tmp/out.json
SIEM Endpoints
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/siem/offenses"
Configuration Endpoints
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/config/event_sources/log_source_management/log_sources"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/asset_model/assets"
curl -k \
-H "SEC: $QRADAR_TOKEN" \
-H "Accept: application/json" \
"https://$QRADAR_HOST/api/config/event_retention_buckets"
Result Processing with jq
jq '.events | length' /tmp/qradar_results.json
jq -r '.events[] | [.LogSource, .EventCount] | @csv' /tmp/qradar_results.json
|
Key gotchas:
|