Scans API

Trigger on-demand SSL/TLS security scans and retrieve detailed analysis results. Get comprehensive information about certificate configuration, protocol support, and security vulnerabilities.

Overview

The Scans API provides detailed SSL/TLS security analysis powered by testssl.sh. Each scan evaluates certificate validity, protocol support, cipher suites, and known vulnerabilities.

Scans are processed asynchronously. After triggering a scan, poll the status endpoint or use webhooks to get notified when complete.

What We Scan

Certificate Chain

Validity, expiration, issuer, chain completeness

Protocol Support

SSLv3, TLS 1.0/1.1/1.2/1.3

Cipher Suites

Strength analysis, forward secrecy

Vulnerabilities

BEAST, POODLE, Heartbleed, ROBOT, etc.

Endpoints

POST /api/v1/scans

Trigger Scan

Start a new SSL/TLS scan for a domain. The scan runs asynchronously and you'll receive a scan ID to check its status.

Request Body

Parameter Type Description
domain_id integer Required* Body ID of an existing monitored domain
hostname string Required* Body Hostname to scan (for ad-hoc scans)
port integer Body Port number (default: 443, used with hostname)
scan_type string Body quick (default) or full - Full scans include vulnerability checks
callback_url string Body Webhook URL to notify when scan completes

* Provide either domain_id OR hostname, not both.

Example Request (by Domain ID)

cURL
curl -X POST "https://myssl.info/api/v1/scans" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain_id": 1,
    "scan_type": "full"
  }'

Example Request (Ad-hoc Scan)

cURL
curl -X POST "https://myssl.info/api/v1/scans" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "hostname": "example.com",
    "port": 443,
    "scan_type": "quick"
  }'

Example Response

202 Accepted
{
  "scan": {
    "id": 12345,
    "hostname": "example.com",
    "port": 443,
    "status": "pending",
    "scan_type": "full",
    "created_at": "2025-01-13T15:00:00Z",
    "estimated_duration_seconds": 60
  },
  "message": "Scan queued successfully",
  "status_url": "https://myssl.info/api/v1/scans/12345"
}
GET /api/v1/scans/{id}

Get Scan Status & Results

Retrieve the status and results of a scan. If the scan is complete, the full results are included.

Path Parameters

Parameter Type Description
id integer Required Path The unique scan ID

Example Request

cURL
curl -X GET "https://myssl.info/api/v1/scans/12345" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response (Pending)

200 OK
{
  "scan": {
    "id": 12345,
    "hostname": "example.com",
    "port": 443,
    "status": "running",
    "progress": 45,
    "current_step": "Checking cipher suites",
    "created_at": "2025-01-13T15:00:00Z",
    "started_at": "2025-01-13T15:00:05Z"
  }
}

Example Response (Complete)

200 OK
{
  "scan": {
    "id": 12345,
    "hostname": "example.com",
    "port": 443,
    "status": "completed",
    "created_at": "2025-01-13T15:00:00Z",
    "started_at": "2025-01-13T15:00:05Z",
    "completed_at": "2025-01-13T15:01:30Z",
    "duration_seconds": 85,
    "results": {
      "grade": "A+",
      "score": 100,
      "certificate": {
        "subject": "example.com",
        "issuer": "Let's Encrypt Authority X3",
        "valid_from": "2024-12-15T00:00:00Z",
        "valid_to": "2025-06-15T12:00:00Z",
        "days_until_expiry": 153,
        "serial_number": "03:AB:CD:EF:12:34:56:78",
        "signature_algorithm": "SHA256withRSA",
        "key_type": "RSA",
        "key_size": 2048,
        "san": ["example.com", "www.example.com"],
        "chain_valid": true,
        "chain_length": 3
      },
      "protocols": {
        "ssl3": false,
        "tls1_0": false,
        "tls1_1": false,
        "tls1_2": true,
        "tls1_3": true
      },
      "cipher_suites": {
        "strong": 12,
        "weak": 0,
        "insecure": 0,
        "forward_secrecy": true
      },
      "vulnerabilities": {
        "heartbleed": false,
        "ccs_injection": false,
        "ticketbleed": false,
        "robot": false,
        "secure_renegotiation": true,
        "poodle_ssl": false,
        "beast": false,
        "lucky13": false,
        "freak": false,
        "logjam": false,
        "drown": false
      },
      "headers": {
        "strict_transport_security": true,
        "hsts_max_age": 31536000,
        "hsts_preload": true
      }
    }
  }
}
GET /api/v1/scans

