API Documentation

Public REST API for DNS, WHOIS, SSL, email authentication and blacklist checks. JSON responses, simple bearer-token auth, 60 requests/minute per token.

Overview

The NerdTools API exposes the same checks available via the web UI as JSON endpoints. All responses are JSON; all requests use standard HTTP methods.

Base URL: https://subs.gr/api/v1

All endpoints are versioned under /v1/. Breaking changes will move to /v2/ — your current integrations stay stable.

Authentication

All data endpoints require an API token. You can pass it three equivalent ways — choose whichever fits your client.

1. Bearer token (recommended)

Authorization: Bearer YOUR_API_TOKEN

2. X-Api-Key header

X-Api-Key: YOUR_API_TOKEN

3. Query parameter (last resort)

https://subs.gr/api/v1/dns?domain=example.com&api_key=YOUR_API_TOKEN

Avoid query-param auth in production — tokens may leak into web server logs and browser history. Use only for testing.

How to get a token

  1. Sign up for a free account (https://subs.gr/register)
  2. Go to Profile → API Tokens
  3. Click "Create Token", give it a descriptive name, copy the generated token (shown once).

Maximum 10 active tokens per account. Tokens never expire automatically — revoke them via the dashboard or DELETE endpoint.

Rate limit

60 requests per minute, per token.

When you exceed this, the API returns HTTP 429 with a Retry-After header indicating when you can try again.

HTTP/1.1 429 Too Many Requests
Retry-After: 47
Content-Type: application/json

{ "message": "Too Many Attempts." }

Many results are cached server-side (DNS 120s, SSL/WHOIS 1h, blacklist/emailauth 5min) — repeating the same query within those windows does not increase load on upstream services.

Error responses

All errors return JSON with a single "error" field describing the problem. Common status codes:

StatusMeaning
401Missing or invalid API token.
422Invalid or missing required parameter.
429Rate limit exceeded (60/min).
503Upstream service unavailable (e.g. whois daemon down).
HTTP/1.1 422 Unprocessable Entity
Content-Type: application/json

{ "error": "domain parameter required (e.g. ?domain=example.com)" }

GET/v1/dns

Resolve DNS records (A, AAAA, MX, NS, TXT, CNAME, CAA, SOA, SRV, PTR, ANY) for a domain.

Parameters

NameTypeRequiredDescription
domainstringyesFQDN to look up, e.g. example.com. IDN domains accepted (auto-converted to Punycode).
typestringnoRecord type. Default: A. One of: A, AAAA, MX, NS, TXT, CNAME, CAA, SOA, SRV, PTR, ANY

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
     "https://subs.gr/api/v1/dns?domain=google.com&type=MX"

Example response (200 OK)

{
  "domain": "google.com",
  "type": "MX",
  "records": [
    { "host": "google.com", "class": "IN", "ttl": 300, "type": "MX", "pri": 10, "target": "smtp.google.com" }
  ],
  "count": 1,
  "cached": true,
  "ttl": 120
}

GET/v1/ssl

Check the SSL/TLS certificate of a domain — expiry, days remaining, issuer, SANs.

Parameters

NameTypeRequiredDescription
domainstringyesFQDN to check (port 443 assumed).

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
     "https://subs.gr/api/v1/ssl?domain=github.com"

Example response (200 OK)

{
  "domain": "github.com",
  "status": "ok",
  "days_left": 287,
  "expires": "2027-03-04",
  "issued": "2026-03-04",
  "subject_cn": "github.com",
  "issuer_o": "Sectigo Limited",
  "issuer_cn": "Sectigo ECC Domain Validation Secure Server CA",
  "san": ["github.com", "www.github.com", "*.github.com"]
}

Possible status values: ok (>30 days left), expiring_soon (≤30), expired, error.

GET/v1/emailauth

Check email authentication records: SPF, DKIM, DMARC.

Parameters

NameTypeRequiredDescription
domainstringyesFQDN to check (e.g. gmail.com).

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
     "https://subs.gr/api/v1/emailauth?domain=gmail.com"

Example response (200 OK)

{
  "domain": "gmail.com",
  "score": "3/3",
  "status": "pass",
  "spf":   { "status": "found", "record": "v=spf1 redirect=_spf.google.com", "policy": "neutral" },
  "dmarc": { "status": "found", "record": "v=DMARC1; p=none; sp=quarantine; rua=mailto:...", "policy": "none" },
  "dkim":  { "status": "found", "selector": "20230601", "host": "20230601._domainkey.gmail.com" }
}

Top-level status: pass (all 3 found), partial (1–2 found), fail (none found).

GET/v1/blacklist

Check if an IP or domain appears on known email blacklists (DNSBLs) — Spamhaus, Barracuda, SpamCop, SORBS and more.

Parameters

NameTypeRequiredDescription
querystringyesIPv4 address or domain. Domains are resolved to IPv4 first; IPv6 is not supported.

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
     "https://subs.gr/api/v1/blacklist?query=1.1.1.1"

Example response (200 OK)

{
  "query":   "1.1.1.1",
  "ip":      "1.1.1.1",
  "status":  "clean",
  "listed":  0,
  "total":   20,
  "details": [
    { "name": "Spamhaus ZEN", "zone": "zen.spamhaus.org", "listed": false, "blocked": false, "code": null },
    { "name": "SpamCop",      "zone": "bl.spamcop.net",   "listed": false, "blocked": false, "code": null }
  ]
}

status is "clean" if listed === 0, otherwise "listed".

GET/v1/whois

Domain registration data — registrar, creation/expiry dates, nameservers.

Parameters

NameTypeRequiredDescription
domainstringyesFQDN to look up.

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
     "https://subs.gr/api/v1/whois?domain=github.com"

Example response (200 OK)

{
  "domain": "github.com",
  "parsed": {
    "registrar":   "MarkMonitor Inc.",
    "created":     "2007-10-09T18:20:50Z",
    "expires":     "2027-10-09T18:20:50Z",
    "nameservers": ["dns1.p08.nsone.net", "dns2.p08.nsone.net", "dns3.p08.nsone.net", "dns4.p08.nsone.net"]
  }
}

.gr / .ελ domains return status:"unavailable" because the registry restricts public WHOIS due to GDPR.

GET/v1/tokens

List your API tokens. The token plaintext is never shown after creation — only metadata is returned.

Example request

curl -H "Authorization: Bearer YOUR_TOKEN" \
     "https://subs.gr/api/v1/tokens"

Example response (200 OK)

{
  "tokens": [
    {
      "id":           42,
      "name":         "production-server-01",
      "last_used_at": "2026-05-22T14:31:08+03:00",
      "expires_at":   null,
      "created_at":   "2026-04-10T09:12:55+03:00"
    }
  ]
}

POST/v1/tokens

Create a new API token. The plain token is returned ONCE — save it immediately.

Body (JSON)

NameTypeRequiredDescription
namestringnoHuman-readable label (1–100 chars). Default: "My token".

Example request

curl -X POST \
     -H "Authorization: Bearer YOUR_TOKEN" \
     -H "Content-Type: application/json" \
     -d '{"name":"my-new-token"}' \
     "https://subs.gr/api/v1/tokens"

Example response (201 Created)

{
  "id":    43,
  "name":  "my-new-token",
  "token": "ntk_live_a8B9c0D1e2F3g4H5i6J7k8L9m0N1o2P3q4R5s6T7",
  "note":  "Save this token — it will not be shown again."
}

Limit: 10 tokens per account.

DELETE/v1/tokens/{id}

Revoke a token by ID. The token is invalidated immediately.

Example request

curl -X DELETE \
     -H "Authorization: Bearer YOUR_TOKEN" \
     "https://subs.gr/api/v1/tokens/42"

Example response (200 OK)

{ "message": "Token revoked." }

Returns 404 if the token does not exist or does not belong to you.

Need help? Open an issue or send feedback via the contact form.