REST API Automation
Maintained by: Aether365 Team Audience: Developers and DevOps engineers Scope: Using the Aether365 API for automation and custom integrations
The Aether365 REST API lets you integrate scan results into your existing security tooling, automate reporting, and trigger scans programmatically.
Getting Started
- Generate an API key in Settings > API Keys
- Use the key as a
Bearertoken in all API requests - See the API Reference for all available endpoints
Common Automation Patterns
Trigger a scan and wait for results
This pattern is useful in CI/CD pipelines where you want to block deployment if security posture drops below a threshold.
python
import requests
import time
API_KEY = "ae_live_your-api-key"
BASE = "https://api.aether365.io"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Trigger a compliance scan
resp = requests.post(f"{BASE}/tenants/me/scans",
json={"scan_type": "compliance"},
headers=HEADERS)
scan = resp.json()["data"]
scan_id = scan["id"]
print(f"Scan started: {scan_id}")
# Poll until complete
while True:
resp = requests.get(f"{BASE}/scans/{scan_id}", headers=HEADERS)
scan = resp.json()["data"]
if scan["status"] in ("completed", "failed"):
break
print(f"Status: {scan['status']} - waiting...")
time.sleep(30)
if scan["status"] == "failed":
print("Scan failed")
exit(1)
score = scan["score"]
print(f"Score: {score}%")
if score < 80:
print(f"Score {score}% is below threshold (80%). Failing pipeline.")
exit(1)
print("Security check passed")Retrieve all critical failures from the latest scan
python
import requests
API_KEY = "ae_live_your-api-key"
BASE = "https://api.aether365.io"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
# Get the most recent completed scan
scans = requests.get(f"{BASE}/tenants/me/scans?status=completed&limit=1",
headers=HEADERS).json()["data"]
if not scans:
print("No completed scans found")
exit(0)
scan_id = scans[0]["id"]
# Fetch critical failures
page, results = 1, []
while True:
resp = requests.get(f"{BASE}/scans/{scan_id}/results",
params={"result": "Failed", "severity": "Critical", "page": page, "limit": 100},
headers=HEADERS).json()
results.extend(resp["data"])
if page >= resp["meta"]["totalPages"]:
break
page += 1
print(f"Critical failures: {len(results)}")
for r in results:
print(f" [{r['id']}] {r['title']}")GitHub Actions: scan on schedule
yaml
name: Aether365 Security Scan
on:
schedule:
- cron: '0 6 * * MON' # Every Monday at 06:00 UTC
workflow_dispatch:
jobs:
scan:
runs-on: ubuntu-latest
steps:
- name: Trigger scan
id: trigger
run: |
RESPONSE=$(curl -s -X POST https://api.aether365.io/tenants/me/scans \
-H "Authorization: Bearer ${{ secrets.AETHER365_API_KEY }}" \
-H "Content-Type: application/json" \
-d '{"scan_type": "compliance"}')
SCAN_ID=$(echo $RESPONSE | jq -r '.data.id')
echo "scan_id=$SCAN_ID" >> $GITHUB_OUTPUT
- name: Wait for completion
run: |
SCAN_ID=${{ steps.trigger.outputs.scan_id }}
for i in $(seq 1 30); do
STATUS=$(curl -s https://api.aether365.io/scans/$SCAN_ID \
-H "Authorization: Bearer ${{ secrets.AETHER365_API_KEY }}" \
| jq -r '.data.status')
echo "Status: $STATUS"
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && echo "Scan failed" && exit 1
sleep 30
done
- name: Check score
run: |
SCAN_ID=${{ steps.trigger.outputs.scan_id }}
SCORE=$(curl -s https://api.aether365.io/scans/$SCAN_ID \
-H "Authorization: Bearer ${{ secrets.AETHER365_API_KEY }}" \
| jq '.data.score')
echo "Security score: $SCORE%"
if (( $(echo "$SCORE < 75" | bc -l) )); then
echo "Score below threshold"
exit 1
fiPowerShell: export results to CSV on a schedule
powershell
$ApiKey = $env:AETHER365_API_KEY
$Headers = @{ Authorization = "Bearer $ApiKey" }
# Get latest scan
$Scans = Invoke-RestMethod -Uri "https://api.aether365.io/tenants/me/scans?status=completed&limit=1" -Headers $Headers
$ScanId = $Scans.data[0].id
# Fetch all results
$Page = 1
$AllResults = @()
do {
$Resp = Invoke-RestMethod -Uri "https://api.aether365.io/scans/$ScanId/results?page=$Page&limit=100" -Headers $Headers
$AllResults += $Resp.data
$Page++
} while ($Page -le $Resp.meta.totalPages)
# Export to CSV
$AllResults | Export-Csv -Path "scan_$(Get-Date -Format 'yyyy-MM-dd').csv" -NoTypeInformation
Write-Host "Exported $($AllResults.Count) results"Pagination
All list endpoints support pagination via page and limit query parameters:
bash
curl "https://api.aether365.io/scans/{scanId}/results?page=2&limit=50" \
-H "Authorization: Bearer <token>"The meta object in list responses includes:
| Field | Description |
|---|---|
total | Total number of items |
page | Current page number |
limit | Items per page |
totalPages | Total number of pages |
Error Handling
All API errors return a consistent structure:
json
{
"success": false,
"error": {
"code": "SNAKE_CASE_ERROR_CODE",
"message": "Human-readable description"
}
}Always check the success field before reading data. See Error Codes for all error codes.