CSR.plus API Reference

Automate the whole SSL/TLS certificate lifecycle with a single open REST API — CSR generation, decoding, A–F grading, certificate transparency, CAA, revocation and TLS tracing. Free, unauthenticated, no API keys.

Try the API live

Overview

The CSR.plus API is a collection of read-only and generation endpoints that power our web tools. Every endpoint returns JSON, supports CORS for browser clients, and is rate-limited per IP address. Keys and CSRs are generated in memory and never stored.

Everything you need: generate a CSR and private key, decode any CSR, grade a deployment from A to F, search certificate transparency logs, check CAA records, verify revocation status and trace a full TLS handshake.

Base URL & authentication

Base URL
https://csr.plus

All endpoints are served over HTTPS. No authentication is required — the API is open and unauthenticated by design. There are no API keys, tokens or billing. Requests are identified by IP address for rate limiting only.

All responses include CORS headers (Access-Control-Allow-Origin: *), so you can call the API directly from browsers and client-side scripts.

Rate limits

EndpointLimitWindow
/api/generate10 requestsper minute per IP
/api/ssl-check, /api/ct, /api/caa30 requestsper minute per IP
/api/revocation, /api/ssl-tracer20 requestsper minute per IP
/api/decode, /api/openssl-traceNot limited—

Exceeding a limit returns HTTP 429 with a Retry-After header indicating how many seconds to wait.

POST/api/generate

Generate a certificate signing request and a private key. Rate limit: 10 requests per minute per IP.

Request body

ParameterTypeRequiredDescription
common_namestringYesPrimary domain (e.g. example.com)
sansarrayNoAdditional subject alternative names, e.g. ["www.example.com"]
organizationstringNoOrganization name (O)
org_unitstringNoOrganizational unit (OU)
countrystringNoTwo-letter country code (C), e.g. "US"
statestringNoState or province (ST)
localitystringNoLocality / city (L)
emailstringNoContact email address
key_typestringNo"rsa" (default) or "ecdsa"
key_sizestring|intNoRSA: 2048 (default) / 3072 / 4096 · ECDSA: "P-256" (default) / "P-384"
passphrasestringNoEncrypts the private key as encrypted PKCS#8 PEM (max 200 chars)

Response fields

