Manage targets, trigger scans, and retrieve findings programmatically.
The Secably EASM API is a RESTful JSON API. All endpoints are under:
https://secably.com/api/v1/easm/
All requests and responses use application/json. Dates are ISO 8601 format in UTC.
Two authentication methods are supported:
Create API keys in Dashboard → API Keys. Pass the key in the X-API-Key header:
curl -H "X-API-Key: easm_your_key_here" \
https://secably.com/api/v1/easm/targets/
API keys support scoped permissions:
| Scope | Description |
|---|---|
targets:read | List and view targets, assets, findings, alerts |
targets:write | Create, update, and delete targets |
scans:trigger | Trigger on-demand scans |
Obtain a token pair via the auth endpoint:
curl -X POST https://secably.com/api/auth/login/ \ -H "Content-Type: application/json" \ -d '{"email": "[email protected]", "password": "..."}' # Response: {"access": "eyJ...", "refresh": "eyJ..."} # Use the access token: curl -H "Authorization: Bearer eyJ..." \ https://secably.com/api/v1/easm/targets/
Errors return a JSON object with an error field:
{"error": "Target limit reached (10). Upgrade your plan."}
| Code | Meaning |
|---|---|
400 | Bad request — invalid parameters |
401 | Unauthorized — missing or invalid credentials |
403 | Forbidden — plan limit reached or insufficient scope |
404 | Not found |
409 | Conflict — e.g., scan already in progress |
429 | Rate limited |
| Plan | Limit |
|---|---|
| Pro | 100 requests/hour |
| Business | 100 requests/hour |
| MSSP | 100 requests/hour |
Rate limit headers (X-RateLimit-Remaining) are included in responses.
List all active targets in your organization.
[
{
"id": 1,
"domain": "example.com",
"status": "active",
"scan_schedule": "daily",
"risk_score": 34,
"risk_grade": "B",
"subdomain_count": 20,
"open_port_count": 6,
"vulnerability_count": 8,
"critical_count": 0,
"high_count": 2,
"medium_count": 4,
"low_count": 2,
"last_scan_at": "2026-03-13T22:52:00Z",
"created_at": "2026-03-01T10:00:00Z",
"client": "Acme Corp"
}
]
Add a new target domain to monitor.
| Field | Type | Required | Description |
|---|---|---|---|
domain | string | Yes | Root domain to monitor (e.g., example.com) |
scan_schedule | string | No | manual, hourly, daily, or weekly. Default: manual |
client_id | integer | No | Assign to a client (MSSP organizations only) |
curl -X POST https://secably.com/api/v1/easm/targets/ \ -H "X-API-Key: easm_your_key" \ -H "Content-Type: application/json" \ -d '{"domain": "example.com", "scan_schedule": "daily"}' # 201 Created {"id": 5, "domain": "example.com", "status": "active"}
400 — Invalid domain format, IP address, or domain already exists403 — Target limit reached for your planRetrieve a single target with full details.
curl -H "X-API-Key: easm_your_key" \
https://secably.com/api/v1/easm/targets/1/
Update target settings.
| Field | Type | Description |
|---|---|---|
scan_schedule | string | manual, hourly, daily, weekly |
status | string | active or paused |
curl -X PUT https://secably.com/api/v1/easm/targets/1/ \ -H "X-API-Key: easm_your_key" \ -H "Content-Type: application/json" \ -d '{"scan_schedule": "hourly"}'
Delete a target and all associated data (subdomains, ports, findings, alerts). This action is irreversible.
curl -X DELETE -H "X-API-Key: easm_your_key" \ https://secably.com/api/v1/easm/targets/1/ # 204 No Content
Trigger an on-demand scan for a target.
| Field | Type | Description |
|---|---|---|
scan_type | string | quick (default) or deep. Deep scans run all nuclei templates. |
curl -X POST https://secably.com/api/v1/easm/targets/1/scan/ \ -H "X-API-Key: easm_your_key" \ -H "Content-Type: application/json" \ -d '{"scan_type": "deep"}' # 200 OK { "scan_id": "easm_a1b2c3d4e5f67890", "status": "running", "target": "example.com", "scan_type": "deep" }
409 — Scan already in progress for this target502 — Failed to dispatch scan to scanner nodeList all discovered assets for a target.
| Query Param | Description |
|---|---|
type | Filter by asset type: subdomain, port, certificate, dns_record, technology, email_security |
curl -H "X-API-Key: easm_your_key" \ "https://secably.com/api/v1/easm/targets/1/assets/?type=subdomain" [ { "id": 42, "type": "subdomain", "value": "api.example.com", "metadata": {"ip": "104.21.50.23", "http_status": 200}, "risk_score": 15, "is_active": true, "first_seen": "2026-03-01T10:05:00Z", "last_seen": "2026-03-13T22:52:00Z" } ]
List open vulnerability findings for a target.
| Query Param | Description |
|---|---|
severity | Filter: critical, high, medium, low, info |
curl -H "X-API-Key: easm_your_key" \ "https://secably.com/api/v1/easm/targets/1/findings/?severity=high" [ { "id": 7, "title": "Exposed Redis on Port 6379", "description": "Redis instance is accessible without authentication...", "severity": "high", "category": "port_service", "cve_id": null, "cvss_score": 7.5, "remediation": "Bind Redis to 127.0.0.1 and enable AUTH...", "status": "open", "first_detected": "2026-03-10T14:00:00Z", "last_detected": "2026-03-13T22:52:00Z" } ]
List the 100 most recent alerts across all targets.
curl -H "X-API-Key: easm_your_key" \ https://secably.com/api/v1/easm/alerts/ [ { "id": 15, "target": "example.com", "alert_type": "new_subdomain", "severity": "info", "title": "New subdomain discovered: backup.example.com", "description": "...", "details": {"subdomain": "backup.example.com", "ip": "104.21.218.246"}, "is_read": false, "created_at": "2026-03-13T22:55:00Z" } ]
| Type | Description |
|---|---|
new_subdomain | New subdomain discovered |
new_port | New open port detected |
new_vulnerability | New vulnerability found |
ssl_expiry | SSL certificate expiring soon |
risk_change | Risk grade changed |
service_change | Service/technology changed |
Configure webhooks in Dashboard → Webhooks. Secably sends POST requests to your URL when events occur:
| Event | Triggered when |
|---|---|
scan.completed | A scan finishes |
finding.new | A new vulnerability is detected |
finding.resolved | A finding changes to resolved |
alert.created | A new alert fires |
risk.changed | A target's risk grade changes |
Each delivery includes an HMAC-SHA256 signature in the X-Secably-Signature header. Verify it against your webhook secret:
# Python verification example import hmac, hashlib def verify_webhook(payload_body, signature, secret): expected = hmac.new( secret.encode(), payload_body, hashlib.sha256 ).hexdigest() return hmac.compare_digest(f"sha256={expected}", signature)
Example payload:
{
"event": "finding.new",
"timestamp": "2026-03-13T22:55:00Z",
"data": {
"target": "example.com",
"finding": {
"id": 7,
"title": "Exposed Redis on Port 6379",
"severity": "high",
"cvss_score": 7.5
}
}
}
Failed deliveries are retried 3 times with exponential backoff (1m, 5m, 30m).
# Python example — list targets & trigger a scan import requests API_KEY = "easm_your_key_here" BASE = "https://secably.com/api/v1/easm" headers = {"X-API-Key": API_KEY} # List all targets targets = requests.get(f"{BASE}/targets/", headers=headers).json() for t in targets: print(f"{t['domain']} — Grade: {t['risk_grade']}, Vulns: {t['vulnerability_count']}") # Add a new target new = requests.post(f"{BASE}/targets/", headers=headers, json={"domain": "newdomain.com", "scan_schedule": "daily"}).json() print(f"Created target #{new['id']}") # Trigger a deep scan scan = requests.post(f"{BASE}/targets/{new['id']}/scan/", headers=headers, json={"scan_type": "deep"}).json() print(f"Scan {scan['scan_id']} is {scan['status']}") # Get findings findings = requests.get(f"{BASE}/targets/{new['id']}/findings/", headers=headers).json() for f in findings: print(f"[{f['severity'].upper()}] {f['title']}")
Create your API key and start automating your attack surface monitoring.
Get Started Free