HSTS header parser API
Reads a Strict-Transport-Security value as RFC 6797 does: whether browsers accept it, max-age, includeSubDomains and preload, and which of the hstspreload.org header rules it meets. The same reader as the security headers check. Nothing is fetched.
POST https://api.lookproof.dev/v1/http/hsts-parse
Updated 2026-10-09
Examples use the Base (eip155:8453) network.
Input
A JSON body with content-type: application/json.
| Name | Type | Required | Limits | Description |
|---|---|---|---|---|
header | string | Yes | 1–8192 characters | A Strict-Transport-Security value, at most 8192 characters; the header name in front is optional. |
Example request
curl -i -X POST https://api.lookproof.dev/v1/http/hsts-parse \
-H 'content-type: application/json' \
-d '{"header": "max-age=63072000; includeSubDomains; preload"}'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.post('https://api.lookproof.dev/v1/http/hsts-parse', json={'header': 'max-age=63072000; includeSubDomains; preload'})
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/http/hsts-parse", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({"header": "max-age=63072000; includeSubDomains; preload"}),
});
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": {
"directives": [
"max-age",
"includesubdomains",
"preload"
],
"header_name": null,
"include_subdomains": true,
"max_age": 63072000,
"notes": [
"Only the pasted text is read; whether a site sends this header is not checked.",
"hstspreload.org also needs the site to redirect http to https on the same host and to send the header on the registrable domain over HTTPS; that needs a live check."
],
"preload": true,
"preload_eligible": true,
"preload_missing": [],
"valid": true
},
"endpoint": "http.hsts_parse",
"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": "offline"
},
"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 |
|---|---|
header_name | string or null |
valid | boolean |
max_age | integer or null |
include_subdomains | boolean |
preload | boolean |
directives | array of string |
preload_eligible | boolean |
preload_missing | array of string |
notes | array of string |
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 |
| 413 | payload_too_large | The body is larger than 64 KB. | 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
HSTS (5)
- Error
HSTS_INVALIDBrowsers ignore this Strict-Transport-Security value. - Warning
HSTS_MAX_AGE_ZEROmax-age=0 tells browsers to forget the HSTS policy. - Info
HSTS_NO_INCLUDE_SUBDOMAINSThe HSTS policy does not cover subdomains. - Warning
HSTS_PRELOAD_NOT_ELIGIBLEThe value asks for preloading but does not meet the preload list's rules. - Info
HSTS_SHORT_MAX_AGEThe HSTS max-age is shorter than one year.