The Certificate Transparency Log API enables proactive monitoring and auditing of SSL/TLS certificates issued for domain names. It helps verify proper issuance, spot misuse, and fortify web security by safeguarding online interactions and maintaining the trustworthiness of digital environments. The Certificate Transparency (CT) Log is a public, append-only ledger of all SSL/TLS certificates issued by trusted Certificate Authorities (CAs). Developed by Google, its primary purpose is to enhance internet security by making the process of certificate issuance transparent and publicly auditable. This transparency allows domain owners and the broader community to monitor and verify certificates, quickly detect any misissued or malicious certificates, and prevent potential security threats like man-in-the-middle attacks.
Our Certificate Transparency Log Replica hosted at https://crt.edgewatch.net/ provides an independent and readily accessible copy of the CT logs. By offering this replica, we enable organizations, security researchers, and individuals to proactively monitor and audit SSL/TLS certificates related to their domains. This service helps verify proper certificate issuance and swiftly identify any misuse, thereby fortifying web security and maintaining the trustworthiness of digital environments. Our API facilitates efficient querying and retrieval of certificate information, empowering users to safeguard their online interactions.
Base URL:
https://crt.edgewatch.net
Quick start
1) (Optional but recommended) Obtain a JWT using your client credentials
curl -s https://crt.edgewatch.net/auth/token/ \
-H "X-Client-Id: <client-id>" \
-H "X-Client-Secret: <client-secret>"2) Search for certificates (exact match)
TOKEN="<jwt>"
curl -s "https://crt.edgewatch.net/certificates/search/?dns_name=example.com&search_mode=exact&limit=10" \
-H "Authorization: Bearer $TOKEN" | jqYou may also authenticate every request with X-Client-Id and X-Client-Secret headers if JWT is not convenient for your workflow.
Authentication & rate limits
- Unauthenticated requests are intentionally throttled and suitable only for light, manual testing.
- Authenticated requests accept either:
- Authorization: Bearer <JWT> (recommended), or
X-Client-Id and X-Client-Secret headers.
- Authorization: Bearer <JWT> (recommended), or
- Token refresh: exchange a refresh token at GET /auth/refresh/ using header X-Refresh-Token.
- HTTP 429 indicates you exceeded burst/usage limits. Back off with exponential retries.
Conventions
- Dates accept YYYY-MM-DD and (where applicable) timestamps in UTC ISO‑8601.
- Unless stated otherwise, endpoints return JSON.
- Most list endpoints take a limit parameter. Use restrictive filters (domain, date ranges) for best performance.
Endpoint overview
| Category | Endpoint | Purpose |
| Search | GET /certificates/search/ | Search by DNS name with multiple match modes |
| Monitoring | GET /certificates/domain-monitor/{domain}/ | One‑shot domain overview (active/expired/expiring) |
| Discovery | GET /certificates/subdomains/{domain}/ | Enumerate subdomains observed in CT |
| Hygiene | GET /certificates/expiring-soon/ | Certificates expiring within N days |
| Hygiene | GET /certificates/expired/ | Certificates that have already expired |
| Discovery | GET /certificates/wildcards/ | Certificates covering wildcard names |
| Feed | GET /certificates/recently-updated/ | Recently added/updated certs |
| Inventory | GET /certificates/multiple-certs-domains/ | Domains with ≥ N different certs |
| Inventory | GET /certificates/oldest-active/ | Oldest still‑valid certificates |
| Inventory | GET /certificates/long-validity/ | Unusually long validity periods |
| Change tracking | GET /certificates/frequent-chain-changes/ | Detect frequent chain hash changes |
| KPIs | GET /api/home-stats/ | Pre‑computed stats for dashboards |
| KPIs | GET /api/certificate-counts/ | Counts (active vs expired) |
| KPIs | GET /certificates/active-count/ | Total active certificates |
| KPIs | GET /certificates/stats/ | 45‑day rolling certificate stats |
| Health | GET /health/ | Service health summary |
| Health | GET /performance/ | Cache + query performance metrics |
| Health | GET /ping/ | Simple liveness check |
Search certificates
GET /certificates/search/
Search for certificates by DNS name with flexible match modes.
Query parameters
| Name | Type | Default | Notes |
| dns_name | string | — | Domain to search (required). |
| search_mode | enum | contains | One of exact, prefix, suffix, contains. exact is fastest. |
| from_date | date | 30 days ago | Lower bound for issuance/observation. |
| to_date | date | now | Upper bound. |
| limit | int | 100 | Max results (up to 1000). |
| skip_cache | bool | false | Force a fresh query (bypass cache). |
Example
curl -s "https://crt.edgewatch.net/certificates/search/?dns_name=example.com&search_mode=exact&limit=10" \
-H "Authorization: Bearer <jwt>"Response (truncated)
{
"count": 10,
"certificates": [
{
"url": "https://ct.googleapis.com/logs/argon2024/",
"cert_index": "123456789",
"url_plus_index": "https://ct.googleapis.com/logs/argon2024/|123456789",
"not_before": "2024-01-01T00:00:00Z",
"not_after": "2025-01-01T00:00:00Z",
"all_dns_names": "example.com www.example.com api.example.com",
"dns_name_count": 3,
"wildcard_count": 0
}
],
"filters_applied": {"dns_name": "example.com", "search_mode": "exact"},
"performance": {"cached": false, "execution_time": 0.25, "query_time_seconds": 0.23}
}Performance tips
- Prefer exact when you know the precise name.
- prefix is ideal for brand monitoring (e.g., edgewatch).
- suffix is ideal for subdomain discovery (e.g., example.com).
- contains is flexible but slower.
Domain monitor
GET /certificates/domain-monitor/{domain}/
Returns a categorized snapshot for a domain (active, expired, expiring soon), with optional date filtering.
Path parameters
| Name | Type | Notes |
| domain | string | Base domain. |
Query parameters
| Name | Type | Default | Notes |
| from_date | date | 30 days ago | Lower bound (observation window). |
| to_date | date | today | Upper bound. |
| exact | bool | false | If true, restrict to exact FQDN. |
| match_mode | enum | — | prefix (fast) or contains (slower, shorter window). |
| count_only | bool | false | Return only counts (faster). |
Example
curl -s "https://crt.edgewatch.net/certificates/domain-monitor/example.com/?exact=true" \
-H "Authorization: Bearer <jwt>"Subdomain enumeration
GET /certificates/subdomains/{domain}/
Discovers subdomains observed in CT for a given base domain.
Path parameters
| Name | Type | Notes |
| domain | string | Base domain (e.g., example.com). |
Query parameters
| Name | Type | Default | Notes |
| from_date | date | 30 days ago | Restrict the window for faster results. |
| to_date | date | today | — |
| limit | int | 1000 | Up to 10000. |
| skip_cache | bool | false | Force a fresh query. |
Example
curl -s "https://crt.edgewatch.net/certificates/subdomains/example.com/?limit=2000" \
-H "Authorization: Bearer <jwt>"Expiring soon
GET /certificates/expiring-soon/
Find certificates that will expire within the specified horizon.
Query parameters
| Name | Type | Default | Notes |
| days_ahead | int | 30 | Range: 1–365. |
| domain_name | string | — | Optional filter to a domain. |
| limit | int | 50 | Up to 1000. |
| skip_cache | bool | false | Force a fresh query. |
Example
curl -s "https://crt.edgewatch.net/certificates/expiring-soon/?days_ahead=14&domain_name=example.com" \
-H "Authorization: Bearer <jwt>"Expired
GET /certificates/expired/
List certificates that have already expired within the requested window.
Query parameters
| Name | Type | Default | Notes |
| from_date | date | yesterday | Narrow to 1–3 days for best performance. |
| to_date | date | today | — |
| domain_name | string | — | Optional filter. |
| limit | int | 50 | Up to 1000. |
Example
curl -s "https://crt.edgewatch.net/certificates/expired/?from_date=2024-11-01&to_date=2024-11-11&domain_name=example.com" \
-H "Authorization: Bearer <jwt>"Wildcards
GET /certificates/wildcards/
Retrieve certificates that include wildcard names (e.g., *.example.com).
Query parameters
| Name | Type | Default | Notes |
| from_date | date | 30 days ago | — |
| to_date | date | today | — |
| domain | string | — | Optional filter. |
| limit | int | 100 | Up to 1000. |
Recently updated
GET /certificates/recently-updated/
Certificates most recently observed or updated in the CT backend.
Query parameters
| Name | Type | Default | Notes |
| from_date | date | 7 days ago | — |
| to_date | date | now | — |
| domain | string | — | Optional filter. |
| limit | int | 50 | Up to 1000. |
Identify domains with a high number of distinct certificates (useful for inventory and anomaly detection).
Multiple certificates per domain
GET /certificates/multiple-certs-domains/
Query parameters
| Name | Type | Default | Notes |
| domain | string | — | Required. Prefix‑style pattern (e.g., google). |
| min_cert_count | int | 2 | Range: 2–1000. |
| limit | int | 100 | Up to 1000. |
Oldest active
GET /certificates/oldest-active/
Surface the oldest yet still valid certificates.
Query parameters
| Name | Type | Default | Notes |
| max_age_years | int | 10 | Range: 1–30. |
| domain_name | string | — | Optional filter. |
| limit | int | 50 | Up to 1000. |
Long validity
GET /certificates/long-validity/
Locate certificates with unusually long validity windows (commonly historical, pre‑2020).
Query parameters
| Name | Type | Default | Notes |
| from_date | date | 180 days ago | — |
| to_date | date | today | — |
| min_validity_days | int | 730 | Range: 1–3650. |
| domain_name | string | — | Optional filter. |
| limit | int | 50 | Up to 1000. |
Frequent chain changes
GET /certificates/frequent-chain-changes/
Detect potentially suspicious frequent re‑issuance by tracking chain hash changes. This query is expensive. Restrict the date range and filter by domain when possible.
Query parameters
| Name | Type | Default | Notes |
| from_date | date | 7 days ago | Use 1–7 days for best results. |
| to_date | date | today | — |
| domain_name | string | — | Strongly recommended. |
| min_chain_changes | int | 2 | Range: 2–10. |
| limit | int | 50 | Range: 1–100. |
KPIs & stats
Home stats
GET /api/home-stats/ – Cached summary for landing dashboards.
Certificate counts
GET /api/certificate-counts/ – Counts split by active/expired.
Active count
GET /certificates/active-count/ – Total active certificates.
45‑day stats
GET /certificates/stats/ – Rolling daily counts of new, expired, issued.
Health & performance endpoints
- GET /health/ – Service and dependency health. (No auth.)
- GET /performance/ – Cache hit ratio, slow query counts, timings.
- GET /ping/ – Simple liveness probe. (No auth.)
Data model
Certificate object (common fields)
| Field | Type | Description |
| url | string | CT log base URL (e.g., Argon2024). |
| cert_index | string | Index within the CT log. |
| url_plus_index | string | Convenience composite `url |
| not_before | string (UTC) | Certificate validity start. |
| not_after | string (UTC) | Certificate expiry. |
| all_dns_names | string | Space‑separated list of DNS names. |
| dns_name_count | int | Count of names present. |
| wildcard_count | int | Count of wildcard DNS names. |
Envelope (typical list response)
{
"count": 123,
"certificates": [ /* … */ ],
"filters_applied": { /* echo of your filters */ },
"performance": {
"cached": true,
"execution_time": 0.08,
"query_time_seconds": 0.07
},
"note": "Optional informational message"
}Performance guidance
- Match mode: exact and prefix leverage indexes; contains is most expensive
- Date windows: Prefer short, recent windows (7–30 days). Historical digs should be sliced.
- Caching: Responses are cached with a short TTL. Use skip_cache=true only when freshness is critical.
- Filtering: Add domain/domain_name filters whenever possible.
- Limits: Start small during development; increase gradually.
Expected latencies (indicative):
| Query | Typical latency |
| Exact / prefix / suffix search | 50–1000 ms |
| Contains search | 1–5 s |
| Expiring soon | 0.5–5 s |
| Expired (wide windows) | 5–30 s |
| Frequent chain changes | 30–120 s |
| Cache hits | <100 ms |
Errors & troubleshooting
| HTTP | Reason | Typical fix |
| 400 | Invalid parameters (e.g., date format) | Use YYYY-MM-DD; review required params. |
| 401 | No/invalid credentials | Provide a valid JWT or client headers. |
| 403 | Not allowed | Check plan/permissions, header format. |
| 404 | Unknown endpoint/path | Verify the path; see Endpoint overview. |
| 429 | Throttled | Reduce rate; add backoff; consider authenticated use. |
| 5xx | Temporary backend issue | Retry with jitter; contact support if persistent. |
Debug tips:
- Echo the server’s filters_applied and performance blocks to understand what ran.
- Narrow from_date/to_date and add domain/domain_name filters.
- Inspect whether the response was a cache miss (first call) or cache hit (subsequent call).
Security & compliance
- HTTPS‑only, JWT‑based auth with refresh tokens.
- Request throttling and per‑token rate limits.
- Optional service‑to‑service authentication via client headers.
- Usage is tracked for fairness; abuse is automatically curtailed.
SDK‑style snippets
Python (requests)
import requests
BASE = "https://crt.edgewatch.net"
headers = {"Authorization": "Bearer <jwt>"}
r = requests.get(f"{BASE}/certificates/search/", params={
"dns_name": "example.com",
"search_mode": "exact",
"limit": 10,
}, headers=headers)
print(r.json())Node.js (fetch)
const BASE = 'https://crt.edgewatch.net';
const headers = { Authorization: 'Bearer <jwt>' };
async function search() {
const url = new URL('/certificates/search/', BASE);
url.searchParams.set('dns_name', 'example.com');
url.searchParams.set('search_mode', 'exact');
url.searchParams.set('limit', '10');
const res = await fetch(url, { headers });
const data = await res.json();
console.log(data);
}
search();