certdesk-dev Certificate API

The Certificate API from certdesk-dev — 1 operation(s) for certificate.

Operations 1

GET /certificate Check one domain's TLS certificate in depth #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/certdesk-dev:certdesk-dev-certificate-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

certdesk-dev-certificate-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: certdesk Certificate API
  version: 1.8.0
  description: 'TLS/SSL certificate diagnostics with a verdict: status OK | WARN | CRITICAL | UNKNOWN, judged from the certificate chain the server actually serves — measured from Korean point A (full chain, CRL revocation) plus point B and an overseas point on the Globalping public measurement network — verification, expiry, renewal point, revocation (CRL), chain, plus security grade, TLS error explanations and free expiry monitoring by email (double opt-in). If the server cannot be measured the status is UNKNOWN; CT logs are then shown only as an estimate and days left is null. No API key. Limit: 30 requests per minute per IP; results cached per domain for 10 minutes (security: 30 minutes). Free and best-effort. Docs: https://certdesk.dev/en/api/ · MCP server: https://certdesk.dev/mcp'
  contact:
    email: hello@certdesk.dev
    url: https://certdesk.dev/en/api/
servers:
- url: https://certdesk.dev/api/v1
tags:
- name: Certificate
paths:
  /certificate:
    get:
      operationId: checkCertificate
      summary: Check one domain's TLS certificate in depth
      description: 'Verdict for one domain from the certificate chain the server actually serves (measured from a Korean network): status, headline, reasons (each with a knowledge-base link), the served leaf, revocation (CRL), the served chain in the order sent (missing intermediates marked), a newer certificate issued but not deployed (CT logs), and the issuing CA''s incident history. If the server cannot be measured: status UNKNOWN, cert.daysLeft null, CT logs only as `estimate`. Only port 443 for now (other ports → 400 PORT_UNSUPPORTED); internationalized names are converted to punycode; IP addresses and private names → 400. Uncached measurements are limited to 10 per minute per IP (429 MEASURE_LIMIT).'
      parameters:
      - $ref: '#/components/parameters/domain'
      - $ref: '#/components/parameters/port'
      - $ref: '#/components/parameters/client'
      - name: fresh
        in: query
        required: false
        description: 1 = skip the cache and re-measure now (once per minute per domain → 429 FRESH_LIMIT)
        schema:
          type: string
          enum:
          - '1'
      - $ref: '#/components/parameters/warnDays'
      - $ref: '#/components/parameters/critDays'
      responses:
        '200':
          description: Diagnosis
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CertificateCheck'
        '400':
          $ref: '#/components/responses/Error'
        '429':
          $ref: '#/components/responses/RateLimited'
      tags:
      - Certificate
