TLS certificate check API
Connects to the domain on port 443 with SNI, verifies the certificate against the system's trusted roots and the host name (RFC 9525), and reports dates, names, issuer, chain, key and signature algorithm and the negotiated TLS version. No HTTP is sent.
GET https://api.lookproof.dev/v1/tls/certificate
Updated 2026-10-09
Examples use the Base (eip155:8453) network.
Input
Query parameters.
| Name | Type | Required | Limits | Description |
|---|---|---|---|---|
domain | string | Yes | 1–1024 characters | The domain to check, for example example.com. |
Example request
curl -i 'https://api.lookproof.dev/v1/tls/certificate?domain=example.com'import asyncio
import os
from eth_account import Account
from x402 import x402Client
from x402.http.clients import x402HttpxClient
from x402.mechanisms.evm import EthAccountSigner
from x402.mechanisms.evm.exact import register_exact_evm_client
async def main() -> None:
signer = EthAccountSigner(Account.from_key(os.environ["EVM_PRIVATE_KEY"]))
client = register_exact_evm_client(x402Client(), signer, networks="eip155:8453")
async with x402HttpxClient(client) as http:
response = await http.get('https://api.lookproof.dev/v1/tls/certificate', params={'domain': 'example.com'})
response.raise_for_status()
print(response.json())
asyncio.run(main())
import { wrapFetchWithPaymentFromConfig } from "@x402/fetch";
import { ExactEvmScheme } from "@x402/evm";
import { privateKeyToAccount } from "viem/accounts";
const account = privateKeyToAccount(process.env.EVM_PRIVATE_KEY);
const fetchWithPayment = wrapFetchWithPaymentFromConfig(fetch, {
schemes: [{ network: "eip155:8453", client: new ExactEvmScheme(account) }],
});
const response = await fetchWithPayment("https://api.lookproof.dev/v1/tls/certificate?domain=example.com");
console.log(await response.json());
curl: unpaid request — returns 402 with the price (PAYMENT-REQUIRED). The Python and JavaScript clients pay it and send the request again. Only ordinary wallets (EOA) can pay; smart-contract wallets get a 402 without charge. See payments.
Example response
{
"checked_at": "2026-10-24T12:00:00Z",
"data": {
"address_family": "ipv4",
"chain": [
{
"issuer": "CN=Example Issuing CA",
"subject": "CN=example.com"
},
{
"issuer": "CN=Example Issuing CA",
"subject": "CN=Example Issuing CA"
}
],
"cipher": "TLS_AES_256_GCM_SHA384",
"days_remaining": 36,
"domain": "example.com",
"hostname_match": true,
"issuer": "CN=Example Issuing CA",
"key_bits": 256,
"key_type": "ec",
"not_after": "2026-11-30T00:00:00Z",
"not_before": "2026-09-01T00:00:00Z",
"san": [
"example.com",
"www.example.com"
],
"serial_number": "5ec0de",
"signature_algorithm": "ecdsa-with-SHA256",
"subject_cn": "example.com",
"tls_version": "TLSv1.3",
"trusted": true,
"untrusted_reason": null
},
"endpoint": "tls.certificate",
"findings": [],
"meta": {
"cache_hit": false,
"duration_ms": 42,
"fresh_until": "2026-10-24T12:05:00Z",
"observed_at": "2026-10-24T12:00:00Z",
"resolver": null,
"source": "dns"
},
"request_id": "req_aaaaaaaaaaaaaaaaaaaaaaaaaa",
"schema_version": "1.0",
"status": "ok"
}
Response fields
| Field | Meaning |
|---|---|
request_id | Unique id of this request. Quote it when you contact support. |
endpoint | The endpoint id, for example mail.spf. |
schema_version | Version of the response format, currently 1.0. |
checked_at | When the check ran (ISO 8601, UTC). |
status | ok, info, warning or error from the worst finding, or unknown when the check was incomplete. unknown is not an error in the domain. |
data | The check's own data. Its fields are listed below. |
findings | What was found: code, severity, message, explanation and evidence. |
meta | Duration, cache use, resolver and how long the result stays fresh. |
Fields in data
| Field | Type |
|---|---|
domain | string |
address_family | one of ipv4, ipv6 or null |
tls_version | string or null |
cipher | string or null |
trusted | boolean or null |
untrusted_reason | one of self_signed, unknown_issuer, incomplete_chain, other or null |
hostname_match | boolean or null |
subject_cn | string or null |
san | array of string |
issuer | string or null |
not_before | string or null |
not_after | string or null |
days_remaining | integer or null |
serial_number | string or null |
signature_algorithm | string or null |
key_type | one of rsa, ec, ed25519, ed448, dsa, other or null |
key_bits | integer or null |
chain | array of ChainCertificate |
Status codes
| Status | Code | Meaning | Do you pay? |
|---|---|---|---|
| 200 | — | The result is delivered, also when it has negative findings. | Yes: charged once per payment; redelivery of the same payment is free |
| 402 | — | Payment is required, or the attached payment was refused. The body states the price. | No |
| 400 | bad_request | The request is malformed. | No |
| 409 | payment_in_progress, payment_bound_to_other_request | This payment is already being processed, or it is bound to a different request. No new payment is taken. | No |
| 422 | invalid_input | The input failed validation on a request that carries a payment; nothing is charged. Without a payment, invalid input gets a 402 whose error field names the problem. | No |
| 429 | rate_limited | Too many requests from this IP address or payer. | No |
| 502 | check_failed | The check could not be completed. | No |
| 503 | busy, unavailable, payments_unavailable | The service is busy or temporarily unavailable. | No |
| 504 | deadline_exceeded | The check ran out of time. | No |
Errors use the common error body. See errors.
Findings this endpoint can return
TLS certificate (8)
- Error
TLS_CERT_EXPIREDThe TLS certificate has expired. - Info
TLS_CERT_EXPIRINGThe TLS certificate expires within 30 days. - Warning
TLS_CERT_EXPIRING_SOONThe TLS certificate expires in less than 14 days. - Error
TLS_HOSTNAME_MISMATCHThe TLS certificate is not valid for the domain name. - Error
TLS_UNAVAILABLENo TLS connection to the domain on port 443 could be made. - Error
TLS_UNTRUSTEDThe TLS certificate does not chain to a trusted certificate authority. - Warning
TLS_WEAK_KEYThe TLS certificate uses a weak public key. - Warning
TLS_WEAK_SIGNATUREA certificate in the chain is signed with SHA-1 or MD5.