Certificates
Decode an X.509 certificate or chain
https://ecdsa.com/api/v1/cert/decodeAccepts PEM (one or more CERTIFICATE blocks — a whole chain works) or a single DER certificate as base64/hex. Returns a structured summary per certificate — subject, issuer, validity, key and signature algorithms, SAN, key usage, fingerprint — plus assessments (weak hashes, expiry, CA/Browser Forum lifetime limits, post-quantum notes).
- API-Schlüssel
- Optional; ein Schlüssel braucht den Scope api
- Kontingentverbrauch mit Schlüssel
- 1 Einheit pro Aufruf
- Rate Limit
- 60 Anfragen/min pro IP
Anfrage
JSON-Body: CertDecodeRequest
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| certificate | string | ja | PEM with one or more CERTIFICATE blocks (chains welcome), or one DER certificate as base64/hex. |
Antworten
200Decoded certificates with assessments.
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| certificates | CertificateSummary[] | ja | |
| notes | string[] | ja | Per-block problems and skipped-block notes. |
Header: X-Request-Id · X-RateLimit-Limit · X-RateLimit-Remaining · X-RateLimit-Reset · X-Quota-Limit · X-Quota-Remaining · X-Quota-Reset
| Status | Bedeutung | Codes |
|---|---|---|
| 400 | Bad request. Input limits: a request body of at most 100 KB (a larger one is answered with 413) and arrays and objects nested at most 64 levels deep, JSON documents inside string fields included. | |
| 401 | Unauthorized. | |
| 403 | Forbidden. | |
| 404 | Not found. | |
| 405 | Method not allowed. | |
| 413 | Payload too large. | |
| 429 | Too many requests. | |
| 500 | Internal server error. | |
| 503 | Service unavailable. | |
| 504 | Gateway timeout. |
Jede Fehlerantwort enthält das JSON-Fehlerobjekt; die Fehlertabelle erklärt, was jeder Code bedeutet und was zu tun ist.
Beispiel
A self-signed ECDSA P-256 certificate
curl -sS 'https://ecdsa.com/api/v1/cert/decode' \
-H 'content-type: application/json' \
-d '{
"certificate": "-----BEGIN CERTIFICATE-----\nMIICFjCCAbugAwIBAgIIBKGyw9Tl9gcwCgYIKoZIzj0EAwIwSDEXMBUGA1UEAxMO\nZGVtby5lY2RzYS5jb20xIDAeBgNVBAoTF0VDRFNBLmNvbSBTaWduYXR1cmUgTGFi\nMQswCQYDVQQGEwJVUzAeFw0yNjAxMTUwMDAwMDBaFw0yNzAxMTUwMDAwMDBaMEgx\nFzAVBgNVBAMTDmRlbW8uZWNkc2EuY29tMSAwHgYDVQQKExdFQ0RTQS5jb20gU2ln\nbmF0dXJlIExhYjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\nAASOtEAsuQh2j8SNY/hVbkvFlXwHUzLXZjcTsaEcuwwvXCVsldoaP1Orr1h16iU+\nqjEAP2gmZSM2XbSN3B+h59Lko4GOMIGLMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/\nBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAtBgNVHREEJjAk\ngg5kZW1vLmVjZHNhLmNvbYISd3d3LmRlbW8uZWNkc2EuY29tMB0GA1UdDgQWBBTp\nEL0Utu1R8qzHZ9IWC2WP789lqTAKBggqhkjOPQQDAgNJADBGAiEAjad1xoTy9SXd\nd8DnZMIA4jkASCGkYSc1R9io7mj83NcCIQDE0GDEHRLcXxZVdZgDcJjSPRx6cLqM\n4v4zJDEFLZ5reA==\n-----END CERTIFICATE-----"
}'const response = await fetch("https://ecdsa.com/api/v1/cert/decode", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
"certificate": "-----BEGIN CERTIFICATE-----\nMIICFjCCAbugAwIBAgIIBKGyw9Tl9gcwCgYIKoZIzj0EAwIwSDEXMBUGA1UEAxMO\nZGVtby5lY2RzYS5jb20xIDAeBgNVBAoTF0VDRFNBLmNvbSBTaWduYXR1cmUgTGFi\nMQswCQYDVQQGEwJVUzAeFw0yNjAxMTUwMDAwMDBaFw0yNzAxMTUwMDAwMDBaMEgx\nFzAVBgNVBAMTDmRlbW8uZWNkc2EuY29tMSAwHgYDVQQKExdFQ0RTQS5jb20gU2ln\nbmF0dXJlIExhYjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\nAASOtEAsuQh2j8SNY/hVbkvFlXwHUzLXZjcTsaEcuwwvXCVsldoaP1Orr1h16iU+\nqjEAP2gmZSM2XbSN3B+h59Lko4GOMIGLMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/\nBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAtBgNVHREEJjAk\ngg5kZW1vLmVjZHNhLmNvbYISd3d3LmRlbW8uZWNkc2EuY29tMB0GA1UdDgQWBBTp\nEL0Utu1R8qzHZ9IWC2WP789lqTAKBggqhkjOPQQDAgNJADBGAiEAjad1xoTy9SXd\nd8DnZMIA4jkASCGkYSc1R9io7mj83NcCIQDE0GDEHRLcXxZVdZgDcJjSPRx6cLqM\n4v4zJDEFLZ5reA==\n-----END CERTIFICATE-----"
}),
});
console.log(response.status, await response.json());import httpx
response = httpx.post(
"https://ecdsa.com/api/v1/cert/decode",
json={
"certificate": "-----BEGIN CERTIFICATE-----\nMIICFjCCAbugAwIBAgIIBKGyw9Tl9gcwCgYIKoZIzj0EAwIwSDEXMBUGA1UEAxMO\nZGVtby5lY2RzYS5jb20xIDAeBgNVBAoTF0VDRFNBLmNvbSBTaWduYXR1cmUgTGFi\nMQswCQYDVQQGEwJVUzAeFw0yNjAxMTUwMDAwMDBaFw0yNzAxMTUwMDAwMDBaMEgx\nFzAVBgNVBAMTDmRlbW8uZWNkc2EuY29tMSAwHgYDVQQKExdFQ0RTQS5jb20gU2ln\nbmF0dXJlIExhYjELMAkGA1UEBhMCVVMwWTATBgcqhkjOPQIBBggqhkjOPQMBBwNC\nAASOtEAsuQh2j8SNY/hVbkvFlXwHUzLXZjcTsaEcuwwvXCVsldoaP1Orr1h16iU+\nqjEAP2gmZSM2XbSN3B+h59Lko4GOMIGLMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/\nBAQDAgeAMB0GA1UdJQQWMBQGCCsGAQUFBwMBBggrBgEFBQcDAjAtBgNVHREEJjAk\ngg5kZW1vLmVjZHNhLmNvbYISd3d3LmRlbW8uZWNkc2EuY29tMB0GA1UdDgQWBBTp\nEL0Utu1R8qzHZ9IWC2WP789lqTAKBggqhkjOPQQDAgNJADBGAiEAjad1xoTy9SXd\nd8DnZMIA4jkASCGkYSc1R9io7mj83NcCIQDE0GDEHRLcXxZVdZgDcJjSPRx6cLqM\n4v4zJDEFLZ5reA==\n-----END CERTIFICATE-----",
},
timeout=30.0,
)
print(response.status_code, response.json()){
"certificates": [
{
"subject": "CN=demo.ecdsa.com, O=ECDSA.com Signature Lab, C=US",
"issuer": "CN=demo.ecdsa.com, O=ECDSA.com Signature Lab, C=US",
"selfSigned": true,
"serialNumber": "04:a1:b2:c3:d4:e5:f6:07",
"version": 3,
"notBefore": "2026-01-15T00:00:00.000Z",
"notAfter": "2027-01-15T00:00:00.000Z",
"validityStatus": "valid",
"daysRemaining": 87,
"lifetimeDays": 365,
"publicKeyLabel": "ECDSA P-256",
"signatureLabel": "ecdsa-with-SHA256",
"san": [
"DNS:demo.ecdsa.com",
"DNS:www.demo.ecdsa.com"
],
"keyUsage": [
"digitalSignature"
],
"extendedKeyUsage": [
"serverAuth",
"clientAuth"
],
"basicConstraints": {
"ca": false
},
"subjectKeyId": "e9:10:bd:14:b6:ed:51:f2:ac:c7:67:d2:16:0b:65:8f:ef:cf:65:a9",
"authorityKeyId": null,
"fingerprintSha256": "54:7A:73:8B:31:CE:3A:55:54:58:4B:5C:FD:D8:CE:7F:78:B7:05:15:29:A3:B7:D5:38:FA:3D:A7:93:5E:C2:CA",
"assessments": [
{
"kind": "info",
"title": "Classical algorithm — post-quantum migration ahead",
"body": "ECDSA P-256 (≈128-bit classical security) is a sound choice today. It is, however, quantum-vulnerable: NIST IR 8547 (draft) plans to disallow classical signature algorithms — ECDSA, EdDSA and RSA — after 2035. At this key size there is no earlier 2030 milestone — that step applies only to 112-bit parameter sets such as RSA-2048. No emergency — but worth an inventory: our upcoming repository scanner maps where your systems still sign with classical algorithms and the matching post-quantum migration targets."
},
{
"kind": "ok",
"title": "Within validity period",
"body": "Valid until 2027-01-15 00:00:00 UTC — 87 days remaining."
}
]
}
],
"notes": []
}Die Antwort der API auf dieses Beispiel, erzeugt für diese Seite am 20. Oktober 2026; relative Zeitangaben und Tageszahlen darin beziehen sich auf diesen Tag.
Fehlercodes
| Code | Status | Bedeutung |
|---|---|---|
| invalid_json | 400 | The body is not valid JSON or not a JSON object; or the input nests arrays and objects more than 64 levels deep (JSON documents inside string fields count too), or is too complex to inspect for private keys. |
| missing_field | 400 | A required field is absent or empty. |
| invalid_input | 400 | A field could not be parsed — the message explains exactly why. |
| private_key_rejected | 400 | The request contains private-key material (a PEM PRIVATE KEY block, an OpenSSH, SSH2 or PuTTY private key, or a JWK with "d"). Never send private keys anywhere. |
| unauthorized | 401 | The Authorization or X-API-Key header is malformed, the API key is not valid (wrong checksum, unknown, revoked or expired), or the operation needs a key. |
| forbidden_scope | 403 | The API key is valid but lacks a scope this operation requires; the message names it. |
| not_found | 404 | No operation exists at this path. |
| method_not_allowed | 405 | The path exists but does not accept this HTTP method; see the Allow header. |
| payload_too_large | 413 | The body exceeds 100 KB. |
| rate_limited | 429 | Too many requests — see Retry-After. |
| quota_exceeded | 429 | A daily or monthly quota of the API key's account is used up. X-Quota-Reset (and Retry-After) say when it starts over; retrying earlier cannot succeed. |
| internal_error | 500 | Unexpected server error. |
| service_unavailable | 503 | API keys cannot be verified right now (the key store is unreachable); retry shortly. |
| timeout | 504 | The operation did not finish within its time budget. |
Schemas
CertificateSummary
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| subject | string | ja | |
| issuer | string | ja | |
| selfSigned | boolean | ja | Subject and issuer are identical. |
| serialNumber | string | ja | Colon-separated hex. |
| version | integer | null | ja | |
| notBefore | string | ja |
|
| notAfter | string | ja |
|
| validityStatus | string | ja |
|
| daysRemaining | integer | ja | Days until notAfter (zero or negative once expired). |
| lifetimeDays | integer | ja | |
| publicKeyLabel | string | ja | |
| signatureLabel | string | ja | |
| san | string[] | ja | "DNS:example.com" style Subject Alternative Name entries. |
| keyUsage | string[] | ja | |
| extendedKeyUsage | string[] | ja | |
| basicConstraints | object | null | ja | |
| basicConstraints.ca | boolean | ja | |
| basicConstraints.pathLength | integer | nein | |
| subjectKeyId | string | null | ja | |
| authorityKeyId | string | null | ja | |
| fingerprintSha256 | string | ja | Colon-separated uppercase hex SHA-256 of the DER. |
| assessments | CertificateAssessment[] | ja |
CertificateAssessment
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| kind | string | ja |
|
| title | string | ja | |
| body | string | ja |
Error
The error envelope of every non-2xx response.
| Feld | Typ | Erforderlich | Beschreibung |
|---|---|---|---|
| error | object | ja | |
| error.code | string | ja | Machine-readable error code. Each response lists the codes it can carry; new codes may be added within v1, so treat an unknown code by its HTTP status. |
| error.message | string | ja | Human-readable explanation (English). |
| error.requestId | string | nein | The X-Request-Id of this request — quote it when reporting a problem. Sent since v1.1. |
| error.detail | object | nein | Structured context for the error, such as the offending field; omitted when there is none.
|
| error.docs | string | nein | Where the error codes are explained. Sent since v1.1.
|
Alle Operationen findest du in der API-Referenz.