components:
  schemas:
    Served:
      type:
      - object
      - 'null'
      description: Leaf certificate the server actually sent
      properties:
        subject:
          type: object
        issuer:
          type: object
        serial:
          type:
          - string
          - 'null'
        sha256:
          type:
          - string
          - 'null'
        san:
          type: array
          items:
            type: string
        notBefore:
          type:
          - string
          - 'null'
          format: date-time
        notAfter:
          type: string
          format: date-time
        lifetimeDays:
          type:
          - integer
          - 'null'
        renewalDue:
          type:
          - string
          - 'null'
          format: date-time
          description: notBefore + 2/3 of lifetime
        protocol:
          type:
          - string
          - 'null'
        cipher:
          type:
          - string
          - 'null'
        ip:
          type:
          - string
          - 'null'
        family:
          type:
          - string
          - 'null'
        port:
          type: integer
        chainLength:
          type: integer
        measuredBy:
          type: string
          description: kr-a normally; a Globalping point id when point A was unavailable (chainLength and revocation are then null)
        starttls:
          type:
          - string
          - 'null'
          enum:
          - smtp
          - imap
          - pop3
          - ldap
          - null
        nodes:
          type: array
          description: 'Other A/AAAA addresses measured from point A (up to 4): leaf sha256, notAfter, same as the measured address'
          items:
            type: object
            properties:
              ip:
                type: string
              family:
                type: string
              sha256:
                type:
                - string
                - 'null'
              notAfter:
                type:
                - string
                - 'null'
              same:
                type:
                - boolean
                - 'null'
              error:
                type:
                - string
                - 'null'
    CertSummary:
      type:
      - object
      - 'null'
      properties:
        notAfter:
          type: string
          format: date-time
          description: RFC 3339 UTC
        daysLeft:
          type:
          - integer
          - 'null'
          description: floor((notAfter − now) / 1 day) of the served leaf; null when the server could not be measured
        issuer:
          type:
          - string
          - 'null'
        source:
          type: string
          enum:
          - served
          - ct
        newerInCt:
          type: boolean
          description: Same as `newer != null` on the parent object
        ctLatest:
          type:
          - object
          - 'null'
          properties:
            notAfter:
              type: string
            issuer:
              type:
              - string
              - 'null'
        hoursLeft:
          type:
          - integer
          - 'null'
          description: Set when less than 72 hours are left
        renewalDue:
          type:
          - string
          - 'null'
          format: date-time
        estimate:
          type: boolean
          description: true = CT-log estimate (server not measured)
    Thresholds:
      type: object
      description: Expiry thresholds actually applied
      properties:
        warnDays:
          type: integer
        critDays:
          type: integer
        custom:
          type: boolean
          description: true when warnDays/critDays were passed
        adjusted:
          type: boolean
          description: true when the defaults were shrunk for a short-lived certificate
    Reason:
      type: object
      properties:
        code:
          type: string
          description: e.g. EXPIRED, NOT_YET_VALID, EXPIRES_SOON (within critDays), HOSTNAME_MISMATCH, SELF_SIGNED, UNTRUSTED_ROOT, INCOMPLETE_CHAIN, ISSUER_NOT_FOUND, EXPIRED_INTERMEDIATE, REVOKED, LEGACY_TLS_ONLY, WEAK_KEY, WEAK_SIGNATURE, CHAIN_ORDER, EXTRA_CERTS, RENEWAL_OVERDUE (within warnDays), NODE_EXPIRING (another node serves a certificate within the thresholds), NODE_MISMATCH (addresses serve different certificates), STARTTLS_UNSUPPORTED, STARTTLS_FAILED, SECONDARY_UNAVAILABLE, NEWER_NOT_DEPLOYED, PROBE_UNAVAILABLE, DNS_NXDOMAIN, DNS_NO_ADDRESS, CONNECT_TIMEOUT, CONNECT_REFUSED, TLS_HANDSHAKE_FAILED … POINT_MISMATCH, REGION_DIFF, DIFFERENT_CERTS, PRIMARY_DOWN, FAMILY_MISMATCH, IPV6_UNREACHABLE, IPV6_NOT_MEASURED …
        severity:
          type: string
          enum:
          - critical
          - unknown
          - warn
          - info
        message:
          type: string
          description: One line, Korean
        messageEn:
          type: string
        detail:
          type:
          - string
          - 'null'
          description: Raw detail (e.g. missing intermediate names, original error text)
        explain:
          type:
          - string
          - 'null'
          description: Knowledge-base id for /api/v1/explain
        explainUrl:
          type:
          - string
          - 'null'
          format: uri
      required:
      - code
      - severity
      - message
    CertificateCheck:
      type: object
      properties:
        domain:
          type: string
        tls:
          type: object
          description: 'Old field kept for compatibility: the overseas measurement point''s real TLS verification on the Globalping network ({kind:''globalping'', ok, error, where}); ok=null when unavailable'
        tlsKr:
          type:
          - object
          - 'null'
          description: Raw result from the Korean measurement point (served chain without DER, verification, revocation)
        cert:
          $ref: '#/components/schemas/CertSummary'
        chain:
          type: array
          items:
            type: object
          description: Served chain in the order the server sent it (source=served), missing intermediates fetched via AIA (source=aia, missing=true) and the trust-store root; CT-based (source=ct-log) only as an estimate
        revoked:
          type:
          - boolean
          - 'null'
          description: From the served leaf's CRL; null = not checked
        incidents:
          type: array
          items:
            type: object
        checkedAt:
          type: string
          format: date-time
        status:
          type: string
          enum:
          - OK
          - WARN
          - CRITICAL
          - UNKNOWN
          description: OK = no issue; WARN = past renewal point, chain order/extra certs, weak key/signature; CRITICAL = verification failed (any reason), revoked, expired or ≤7 days left, TLS below 1.2 only; UNKNOWN = could not be measured (never treat as OK)
        headline:
          type: string
          description: One-line verdict (Korean)
        headlineEn:
          type: string
        reasons:
          type: array
          items:
            $ref: '#/components/schemas/Reason'
        served:
          $ref: '#/components/schemas/Served'
        revocation:
          type:
          - object
          - 'null'
          properties:
            status:
              type: string
              enum:
              - good
              - revoked
              - unknown
            method:
              type:
              - string
              - 'null'
            url:
              type:
              - string
              - 'null'
            checkedAt:
              type:
              - string
              - 'null'
            detail:
              type:
              - string
              - 'null'
        estimate:
          type:
          - object
          - 'null'
          description: 'Only when the server could not be measured: latest certificate in CT logs (an estimate, not the installed certificate)'
        newer:
          type:
          - object
          - 'null'
          description: A certificate with the same SAN set, issued later and expiring later, found in CT logs but not served (CDN backup certificates from a different CA issued within 14 days are excluded)
        measuredFrom:
          type: array
          description: 'Per-point results: kr-a (own probe, chain and revocation), kr-b (Globalping, KT Seoul), intl-* (Globalping, Tokyo)'
          items:
            type: object
            properties:
              id:
                type: string
              label:
                type: string
              provider:
                type: string
                enum:
                - certdesk
                - globalping
              network:
                type:
                - string
                - 'null'
              ok:
                type:
                - boolean
                - 'null'
                description: Verification passed at this point; null = not measured
              reason:
                type:
                - string
                - 'null'
              notAfter:
                type:
                - string
                - 'null'
                format: date-time
              checkedAt:
                type:
                - string
                - 'null'
        chainSource:
          type:
          - string
          - 'null'
          enum:
          - served
          - ct-estimate
          - null
        requesterCountry:
          type:
          - string
          - 'null'
        thresholds:
          $ref: '#/components/schemas/Thresholds'
        todo:
          type:
          - object
          - 'null'
          description: What to do now for the most severe reason (Korean, up to 2 lines) and a guide URL; null when OK
          properties:
            items:
              type: array
              items:
                type: string
            url:
              type:
              - string
              - 'null'
        port:
          type: integer
        target:
          type: string
          description: host, or host:port when the port is not 443
      required:
      - domain
      - status
      - headline
      - reasons
  parameters:
    port:
      name: port
      in: query
      required: false
      description: 'TLS port (default 443; or pass domain as host:port). Implicit TLS: 443 8443 4443 9443 6443 636 465 993 995 853 5061 3269 8883. STARTTLS: 25 587 (SMTP), 143 (IMAP), 110 (POP3), 389 (LDAP). Other ports → 400 PORT_UNSUPPORTED.'
      schema:
        type: integer
    warnDays:
      name: warnDays
      in: query
      required: false
      description: Days before expiry that count as WARN (1-365, default 30). The default shrinks to 1/3 of the lifetime for certificates shorter than 90 days; explicit values are used as given. Also applies to domain registration expiry.
      schema:
        type: integer
        minimum: 1
        maximum: 365
    domain:
      name: domain
      in: query
      required: true
      schema:
        type: string
        examples:
        - example.com
    critDays:
      name: critDays
      in: query
      required: false
      description: Days before expiry that count as CRITICAL 'expiring soon' (1-365, default 15, must be < warnDays → otherwise 400 INVALID_THRESHOLD). The default shrinks to 1/6 of the lifetime for certificates shorter than 90 days.
      schema:
        type: integer
        minimum: 1
        maximum: 365
    client:
      name: client
      in: query
      required: false
      description: Optional name of your app or tool, used only for aggregate usage counts
      schema:
        type: string
  responses:
    Error:
      description: Invalid input
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: string
              code:
                type: string
                description: EMPTY, INVALID_DOMAIN, INVALID_PORT, PORT_UNSUPPORTED, IP_LITERAL, PRIVATE_ADDRESS (400); MEASURE_LIMIT, FRESH_LIMIT (429)
    RateLimited:
      description: More than 30 requests per minute from this IP
      headers:
        retry-after:
          schema:
            type: integer