Docs / API Reference

API Reference

Integrate Luna into your workflow with our REST API

Getting Started

Base URL: https://api.lunatech.xyz/v1

To use the Luna API, you need two things:

  1. An API key, created from the Luna dashboard
  2. Your Organization ID, shown in your profile

Step 1: Get your Organization ID

In the Luna dashboard, go to Settings > API Keys. Your Organization ID is shown there with a copy button.

Step 2: Create an API key

  1. In the Luna dashboard, go to Settings > API Keys
  2. Click Create API Key
  3. Give it a name and select the permissions you need (see Permissions)
  4. Copy the key immediately. It starts with sk- and is only shown once
Requirements: MFA must be enabled on your account, and your organization needs an active paid plan (Professional or above).

Step 3: Make requests

Every request needs two headers:

Authorization: Bearer sk-your-api-key
X-Organization-ID: your-org-id

Full example:

curl https://api.lunatech.xyz/v1/vulnerabilities/stats \
  -H "Authorization: Bearer sk-abc123..." \
  -H "X-Organization-ID: 6650a1b2c3d4e5f678901234"

For convenience, set these as environment variables:

export API_KEY="sk-your-api-key"
export ORG_ID="your-org-id"
export BASE="https://api.lunatech.xyz/v1"

Then all the examples below work as-is.

Targets

Targets are the domains, subdomains, or IPs you want to scan. You must add targets before you can scan them.

Add Targets

curl -X POST "$BASE/addtargets" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{"target": ["example.com", "app.example.com"]}'

Response:

{"status": "Targets added", "added": 2, "duplicates": 0, "reactivated": 0}

Internal/private IPs (127.0.0.1, 10.x.x.x, etc.) are blocked.

List Targets

curl "$BASE/listtargets" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

Remove Targets

curl -X DELETE "$BASE/removetargets" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{"target": ["example.com"]}'

Scans

Start a Scan

curl -X POST "$BASE/scan" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "target": ["example.com"],
    "scan_type": "comprehensive",
    "discovery_preset": "full"
  }'
FieldTypeDescription
targetstring[]Required. Targets to scan (must already be added)
scan_typestringquick, comprehensive, or cve-only
discovery_presetstringfull, quick, or custom
deep_scanboolEnable deep scan mode

Returns 409 if a scan is already running for the same targets.

List Scans

curl "$BASE/scans" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

Get Scan Results

curl "$BASE/scans/SCAN_ID/results" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

Vulnerabilities

Get Stats

curl "$BASE/vulnerabilities/stats" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

Response:

{
  "total": 42,
  "critical": 2,
  "high": 8,
  "medium": 15,
  "low": 12,
  "info": 5,
  "security_score": 72.5
}

List All Vulnerabilities

curl "$BASE/vulnerabilities" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

Reports

Reports are generated on the fly. No creation step needed. Just request the format you want and the file is returned immediately.

# Security posture report (all vulnerabilities across your org)
curl -o report.pdf "$BASE/reports/security-posture/pdf" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

curl -o report.csv "$BASE/reports/security-posture/csv" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

curl -o report.json "$BASE/reports/security-posture/json" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

# Single scan report
curl -o scan-report.pdf "$BASE/reports/scans/SCAN_ID/pdf" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID"

Available formats: pdf, csv, json. Requires Professional plan or above.

Scheduled Scans

Create a Scheduled Scan

curl -X POST "$BASE/scheduled-scans" \
  -H "Authorization: Bearer $API_KEY" \
  -H "X-Organization-ID: $ORG_ID" \
  -H "Content-Type: application/json" \
  -d '{
    "schedule_name": "Weekly full scan",
    "targets": ["example.com"],
    "cron_schedule": "weekly-monday",
    "scan_type": "comprehensive",
    "discovery_preset": "full"
  }'

Schedule formats: daily, weekly-monday, hourly, every-12hours, or cron syntax (0 9 * * 1).

List / Update / Delete

GET    /v1/scheduled-scans
PUT    /v1/scheduled-scans/:scanId
DELETE /v1/scheduled-scans/:scanId

Errors

All errors return a JSON object with an error field:

{"error": "A scan is already in progress for these targets. Wait for it to complete or cancel it first."}
CodeMeaning
400Invalid input
401Missing or invalid authentication
402Plan limit exceeded (upgrade required)
403Insufficient permissions or plan tier
409Conflict (e.g., scan already running for these targets)
429Rate limited, wait and retry

API Key Permissions

When creating an API key, assign only the permissions you need:

PermissionWhat it grants
scan:readView scans, results, vulnerabilities, discovery data, reports
scan:writeStart scans, delete scans, create/update scheduled scans
targets:readList targets
targets:writeAdd and remove targets