FieldDescription
csrCertificate signing request in PEM format (PKCS#10, SHA-256 signature)
private_keyPrivate key in PEM format (PKCS#8; encrypted PKCS#8 when a passphrase is supplied)
algorithmAlgorithm used, e.g. "RSA-2048" or "ECDSA-P-256"
created_atISO 8601 timestamp of generation
Example request (cURL)
curl -X POST https://csr.plus/api/generate \
  -H "Content-Type: application/json" \
  -d '{
    "common_name": "example.com",
    "sans": ["www.example.com", "api.example.com"],
    "organization": "Example Inc",
    "country": "US",
    "key_type": "rsa",
    "key_size": 2048
  }'
Example response
{
  "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIICzDCCAbQCAQAwgYwxCzAJBgNVBAYTAVVT...\n-----END CERTIFICATE REQUEST-----",
  "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASC...\n-----END PRIVATE KEY-----",
  "algorithm": "RSA-2048",
  "created_at": "2026-08-14T10:30:00.000Z"
}
Verify the result with OpenSSL
openssl req -verify -noout -in example.com.csr
openssl req -in example.com.csr -text -noout | head -20
POST/api/decode

Parse any PKCS#10 CSR and return its subject, subject alternative names, public key, signature verification and extensions.

Request body

ParameterTypeRequiredDescription
csrstringYesThe CSR in PEM format (-----BEGIN CERTIFICATE REQUEST-----)
Example request (cURL)
curl -X POST https://csr.plus/api/decode \
  -H "Content-Type: application/json" \
  -d '{"csr": "-----BEGIN CERTIFICATE REQUEST-----\n..."}'
Example response
{
  "success": true,
  "subject": {
    "commonName": "example.com",
    "organization": "Example Inc",
    "organizationalUnit": null,
    "country": "US",
    "state": "California",
    "locality": "San Francisco",
    "email": null
  },
  "publicKey": { "type": "RSA", "size": 2048 },
  "signature": { "algorithm": "sha256WithRSAEncryption", "verified": true },
  "sanList": ["example.com", "www.example.com", "api.example.com"],
  "extensions": [],
  "size": 640,
  "version": 0,
  "timestamp": "2026-08-14T10:30:00.000Z"
}

Note: dcvInfo contains domain control validation hints (HTTP token files and a CNAME record) useful when completing CA validation steps.

GET/api/ssl-check?domain={domain}

Full SSL/TLS check with an SSL Labs-style A–F grade: certificate validity, hostname match, chain trust, TLS version probes and HSTS inspection.

Query parameters

ParameterTypeRequiredDescription
domainstringYesHostname to check (port 443 is assumed)
Example request
curl "https://csr.plus/api/ssl-check?domain=example.com"
Example response
{
  "success": true,
  "domain": "example.com",
  "grade": {
    "letter": "A+",
    "score": 100,
    "label": "Excellent configuration with HSTS",
    "checks": [
      { "name": "Hostname match", "status": "pass", "detail": "Certificate covers the requested hostname" },
      { "name": "TLS 1.3", "status": "pass", "detail": "TLS 1.3 is supported" }
    ]
  },
  "cert": {
    "subject": "CN=example.com",
    "issuer": "CN=R10,O=Let's Encrypt,C=US",
    "validFrom": "2026-05-14T00:00:00.000Z",
    "validTo": "2026-08-12T00:00:00.000Z",
    "daysRemaining": 30,
    "san": ["example.com", "www.example.com"]
  },
  "tls": { "tls13": true, "tls12": true, "tls11": false, "tls10": false, "protocol": "TLSv1.3" },
  "hsts": { "present": true, "maxAge": 31536000, "includeSubDomains": true, "preload": false }
}
GET/api/ct?domain={domain}

Search public certificate transparency logs for every certificate ever issued to a domain. Falls back to Cert Spotter when crt.sh is unavailable.

Query parameters

ParameterTypeRequiredDescription
domainstringYesDomain to search in CT logs
Example request
curl "https://csr.plus/api/ct?domain=example.com"
Example response
{
  "success": true,
  "count": 12,
  "source": "crt.sh",
  "certs": [
    {
      "id": 123456,
      "logged_at": "2026-08-01T12:00:00.000Z",
      "not_before": "2026-07-15T00:00:00.000Z",
      "not_after": "2026-10-13T00:00:00.000Z",
      "common_name": "example.com",
      "name_value": "example.com\nwww.example.com"
    }
  ]
}

The response includes source (crt.sh or certspotter) so you can tell which provider served the data.

GET/api/caa?domain={domain}

Return the DNS CAA records for a domain together with A, AAAA, NS and MX records, showing which certificate authorities are authorized to issue certificates.

Query parameters

ParameterTypeRequiredDescription
domainstringYesDomain to query
Example request
curl "https://csr.plus/api/caa?domain=example.com"
Example response
{
  "success": true,
  "domain": "example.com",
  "caa": [
    { "flags": 0, "tag": "issue", "value": "letsencrypt.org" },
    { "flags": 0, "tag": "iodef", "value": "mailto:[email protected]" }
  ],
  "a": ["93.184.216.34"],
  "aaaa": ["2606:2800:220:1:248:1893:25c8:1946"],
  "ns": ["a.iana-servers.net"],
  "mx": [],
  "caaError": ""
}
GET/api/revocation?domain={domain}

Fetch the certificate currently served by a domain and report its CRL distribution points and OCSP responder endpoints.

Query parameters

ParameterTypeRequiredDescription
domainstringYesDomain whose serving certificate is inspected
Example request
curl "https://csr.plus/api/revocation?domain=example.com"
Example response
{
  "success": true,
  "domain": "example.com",
  "serial": "03F2A1B3C4D5E6F7",
  "crlUrls": ["http://crl.letsencrypt.org/r3.crl"],
  "ocspUrls": ["http://r3.o.lencr.org"],
  "status": "good"
}
GET/api/ssl-tracer?domain={domain}&port={port}

Perform a real TLS handshake against any host and port, recording DNS resolution, TCP connectivity, negotiated TLS version and cipher, and the full certificate chain.

Query parameters

ParameterTypeRequiredDescription
domainstringYesHostname to connect to
portintNoTCP port (default 443)
Example request
curl "https://csr.plus/api/ssl-tracer?domain=example.com&port=443"
Example response
{
  "success": true,
  "host": "example.com",
  "port": 443,
  "dns": { "ips": ["93.184.216.34"], "ms": 12 },
  "tcp": { "ok": true, "ms": 38 },
  "tls": { "version": "TLSv1.3", "cipher": "TLS_AES_128_GCM_SHA256", "weak": false },
  "certs": [
    {
      "subject": { "CN": "example.com" },
      "issuer": { "CN": "R10", "O": "Let's Encrypt", "C": "US" },
      "serialNumber": "03F2A1B3C4D5E6F7",
      "notBefore": "2026-05-14T00:00:00.000Z",
      "notAfter": "2026-08-12T00:00:00.000Z",
      "daysRemaining": 30,
      "expired": false,
      "isCA": false,
      "isSelfSigned": false,
      "keyType": "RSA",
      "keySize": 2048,
      "sha256": "E8:2F:0A:..."
    }
  ],
  "chainComplete": true,
  "chainNote": "Chain resolves to a trusted root",
  "errors": []
}
GET/api/openssl-trace?domain={domain}

Run a raw openssl s_client handshake against a domain and return the complete verbose output — useful for debugging certificate chain and protocol issues.

Query parameters

ParameterTypeRequiredDescription
domainstringYesDomain to trace (port 443 is assumed)
Example request
curl "https://csr.plus/api/openssl-trace?domain=example.com"
Example response
{
  "success": true,
  "output": "CONNECTED(00000005)\ndepth=2 C=US, O=Internet Security Research Group...\nverify return:1\n..."
}

Error codes

Errors are returned as JSON with an error message and, where applicable, an errorId for programmatic handling.

StatuserrorIdMeaning
400invalid_jsonRequest body is not valid JSON
400invalid_common_namecommon_name is missing or longer than 253 characters
400invalid_key_typekey_type must be "rsa" or "ecdsa"
400invalid_key_sizeRSA sizes must be 2048/3072/4096; ECDSA curves must be "P-256"/"P-384"
400invalid_passphrasepassphrase must be a non-empty string (max 200 characters)
400invalid_json_formatRequest body or fields are malformed
405method_not_allowedOnly POST is accepted on /api/generate
413payload_too_largeRequest body too large (limit 10 KB)
429rate_limit_exceededRate limit exceeded — retry after the Retry-After header
500generation_failedInternal error during key/CSR generation

Best practices

  • Generate private keys locally with OpenSSL or node-forge for production workloads. The API is designed for development, testing and light automation.
  • Set a passphrase when the key needs to be stored or transferred between systems.
  • Use RSA 2048 or ECDSA P-256 unless compliance rules require stronger keys.
  • Honor the Retry-After header instead of hammering the API after a 429.
  • Validate domain parameters client-side (max 253 chars, alphanumeric, dots and dashes) before calling read-only endpoints.
  • Never log the private_key field from API responses.

More examples

Python (requests)
import requests

r = requests.post(
    "https://csr.plus/api/generate",
    json={"common_name": "example.com", "sans": ["www.example.com"]},
)
r.raise_for_status()
data = r.json()

open("example.com.csr", "w").write(data["csr"])
open("example.com.key", "w").write(data["private_key"])
Node.js (fetch)
const res = await fetch("https://csr.plus/api/generate", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ common_name: "example.com", key_type: "ecdsa", key_size: "P-256" }),
});
const { csr, private_key } = await res.json();
console.log(csr);

Try the API live

Pick an endpoint, fill in the parameters and run a real request against the production API.

FAQ

What is the API rate limit?

CSR generation allows 10 requests per minute per IP address. SSL check, CT and CAA allow 30 per minute; revocation and TLS tracer allow 20 per minute. Exceeding a limit returns HTTP 429 with a Retry-After header.

What key types are supported?

RSA 2048/3072/4096 and ECDSA P-256/P-384. Pass the key_type and key_size parameters in the request body.

Can I encrypt the generated private key?

Yes. Add a passphrase field to the request and the private key is returned encrypted as an encrypted PKCS#8 PEM key.

Does the API store my private key?

No. Keys and CSRs are generated in memory and never persisted, logged or stored on disk. Use the API for development and testing.

What CAs accept CSRs generated by this API?

The API produces standard PKCS#10 CSRs with SHA-256 signatures that are accepted by all major certificate authorities, including Let’s Encrypt, DigiCert, Sectigo and Google Trust Services.