API REST v1 · gratuita · sem chaves · CORS habilitado
API de assinaturas gratuita
As verificações por trás das ferramentas do ecdsa.com, que podem ser chamadas a partir de scripts, CI e agentes de IA: verifique assinaturas ECDSA, converta DER ⇄ raw, decodifique e verifique JWTs ES256/ES384/ES512, decodifique certificados X.509 e dê uma nota à saúde das assinaturas TLS de um domínio. JSON simples via HTTPS — https://ecdsa.com/api/v1
curl -s https://ecdsa.com/api/v1Especificação legível por máquina: /api/v1/openapi.json (OpenAPI 3.1)
O que a API faz
Toda operação é uma função pura da entrada: você envia JSON e recebe JSON. Cada uma tem uma página de referência com seus campos, um exemplo executável e seus códigos de erro.
- 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
Agentes de IA e assistentes de IDE chamam as mesmas operações pelo servidor MCP. Referência completa da API
Sua primeira chamada em 30 segundos
Cole um destes trechos em um terminal ou no console do navegador. O exemplo é real: a assinatura passa na verificação com essa chave.
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": []
}Esta é a resposta da API para exatamente esta requisição.
Próximo passo: todos os campos e opções desta operação na referência da API e o significado de cada erro na tabela de erros.
O básico
Gratuita, sem chaves
Sem cadastro, sem tokens, sem cotas para gerenciar. Envie uma requisição e receba JSON de volta. Chaves de API opcionais, com limites maiores, virão com as contas do ecdsa.com.
60 requisições/min por IP
Limite generoso para scripts e CI. A operação de health check de domínio tem uma cota adicional de 10 por minuto, porque faz varreduras em servidores externos.
CORS aberto
Access-Control-Allow-Origin: * em todas as respostas — chame a API direto de um navegador, de uma página de documentação ou de uma função serverless.
Nunca envie chaves privadas
Requisições que contêm um bloco PEM PRIVATE KEY, uma chave privada OpenSSH, SSH2 ou PuTTY, ou uma JWK com “d” são recusadas com private_key_rejected. Para qualquer coisa secreta, use as ferramentas locais no navegador — elas nunca transmitem os dados de entrada.
Nada é registrado em log
Os corpos das requisições são processados em memória e nunca gravados em logs.
Limites de taxa
60 requisições por minuto por IP na API inteira, mais 10 por minuto para /v1/health/{domain}, que abre conexões TLS de saída.
Toda resposta traz X-RateLimit-Limit, X-RateLimit-Remaining e X-RateLimit-Reset; ultrapassar um limite retorna 429 com um cabeçalho Retry-After.
As varreduras reais de um domínio também consomem cotas compartilhadas por todos: um host é varrido no máximo 6 vezes a cada 10 minutos, e todas as varreduras juntas, no máximo 300 vezes por minuto, para que a API não possa ser usada para inundar um servidor. Respostas vindas do cache de uma hora não consomem nada; uma varredura além de uma cota recebe como resposta 429 rate_limited e Retry-After.
Com uma chave de API, o limite passa a ser por chave — 120 por minuto no plano gratuito, 600 no plano pro — e as chamadas consomem as cotas diárias e mensais da conta. As chaves virão com as contas do ecdsa.com e ainda não podem ser criadas; até lá, toda chamada é anônima.
Mais chamadas e monitoramento estão nos planos: veja os preços e entre na lista de espera.
Trate os números documentados como a cota prevista, não como um teto rígido: diante de um 429, espere educadamente antes de tentar de novo e mantenha um cache do seu lado — os resultados do health check de domínio já ficam em cache por uma hora.
Erros
Todo erro é um JSON com um código legível por máquina e uma mensagem legível por humanos que diz exatamente o que estava errado na entrada — as mesmas explicações que as ferramentas no navegador mostram. As respostas de erro apontam para cá no campo docs.
| Código | HTTP | Significado |
|---|---|---|
| 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. |
O que fazer com cada código e quais deles os SDKs tentam de novo
Explorar
- Referência da APITodas as operações, com seus campos, exemplos em curl, JavaScript e Python e seus códigos de erro.
- Códigos de erroTodos os 25 códigos: status HTTP, quando ocorre, o que fazer, se convém tentar de novo.
- Registro de alteraçõesO que mudou na v1 até agora e o que muda quando as chaves de API forem lançadas.
- Servidor MCPDê ao Claude, ao Cursor ou ao VS Code as ferramentas do ecdsa.com com uma linha — sem precisar de chave.
- SDKsSDKs oficiais para 8 linguagens estão a caminho
Registro de alterações
Versão mais recente: v1.1.0, 22 de outubro de 2026. A versão da API faz parte do caminho; mudanças incompatíveis sairiam como /api/v2 — as respostas da v1 podem ganhar campos, mas não vão perdê-los nem alterá-los.