REST API v1 · бесплатно · без ключей · CORS включён
Бесплатный API для подписей
Проверки, на которых работают инструменты ecdsa.com, можно вызывать из скриптов, CI и ИИ-агентов: проверку подписей ECDSA, преобразование DER ⇄ raw, декодирование и проверку JWT с ES256/ES384/ES512, декодирование сертификатов X.509, оценку состояния TLS-подписей домена. Обычный JSON по HTTPS — https://ecdsa.com/api/v1
curl -s https://ecdsa.com/api/v1Машиночитаемая спецификация: /api/v1/openapi.json (OpenAPI 3.1)
Что умеет API
Каждая операция — чистая функция от входных данных: отправляете JSON, получаете JSON. У каждой есть справочная страница с полями, примером, который можно запустить, и кодами ошибок.
- 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
ИИ-агенты и ассистенты в IDE вызывают те же операции через MCP-сервер. Полный справочник API
Первый вызов за 30 секунд
Вставьте один из этих примеров в терминал или консоль браузера. Пример настоящий: подпись проходит проверку с этим ключом.
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": []
}Это ответ API именно на этот запрос.
Дальше: все поля и параметры этой операции — в справочнике API, а значение каждой ошибки — в таблице ошибок.
Основное
Бесплатно, без ключей
Без регистрации, без токенов, без квот, за которыми нужно следить. Отправьте запрос — получите JSON. Необязательные API-ключи с более высокими лимитами появятся вместе с аккаунтами ecdsa.com.
60 запросов в минуту с одного IP
С запасом для скриптов и CI. У операции проверки состояния домена есть дополнительный лимит — 10 в минуту, потому что она обращается к внешним серверам.
CORS открыт
Access-Control-Allow-Origin: * в каждом ответе: вызывайте API прямо из браузера, со страницы документации или из бессерверной функции.
Никогда не отправляйте закрытые ключи
Запросы, содержащие блок PEM PRIVATE KEY, закрытый ключ OpenSSH, SSH2 или PuTTY либо JWK с параметром «d», отклоняются с кодом private_key_rejected. Для всего секретного используйте локальные инструменты в браузере: они никогда не передают введённые данные.
Ничего не пишется в логи
Тела запросов разбираются в памяти и никогда не записываются в логи.
Лимиты запросов
60 запросов в минуту с одного IP на весь API и ещё 10 в минуту для /v1/health/{domain}: этот эндпоинт открывает исходящие TLS-соединения.
Каждый ответ содержит заголовки X-RateLimit-Limit, X-RateLimit-Remaining и X-RateLimit-Reset; при превышении лимита приходит ответ 429 с заголовком Retry-After.
Настоящие сканирования домена расходуют ещё и общие для всех лимиты: один хост сканируется не чаще 6 раз за 10 минут, а все сканирования вместе — не чаще 300 раз в минуту, поэтому через API нельзя завалить сервер запросами. Ответы из часового кеша лимиты не расходуют; на сканирование сверх лимита приходит ответ 429 с кодом rate_limited и заголовком Retry-After.
С API-ключом лимиты считаются по ключу, а не по IP: 120 в минуту на бесплатном тарифе и 600 на тарифе Pro, а вызовы расходуют дневную и месячную квоты аккаунта. Ключи появятся вместе с аккаунтами ecdsa.com, а пока создать их нельзя, поэтому все вызовы анонимные.
В планах — больше вызовов и мониторинг: посмотрите тарифы и запишитесь в список ожидания.
Считайте указанные в документации цифры расчётным объёмом, а не жёстким потолком: получив 429, вежливо снижайте частоту запросов и кешируйте результаты на своей стороне — результаты проверки состояния домена и так кешируются на час.
Ошибки
Каждая ошибка — это JSON с машиночитаемым кодом и понятным человеку сообщением, которое точно говорит, что не так во входных данных: это те же объяснения, что показывают инструменты в браузере. Ответы с ошибкой ссылаются на эту страницу в поле docs.
| Код | HTTP | Значение |
|---|---|---|
| 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. |
Что делать при каждом коде и при каких кодах SDK повторяют запрос
Что ещё посмотреть
- Справочник APIВсе операции с полями, примерами на curl, JavaScript и Python и кодами ошибок.
- Коды ошибокВсе 25 кодов: HTTP-статус, когда возникает, что делать и стоит ли повторять запрос.
- Журнал измененийЧто уже изменилось в v1 и что изменится с появлением API-ключей.
- MCP-серверПодключите инструменты ecdsa.com к Claude, Cursor или VS Code одной строкой — ключ не нужен.
- SDKСкоро появятся официальные SDK для 8 языков
Журнал изменений
Последний релиз: v1.1.0, 22 октября 2026 г.. Версия API указана в пути; несовместимые изменения, если они понадобятся, выйдут как /api/v2 — в ответах v1 могут появляться новые поля, но существующие не исчезнут и не изменятся.