Skip to content
ecdsa.com

API

API self-description

GEThttps://ecdsa.com/api/v1

Version, endpoint list, rate limits and documentation links.

API key
Not read: the answer is the same for everyone
Rate limit
60 requests/min per IP

Request

This operation takes no input.

Responses

200Self-description of the API.

FieldTypeRequiredDescription
namestringyes
versionstringyes

Version of the v1 API.

descriptionstringyes
documentationstringyes
  • format uri
openapistringyes

This API's OpenAPI document.

  • format uri
authstringyes

How callers authenticate.

rateLimitobjectyes
rateLimit.requestsPerMinuteintegeryes
  • greater than 0
rateLimit.healthRequestsPerMinuteintegeryes
  • greater than 0
rateLimit.scopestringyes
rateLimit.headersstring[]yes
rateLimit.onExceededstringyes
privacystringyes
endpointsApiEndpoint[]yes

Headers: X-Request-Id · X-RateLimit-Limit · X-RateLimit-Remaining · X-RateLimit-Reset

StatusMeaningCodes
404Not found.
405Method not allowed.
429Too many requests.
500Internal server error.
504Gateway timeout.

Every error answer carries the JSON envelope; the error table says what each code means and what to do.

Example

The API index

curl
curl -sS 'https://ecdsa.com/api/v1'
JavaScript (fetch)
const response = await fetch("https://ecdsa.com/api/v1");
console.log(response.status, await response.json());
Python (httpx)
import httpx

response = httpx.get("https://ecdsa.com/api/v1", timeout=30.0)
print(response.status_code, response.json())
Response 200
{
  "name": "ecdsa.com Signature API",
  "version": "1.1.0",
  "description": "Free REST API for ECDSA signature verification, signature format conversion, JWT (ES256/ES384/ES512) decoding and verification, X.509 certificate decoding and TLS signature-health grades.",
  "documentation": "https://ecdsa.com/developers",
  "openapi": "https://ecdsa.com/api/v1/openapi.json",
  "auth": "optional — every operation works without a key except managing webhooks, which needs a key with the webhooks scope. An API key (Authorization: Bearer <key> or X-API-Key) gets per-key rate limits and the quotas of its account's plan.",
  "rateLimit": {
    "requestsPerMinute": 60,
    "healthRequestsPerMinute": 10,
    "scope": "per IP address, per server instance",
    "headers": [
      "X-RateLimit-Limit",
      "X-RateLimit-Remaining",
      "X-RateLimit-Reset"
    ],
    "onExceeded": "HTTP 429 with a Retry-After header"
  },
  "privacy": "Request bodies are processed in memory and never logged. Never send private keys — requests containing one are rejected. For anything secret, use the in-browser tools at https://ecdsa.com: they run entirely client-side.",
  "endpoints": [
    {
      "method": "GET",
      "path": "/api/v1",
      "summary": "This self-description."
    },
    {
      "method": "POST",
      "path": "/api/v1/verify",
      "summary": "Verify an ECDSA signature (P-256, P-384, P-521, secp256k1; DER or raw r‖s)."
    },
    {
      "method": "POST",
      "path": "/api/v1/convert",
      "summary": "Convert an ECDSA signature between DER and raw r‖s, optionally normalizing to low-S."
    },
    {
      "method": "POST",
      "path": "/api/v1/jwt/decode",
      "summary": "Decode a JWT (header, payload, time claims, algorithm info) without verifying the signature."
    },
    {
      "method": "POST",
      "path": "/api/v1/jwt/verify",
      "summary": "Verify an ES256/ES384/ES512 JWT signature against a public key."
    },
    {
      "method": "POST",
      "path": "/api/v1/cert/decode",
      "summary": "Decode an X.509 certificate or chain (PEM or base64/hex DER) with assessments."
    },
    {
      "method": "GET",
      "path": "/api/v1/health/{domain}",
      "summary": "TLS signature-health grade for a public domain (1-hour cache)."
    },
    {
      "method": "GET",
      "path": "/api/v1/webhooks",
      "summary": "List the webhook endpoints of the API key's account (needs a key with the webhooks scope)."
    },
    {
      "method": "POST",
      "path": "/api/v1/webhooks",
      "summary": "Create or update a webhook endpoint of the API key's account (needs a key with the webhooks scope)."
    },
    {
      "method": "POST",
      "path": "/api/v1/webhooks/delete",
      "summary": "Delete a webhook endpoint of the API key's account (needs a key with the webhooks scope)."
    },
    {
      "method": "POST",
      "path": "/api/v1/webhooks/test",
      "summary": "Send a webhook.test event to an endpoint of the API key's account (needs a key with the webhooks scope)."
    },
    {
      "method": "GET",
      "path": "/api/v1/openapi.json",
      "summary": "OpenAPI 3.1 specification of this API."
    }
  ]
}

The API’s answer to this example, produced for this page on October 20, 2026; relative times and day counts in it refer to that day.

Error codes

CodeStatusMeaning
not_found404No operation exists at this path.
method_not_allowed405The path exists but does not accept this HTTP method; see the Allow header.
rate_limited429Too many requests — see Retry-After.
internal_error500Unexpected server error.
timeout504The operation did not finish within its time budget.

Schemas

ApiEndpoint

FieldTypeRequiredDescription
methodstringyes
  • one of "GET" or "POST"
pathstringyes

Path on https://ecdsa.com, e.g. "/api/v1/verify".

summarystringyes

Error

The error envelope of every non-2xx response.

FieldTypeRequiredDescription
errorobjectyes
error.codestringyes

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.messagestringyes

Human-readable explanation (English).

error.requestIdstringno

The X-Request-Id of this request — quote it when reporting a problem. Sent since v1.1.

error.detailobjectno

Structured context for the error, such as the offending field; omitted when there is none.

  • any member names
error.docsstringno

Where the error codes are explained. Sent since v1.1.

  • format uri

All operations are listed in the API reference.