API REST v1 · gratuite · sans clé · CORS activé
API de signature gratuite
Les vérifications sur lesquelles reposent les outils d’ecdsa.com, accessibles depuis des scripts, la CI et des agents IA : vérifiez des signatures ECDSA, convertissez DER ⇄ brut, décodez et vérifiez des JWT ES256/ES384/ES512, décodez des certificats X.509, notez la santé des signatures TLS d’un domaine. Du JSON simple sur HTTPS : https://ecdsa.com/api/v1
curl -s https://ecdsa.com/api/v1Spécification lisible par machine : /api/v1/openapi.json (OpenAPI 3.1)
Ce que fait l’API
Chaque opération est une fonction pure de son entrée : vous envoyez du JSON, vous recevez du JSON. Chacune a sa page de référence, avec ses champs, un exemple exécutable et ses codes d’erreur.
- POST/v1/verifyVerify an ECDSA signature
- POST/v1/convertConvert a signature between DER and raw r‖s
- POST/v1/jwt/decodeDecode a JWT (no signature check)
- POST/v1/jwt/verifyVerify an ES256/ES384/ES512 JWT signature
- POST/v1/cert/decodeDecode an X.509 certificate or chain
- GET/v1/health/{domain}TLS signature-health grade for a domain
- GET/v1/webhooksList webhook endpoints
- POST/v1/webhooksCreate a webhook endpoint
- POST/v1/webhooks/deleteDelete a webhook endpoint
- POST/v1/webhooks/testSend a test event
Les agents IA et les assistants d’IDE appellent les mêmes opérations via le serveur MCP. Référence complète de l’API
Votre premier appel en 30 secondes
Collez l’un de ces extraits dans un terminal ou dans la console d’un navigateur. L’exemple est réel : la signature se vérifie bien avec la clé.
curl -sS 'https://ecdsa.com/api/v1/verify' \
-H 'content-type: application/json' \
-d '{
"publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4+8TCP3Hop/Acb8L7reksO9flyt1\nsUhvEqUs7a45RVDRDtAIZdTnOJcAhTCQvdzUBO4KUyxSRcZm6ro+2RGfSQ==\n-----END PUBLIC KEY-----",
"message": "The quick brown fox jumps over the lazy dog",
"signature": "3045022100df542bb71e0e3019086f1b1ba51f1aa0ec5e6afca05c3f5a7f4f02f5b7c39d24022030c59f1ac6d8c6893fb2a5ac8dfd9388d31ebd3382510dcfb7f28f9182eb1131"
}'const response = await fetch("https://ecdsa.com/api/v1/verify", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
"publicKey": "-----BEGIN PUBLIC KEY-----\nMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE4+8TCP3Hop/Acb8L7reksO9flyt1\nsUhvEqUs7a45RVDRDtAIZdTnOJcAhTCQvdzUBO4KUyxSRcZm6ro+2RGfSQ==\n-----END PUBLIC KEY-----",
"message": "The quick brown fox jumps over the lazy dog",
"signature": "3045022100df542bb71e0e3019086f1b1ba51f1aa0ec5e6afca05c3f5a7f4f02f5b7c39d24022030c59f1ac6d8c6893fb2a5ac8dfd9388d31ebd3382510dcfb7f28f9182eb1131"
}),
});
console.log(response.status, await response.json());{
"valid": true,
"curve": "P-256",
"curvesTried": [
"P-256"
],
"keySource": "pem-spki",
"signatureFormat": "der",
"details": {
"r": "df542bb71e0e3019086f1b1ba51f1aa0ec5e6afca05c3f5a7f4f02f5b7c39d24",
"s": "30c59f1ac6d8c6893fb2a5ac8dfd9388d31ebd3382510dcfb7f28f9182eb1131",
"highS": false
},
"notes": []
}Voici la réponse de l’API à cette requête précise.
Ensuite : tous les champs et options de cette opération dans la référence de l’API, et la signification de chaque erreur dans le tableau des erreurs.
L’essentiel
Gratuit et sans clé
Pas d’inscription, pas de jetons, pas de quotas à gérer. Envoyez une requête, recevez du JSON. Des clés d’API facultatives, avec des limites plus élevées, arriveront avec les comptes ecdsa.com.
60 requêtes/min par IP
Largement suffisant pour les scripts et la CI. L’opération qui évalue la santé des domaines ajoute un budget de 10 par minute, car elle lance des analyses vers l’extérieur.
CORS ouvert
Access-Control-Allow-Origin: * sur chaque réponse : appelez l’API directement depuis un navigateur, une page de documentation ou une fonction sans serveur.
N’envoyez jamais de clé privée
Les requêtes contenant un bloc PEM PRIVATE KEY, une clé privée OpenSSH, SSH2 ou PuTTY, ou une JWK avec « d » sont refusées avec private_key_rejected. Pour tout ce qui est secret, utilisez les outils qui fonctionnent en local dans votre navigateur : ils ne transmettent jamais votre saisie.
Aucune journalisation
Les corps de requête sont analysés en mémoire et ne sont jamais écrits dans les journaux.
Limites de requêtes
60 requêtes par minute et par IP sur l’ensemble de l’API, plus 10 par minute pour /v1/health/{domain}, qui ouvre des connexions TLS sortantes.
Chaque réponse porte les en-têtes X-RateLimit-Limit, X-RateLimit-Remaining et X-RateLimit-Reset ; un dépassement de limite renvoie 429 avec un en-tête Retry-After.
Les analyses réelles d’un domaine puisent aussi dans des budgets partagés par tous : un même hôte est analysé au plus 6 fois toutes les 10 minutes, et l’ensemble des analyses au plus 300 fois par minute, pour que l’API ne puisse pas servir à submerger un serveur. Les réponses servies depuis le cache d’une heure ne consomment rien ; une analyse au-delà d’un budget reçoit la réponse 429 rate_limited avec Retry-After.
Avec une clé d’API, les appels sont limités par clé et non plus par IP (120 par minute avec l’offre gratuite, 600 avec l’offre Pro), et puisent dans les quotas quotidiens et mensuels du compte. Les clés arriveront avec les comptes ecdsa.com et ne peuvent pas encore être créées ; d’ici là, tous les appels sont anonymes.
Des volumes d’appels plus importants et la surveillance sont prévus : consultez les tarifs et inscrivez-vous sur la liste d’attente.
Considérez les chiffres documentés comme le budget prévu, pas comme un plafond strict : en cas de 429, ralentissez poliment, et mettez en cache de votre côté (les résultats de santé des domaines sont déjà mis en cache pendant une heure).
Erreurs
Chaque erreur est un objet JSON contenant un code lisible par machine et un message lisible par un humain. Ce message indique exactement ce qui n’allait pas dans l’entrée, avec les mêmes explications que celles qu’affichent les outils dans le navigateur. Les réponses d’erreur renvoient vers cette page dans leur champ docs.
| Code | HTTP | Signification |
|---|---|---|
| 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. |
| unsupported_algorithm | 400 | The token's algorithm is not one this operation verifies. |
| invalid_domain | 400 | Not a public DNS hostname (IP addresses, single-label names and paths are refused). |
| scan_dns_error | 400 | The domain does not resolve in public DNS. |
| scan_private_address | 400 | The domain resolves (at least partly) to a private or reserved address. |
| webhook_url_refused | 400 | The webhook URL cannot receive deliveries: it is not https on port 443, its host is not a public DNS name, or the name does not resolve or resolves (at least partly) to a private or reserved address. |
| 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. |
| webhook_limit_reached | 403 | The account already has as many webhook endpoints as its plan allows. |
| not_found | 404 | No operation exists at this path. |
| webhook_not_found | 404 | The API key's account has no webhook endpoint with this id. |
| 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. |
| scan_unreachable | 502 | The domain refused or dropped the connection on port 443. |
| scan_tls_error | 502 | The TLS handshake failed or presented no usable certificate. |
| service_unavailable | 503 | API keys cannot be verified right now (the key store is unreachable); retry shortly. |
| webhooks_unavailable | 503 | Webhooks are switched off on this server: it has no signing keys configured. |
| scan_timeout | 504 | The scan did not finish in time. |
| timeout | 504 | The operation did not finish within its time budget. |
Que faire pour chaque code, et lesquels sont retentés par les SDK
Explorer
- Référence de l’APIChaque opération avec ses champs, des exemples en curl, JavaScript et Python, et ses codes d’erreur.
- Codes d’erreurTous les 25 codes : statut HTTP, circonstances, marche à suivre, nouvelle tentative ou non.
- Journal des modificationsCe qui a changé dans la v1 jusqu’ici, et ce qui changera à l’arrivée des clés d’API.
- Serveur MCPDonnez à Claude, Cursor ou VS Code les outils d’ecdsa.com en une seule ligne, sans clé.
- SDKDes SDK officiels pour 8 langages sont en préparation
Journal des modifications
Dernière version : v1.1.0, 22 octobre 2026. La version de l’API figure dans le chemin ; des changements incompatibles seraient publiés sous /api/v2 : les réponses v1 peuvent s’enrichir de nouveaux champs, mais aucun champ existant ne sera supprimé ni modifié.