Skip to content
ecdsa.com

Changelog

Changes to the public API, newest first. The API is versioned in the path; breaking changes would ship as /api/v2 — v1 answers may gain fields and codes but will not lose or change them.

  1. With API keys

    Not released yet

    Merged, not released: these changes ship when API keys launch together with ecdsa.com accounts. Calls without a key stay exactly as they are.

    • Changed

      A well-formed key that is unknown, revoked or expired is refused with 401 unauthorized and a WWW-Authenticate challenge, instead of being served anonymously.

      Codes:unauthorized

      Headers:WWW-Authenticate

    • Added

      403 forbidden_scope: the key is valid but lacks a scope the operation needs; the message names it. The call is refused before any rate limit or quota is spent.

      Codes:forbidden_scope

    • Added

      429 quota_exceeded: a daily or monthly quota of the key’s account is used up. Retry-After runs until the quota starts over; the SDKs never retry it.

      Codes:quota_exceeded

    • Added

      Every answer to a call with a key carries the quota that runs out first; browsers may read these headers too.

      Headers:X-Quota-LimitX-Quota-RemainingX-Quota-Reset

    • Added

      503 service_unavailable: keys cannot be verified right now. A call with a key is never served anonymously — retry shortly.

      Codes:service_unavailable

    • Changed

      Calls with a key are limited per key instead of per IP: 120 per minute on the free tier, 600 on the pro tier. Test keys always get the free tier.

      Codes:rate_limited

    • Changed

      The API index’s auth field says that keys are optional, what a key changes and which operations need one, instead of “no API keys”.

      Operations:GET /v1

    • Added

      Webhooks: /api/v1/webhooks lists (GET) and creates (POST) the endpoints of the key’s account, /api/v1/webhooks/delete deletes one and /api/v1/webhooks/test sends a test event. They need a key with the webhooks scope and are offered over REST only — not as MCP tools and not in the SDKs.

      Operations:GET /v1/webhooksPOST /v1/webhooksPOST /v1/webhooks/deletePOST /v1/webhooks/test

    • Added

      Deliveries are signed with ECDSA P-256: ECDSA-Signature carries the timestamp, the key id and the signature, and the public keys are the JWKS at /.well-known/ecdsa-webhook-keys.json — two key ids overlap during a rotation. Every SDK checks a delivery with verifyWebhook().

    • Added

      New codes for webhooks: webhook_url_refused (400), webhook_limit_reached (403), webhook_not_found (404) and webhooks_unavailable (503).

      Codes:webhook_url_refusedwebhook_limit_reachedwebhook_not_foundwebhooks_unavailable

  2. v1.1.0

    Released October 22, 2026

    The API core was rebuilt on declarative operations, and scans of a domain now share a budget per checked host. Additive for existing clients: every v1.0 request gets the same status and the same body, plus the new fields. Most of these changes have been live since October 20, 2026; the index reports 1.1.0 from this release on.

    • Added

      Real scans of a domain draw on budgets shared by all clients: one host at most 6 times per 10 minutes, all scans together at most 300 per minute. A scan beyond a budget is answered with 429 rate_limited and Retry-After; answers from the one-hour cache spend nothing.

      Codes:rate_limited

      Operations:GET /v1/health/{domain}

    • Added

      Error bodies gain requestId — quote it when you report a problem — and docs, a link to the error codes. code and message are unchanged.

      Fields:error.requestIderror.docs

    • Added

      Every answer carries X-Request-Id. Send your own (1–128 letters, digits, dots, underscores, colons or hyphens) to correlate requests: it is echoed back.

      Headers:X-Request-Id

    • Changed

      Unknown paths answer 404 not_found and wrong methods 405 method_not_allowed with an Allow header — JSON envelopes with CORS instead of HTML pages.

      Codes:not_foundmethod_not_allowed

      Headers:Allow

    • Fixed

      JSON nested more than 64 levels deep — JSON inside string fields included — is answered with 400 invalid_json in the JSON envelope. It used to fail with a 500 that was not JSON.

      Codes:invalid_json

    • Added

      Domain-health answers gain certificate: the leaf certificate’s expiry, days remaining, key algorithm and curve.

      Fields:certificate

      Operations:GET /v1/health/{domain}

    • Added

      A malformed Authorization or X-API-Key header is refused with 401 unauthorized instead of being ignored, so a client that meant to authenticate learns about the typo. Well-formed keys are still served anonymously until API keys launch.

      Codes:unauthorized

    • Added

      An operation that does not finish within its time budget of 10 seconds answers 504 timeout.

      Codes:timeout

    • Changed

      Browsers may send Authorization, X-API-Key, X-Request-Id and Idempotency-Key cross-origin, and read X-Request-Id.

    • Changed

      The OpenAPI document is generated from the API’s own schemas: every operation lists its error codes by status, its examples and the scopes an API key needs.

      Operations:GET /v1/openapi.json

  3. v1.0.0

    Released August 20, 2026

    The free Signature API goes public.