List Scans

Retrieve a paginated list of scans with optional filtering by domain, status, or date range.

Query Parameters

Parameter Type Description
domain_id integer Optional Filter scans by domain ID
hostname string Optional Filter scans by hostname
status string Optional Filter by status: pending, running, completed, failed
grade string Optional Filter by result grade: A+, A, B, etc.
from_date string Optional Start date (ISO 8601 format)
to_date string Optional End date (ISO 8601 format)
page integer Optional Page number (default: 1)
per_page integer Optional Items per page, max 100 (default: 20)

Example Request

cURL
curl -X GET "https://myssl.info/api/v1/scans?domain_id=1&status=completed&per_page=10" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

200 OK
{
  "scans": [
    {
      "id": 12345,
      "hostname": "example.com",
      "port": 443,
      "status": "completed",
      "grade": "A+",
      "score": 100,
      "scan_type": "full",
      "duration_seconds": 85,
      "completed_at": "2025-01-13T15:01:30Z"
    },
    {
      "id": 12340,
      "hostname": "example.com",
      "port": 443,
      "status": "completed",
      "grade": "A+",
      "score": 100,
      "scan_type": "quick",
      "duration_seconds": 15,
      "completed_at": "2025-01-12T10:30:00Z"
    }
  ],
  "pagination": {
    "page": 1,
    "per_page": 10,
    "total": 2,
    "pages": 1
  }
}
GET /api/v1/domains/{id}/scans

Get Domain Scan History

Retrieve the scan history for a specific domain, useful for tracking SSL grade changes over time.

Path Parameters

Parameter Type Description
id integer Required Path The domain ID

Example Request

cURL
curl -X GET "https://myssl.info/api/v1/domains/1/scans?per_page=30" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

200 OK
{
  "domain": {
    "id": 1,
    "hostname": "example.com"
  },
  "scans": [
    {
      "id": 12345,
      "grade": "A+",
      "score": 100,
      "completed_at": "2025-01-13T10:00:00Z"
    },
    {
      "id": 12300,
      "grade": "A+",
      "score": 100,
      "completed_at": "2025-01-12T10:00:00Z"
    },
    {
      "id": 12255,
      "grade": "A",
      "score": 95,
      "completed_at": "2025-01-11T10:00:00Z"
    }
  ],
  "summary": {
    "total_scans": 45,
    "grade_changes": 2,
    "current_grade": "A+",
    "best_grade": "A+",
    "worst_grade": "A"
  },
  "pagination": {
    "page": 1,
    "per_page": 30,
    "total": 45,
    "pages": 2
  }
}
GET /api/v1/scans/compare

Compare Scans

Compare two scans to see what changed between them. Useful for tracking configuration changes.

Query Parameters

Parameter Type Description
scan_id_1 integer Required Query First scan ID (older)
scan_id_2 integer Required Query Second scan ID (newer)

Example Request

cURL
curl -X GET "https://myssl.info/api/v1/scans/compare?scan_id_1=12255&scan_id_2=12345" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

200 OK
{
  "comparison": {
    "hostname": "example.com",
    "scan_1": {
      "id": 12255,
      "grade": "A",
      "score": 95,
      "completed_at": "2025-01-11T10:00:00Z"
    },
    "scan_2": {
      "id": 12345,
      "grade": "A+",
      "score": 100,
      "completed_at": "2025-01-13T10:00:00Z"
    },
    "changes": {
      "grade_improved": true,
      "score_change": 5,
      "protocols": {
        "tls1_0": {"before": true, "after": false, "change": "disabled"},
        "tls1_3": {"before": false, "after": true, "change": "enabled"}
      },
      "cipher_suites": {
        "weak_removed": 2,
        "strong_added": 3
      },
      "certificate": {
        "renewed": true,
        "new_expiry": "2025-06-15T12:00:00Z"
      }
    }
  }
}

Scan Statuses

Understanding scan status values:

Status Description
pending Scan is queued and waiting to start
running Scan is currently in progress
completed Scan finished successfully with results
failed Scan failed (connection error, timeout, etc.)

Error Codes

Scan-specific error codes:

Code Message Description
400 Invalid scan type scan_type must be "quick" or "full"
404 Scan not found The specified scan ID does not exist
409 Scan in progress A scan is already running for this domain
429 Scan limit reached You've exceeded your daily scan limit
502 Connection failed Could not connect to the target host
504 Scan timeout Scan took too long to complete

Related Endpoints