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
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 -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 -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
{
"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 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 -X GET "https://myssl.info/api/v1/scans/12345" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response (Pending)
{
"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)
{
"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
}
}
}
}
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 -X GET "https://myssl.info/api/v1/scans?domain_id=1&status=completed&per_page=10" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"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 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 -X GET "https://myssl.info/api/v1/domains/1/scans?per_page=30" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"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
}
}
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 -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
{
"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 |