Saltar al contenido
ecdsa.com

API REST v1 · gratuita · sin claves · CORS habilitado

API de firmas gratuita

Las comprobaciones que hay detrás de las herramientas de ecdsa.com, invocables desde scripts, CI y agentes de IA: verificar firmas ECDSA, convertir DER ⇄ raw, decodificar y verificar JWT ES256/ES384/ES512, decodificar certificados X.509 y calificar el estado de las firmas TLS de un dominio. JSON simple sobre HTTPS: https://ecdsa.com/api/v1

curl -s https://ecdsa.com/api/v1

Especificación legible por máquina: /api/v1/openapi.json (OpenAPI 3.1)

Qué hace la API

Cada operación es una función pura de su entrada: envías JSON y recibes JSON. Cada una tiene una página de referencia con sus campos, un ejemplo ejecutable y sus códigos de error.

Los agentes de IA y los asistentes de los IDE invocan las mismas operaciones a través del servidor MCP. Referencia completa de la API

Tu primera llamada en 30 segundos

Pega uno de estos fragmentos en una terminal o en la consola de un navegador. El ejemplo es real: la firma se verifica con la clave.

curl
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"
}'
JavaScript (fetch)
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());
Respuesta 200
{
  "valid": true,
  "curve": "P-256",
  "curvesTried": [
    "P-256"
  ],
  "keySource": "pem-spki",
  "signatureFormat": "der",
  "details": {
    "r": "df542bb71e0e3019086f1b1ba51f1aa0ec5e6afca05c3f5a7f4f02f5b7c39d24",
    "s": "30c59f1ac6d8c6893fb2a5ac8dfd9388d31ebd3382510dcfb7f28f9182eb1131",
    "highS": false
  },
  "notes": []
}

Esta es la respuesta de la API a esta misma solicitud.

Siguiente paso: todos los campos y opciones de esta operación en la referencia de la API, y qué significa cada error en la tabla de errores.

Lo básico

Gratis, sin claves

Sin registro, sin tokens, sin cuotas que gestionar. Envías una solicitud y recibes JSON. Las claves de API opcionales, con límites más altos, llegarán con las cuentas de ecdsa.com.

60 solicitudes/min por IP

Un límite generoso para scripts y CI. La operación de diagnóstico de dominios añade un cupo propio de 10 por minuto, porque escanea hacia el exterior.

CORS abierto

Access-Control-Allow-Origin: * en cada respuesta: llama a la API directamente desde un navegador, una página de documentación o una función serverless.

Nunca envíes claves privadas

Las solicitudes que contienen un bloque PEM PRIVATE KEY, una clave privada de OpenSSH, SSH2 o PuTTY, o una JWK con «d» se rechazan con private_key_rejected. Para cualquier dato secreto, usa las herramientas locales del navegador: nunca transmiten tus datos de entrada.

No se registra nada

Los cuerpos de las solicitudes se analizan en memoria y nunca se escriben en los registros.

Límites de frecuencia

60 solicitudes por minuto por IP en toda la API, más 10 por minuto para /v1/health/{domain}, que abre conexiones TLS salientes.

Cada respuesta incluye X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset; al superar un límite se devuelve 429 con un encabezado Retry-After.

Los escaneos reales de un dominio también consumen cupos compartidos por todos: un mismo host se escanea como máximo 6 veces cada 10 minutos, y todos los escaneos juntos, como máximo 300 veces por minuto, de modo que la API no se puede usar para saturar un servidor. Las respuestas servidas desde la caché de una hora no consumen nada; un escaneo que supera un cupo recibe como respuesta 429 rate_limited y Retry-After.

Con una clave de API, las llamadas se limitan por clave —120 por minuto en el plan gratuito, 600 en el plan Pro— y consumen las cuotas diarias y mensuales de la cuenta. Las claves llegarán con las cuentas de ecdsa.com y todavía no se pueden crear; hasta entonces, todas las llamadas son anónimas.

Se prevé ofrecer más llamadas y monitorización: consulta los precios y únete a la lista de espera.

Considera las cifras documentadas como el cupo previsto, no como un techo estricto: ante un 429, espera con cortesía antes de reintentar y usa tu propia caché; los resultados del diagnóstico de dominios ya se guardan en caché durante una hora.

Errores

Cada error es un JSON con un código legible por máquina y un mensaje legible por personas que dice exactamente qué estaba mal en la entrada: las mismas explicaciones que muestran las herramientas del navegador. Las respuestas de error enlazan a esta página en su campo docs.

CódigoHTTPSignificado
invalid_json400The 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_field400A required field is absent or empty.
invalid_input400A field could not be parsed — the message explains exactly why.
private_key_rejected400The 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_algorithm400The token's algorithm is not one this operation verifies.
invalid_domain400Not a public DNS hostname (IP addresses, single-label names and paths are refused).
scan_dns_error400The domain does not resolve in public DNS.
scan_private_address400The domain resolves (at least partly) to a private or reserved address.
webhook_url_refused400The 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.
unauthorized401The 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_scope403The API key is valid but lacks a scope this operation requires; the message names it.
webhook_limit_reached403The account already has as many webhook endpoints as its plan allows.
not_found404No operation exists at this path.
webhook_not_found404The API key's account has no webhook endpoint with this id.
method_not_allowed405The path exists but does not accept this HTTP method; see the Allow header.
payload_too_large413The body exceeds 100 KB.
rate_limited429Too many requests — see Retry-After.
quota_exceeded429A 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_error500Unexpected server error.
scan_unreachable502The domain refused or dropped the connection on port 443.
scan_tls_error502The TLS handshake failed or presented no usable certificate.
service_unavailable503API keys cannot be verified right now (the key store is unreachable); retry shortly.
webhooks_unavailable503Webhooks are switched off on this server: it has no signing keys configured.
scan_timeout504The scan did not finish in time.
timeout504The operation did not finish within its time budget.

Qué hacer con cada código y cuáles reintentan los SDK

Explorar

Registro de cambios

Última versión: v1.1.0, 22 de octubre de 2026. La versión de la API forma parte de la ruta; los cambios incompatibles se publicarían como /api/v2: las respuestas de la v1 pueden ganar campos, pero no los perderán ni los cambiarán.

Registro de cambios completo