di>_
DigInterface
Free DNS, Email & Developer Tools
🧩 New! DigInterface Tools is now available as a browser extension — DNS, Headers, SSL, Blacklist, WHOIS, SPF & Propagation right from your toolbar.

DigInterface API

← API Overview

A RESTful API for DNS lookups, domain intelligence, email authentication checks and cryptographic hashing — the same tools powering DigInterface, available programmatically.

API Live. All endpoints documented below are active. Generate an API key from your account dashboard to get started.

Base URL

BASE URL
https://www.diginterface.com/api/v2

All requests must be made over HTTPS. HTTP requests will be redirected to HTTPS. All request bodies must be JSON with Content-Type: application/json. All responses are JSON.

📄
OpenAPI spec. Machine-readable OpenAPI 3.1 spec at /api/openapi.json — import into Postman, Insomnia, or generate a client with openapi-generator.

🔑 Authentication

All API requests require authentication using an API key passed in the Authorization header as a Bearer token. API keys can be generated from your account dashboard.

REQUEST HEADER
Authorization: Bearer di_a1b2c3d4e5f6g7h8i9j0k1l2
PropertyDetail
Formatdi_ prefix followed by a 24-character alphanumeric string
TransmissionAlways via Authorization: Bearer <key> header — never in query strings
StorageKeys are stored hashed on the server — only the prefix (di_xxxx) is shown after creation
ScopesEach key has scopes limiting which endpoints it can call. See Scopes below.
ExpiryKeys can be set to expire after 30, 60, or 90 days, or never expire. Expired keys return KEY_EXPIRED.
IP AllowlistOptionally restrict a key to one or more IP addresses. Requests from other IPs return IP_NOT_ALLOWED.
ResetKeys can be reset from the dashboard — generates a new secret while keeping all settings intact. Old key is immediately invalidated.
RevocationKeys can be revoked instantly from the account dashboard

Programmatic Login (JWT)

If you need a short-lived token for dashboard access or automation, you can exchange email and password for a 1-hour JWT using the /auth/token endpoint.

POST /auth/token
curl -X POST https://www.diginterface.com/auth/token \ -H "Content-Type: application/json" \ -d '{ "email": "you@example.com", "password": "yourpassword" }' // Response { "status": "ok", "access_token": "eyJ...", "token_type": "Bearer", "expires_in": 3600 }
⚠️
Treat your API key like a password. Do not commit it to source control or expose it in client-side code. If a key is compromised, reset or revoke it immediately from your dashboard.

🛡 Scopes

Every API key has one or more scopes that control which endpoints it can access. Scopes are assigned when a key is created and cannot be changed — create a new key if you need different scopes. A request made with a key that lacks the required scope returns a 403 INSUFFICIENT_SCOPE error.

ScopeEndpoints covered
dns POST /api/v2/dns/lookup   POST /api/v2/dns/propagation
domain POST /api/v2/whois   POST /api/v2/ssl   POST /api/v2/blacklist   POST /api/v2/domain/age
email POST /api/v2/spf/expand   POST /api/v2/email/deliverability   POST /api/v2/email/headers   POST /api/v2/dmarc
utils POST /api/v2/hash/text   POST /api/v2/hash/url   POST /api/v2/cidr   POST /api/v2/qr/generate   POST /api/v2/qr/decode
account GET /api/v2/account/keys   GET /api/v2/account/usage
💡
For maximum security, create separate keys for each integration with only the scopes that integration needs. For example, a monitoring script that only checks SSL certificates only needs the domain scope.

⏱ Rate Limits

API requests are rate-limited per API key. The default limit is 100 requests per day. Account admins can increase this limit on a per-key basis for trusted integrations.

100
Default requests / day
Custom
Admin-configurable per key
Midnight
Resets at UTC

Every response includes the following rate limit headers:

RESPONSE HEADERS
X-RateLimit-Limit: 100 X-RateLimit-Remaining: 73 X-RateLimit-Reset: 1745491200 # UTC epoch seconds when the window resets

When the rate limit is exceeded the API returns a 429 Too Many Requests response with a Retry-After header indicating how many seconds to wait.


❌ Error Codes

All errors follow a consistent format. HTTP status codes indicate the category of error; the code field provides a machine-readable identifier.

ERROR RESPONSE
{ "status": "error", "code": "INVALID_DOMAIN", "message": "The value 'not-a-domain' is not a valid domain name", "request_id": "req_7x8y9z" }
HTTP StatusCodeDescription
400INVALID_DOMAINThe supplied domain name is malformed or empty
400INVALID_IPThe supplied IP address is not a valid IPv4 or IPv6 address
400INVALID_PARAMETERA required parameter is missing or has an invalid value
400INVALID_RECORD_TYPEThe requested DNS record type is not supported
401MISSING_API_KEYNo Authorization header was provided
401INVALID_API_KEYThe API key is invalid or has been revoked
401KEY_EXPIREDThe API key has passed its expiry date — generate a new key from the dashboard
403IP_NOT_ALLOWEDThe request came from an IP address not on the key’s allowlist
403INSUFFICIENT_SCOPEThe API key does not have the scope required for this endpoint
429RATE_LIMIT_EXCEEDEDDaily request limit reached — resets at midnight UTC
404DNS_NXDOMAINThe domain does not exist (NXDOMAIN)
404NO_SPF_RECORDNo SPF TXT record found for the domain
422SPF_PERMERRORSPF record has a permanent error (e.g. exceeds 10 DNS lookups)
408DNS_TIMEOUTDNS query timed out — try again
502UPSTREAM_ERRORUpstream DNS resolver or service returned an error
500INTERNAL_ERRORUnexpected server error — contact support if persistent

🔖 Versioning

The API version is included in the URL path (/api/v2/). Breaking changes will result in a new version (v3). Non-breaking additions (new fields, new optional parameters) may be made to existing versions without notice. The api_version field in every response reflects the version that served the request.


🤖 MCP Endpoint

Every DigInterface tool is also available over the Model Context Protocol, the open standard that lets AI assistants like Claude call real tools instead of guessing from training data. Auth, scopes and rate limits are shared with the REST surface — one di_ API key works for both.

🚀
Launched July 2026. See the announcement blog post for background and worked examples.

Endpoint URL

MCP URL
https://www.diginterface.com/mcp

Connecting from Claude

In Claude, go to Settings → Connectors → Add Custom Connector and enter:

NameDigInterface (or any label you prefer)
URLhttps://www.diginterface.com/mcp
AuthLeave blank for anonymous access at the shared rate limit, or paste a di_ API key as a bearer token for per-scope quotas.

Available tools

All tools reuse the same scope taxonomy as the REST API — a key with the dns scope can call MCP tools that need dns, and so on. Some tools have a REST equivalent (documented below); others are MCP-only.

ToolScopeREST equivalent
dns_lookupdns/api/v2/dns/lookup
whois_lookupdomain/api/v2/whois
ssl_checkdomain/api/v2/ssl
blacklist_checkdomain/api/v2/blacklist
domain_agedomain/api/v2/domain/age
tech_partner_lookupdomainMCP only
spf_expandemail/api/v2/spf/expand
dmarc_analyzeemail/api/v2/dmarc
header_analysisemail/api/v2/email/headers
cidr_infoutils/api/v2/cidr
qr_generateutils/api/v2/qr/generate
qr_decodeutils/api/v2/qr/decode
hash_textutils/api/v2/hash/text
base64_encodeutilsMCP only
base64_decodeutilsMCP only
timestamp_convertutilsMCP only
timezone_convertutilsMCP only
regex_testutilsMCP only

Anonymous vs authenticated

Anonymous requests (no Authorization header) are allowed for discovery and casual use — scope checks are bypassed and only the nginx per-IP limit applies. Authenticated requests (Authorization: Bearer di_...) are checked against the key's scope for every tools/call and count toward the key's daily quota exactly like REST.

Transport and rate limits

The endpoint speaks the MCP Streamable HTTP transport (JSON-RPC 2.0 over Server-Sent Events). Any MCP client implementing the 2025-11-25 or later specification should work.

Anonymous requests share a nginx-level limit of 30 per minute per IP. Authenticated requests draw from the same daily quota as REST (default 100/day per key, admin-configurable). Every tool invocation is logged to /account/usage so you can see MCP and REST traffic side by side.

💡
MCP is for when you want an assistant to run checks on your behalf. If you want to call these tools directly from code, use the REST endpoints documented below — same auth, same scopes.

DNS Lookup

POST /api/v2/dns/lookup Query DNS records for a domain using any public resolver

Request Parameters

ParameterTypeRequiredDescription
domain string required The domain name to query (e.g. example.com)
record_types string[] optional Array of record types to query. Supported: A AAAA MX NS TXT SPF CNAME SOA PTR DMARC DKIM. Defaults to ["A","MX","TXT"]
resolver string optional Resolver to use: google (8.8.8.8), cloudflare (1.1.1.1), opendns, quad9. Defaults to google
dkim_selector string optional Required when DKIM is in record_types. The DKIM selector (e.g. google)
REQUEST — curl
curl -X POST https://www.diginterface.com/api/v2/dns/lookup \ -H "Authorization: Bearer di_a1b2c3d4e5f6g7h8i9j0k1l2" \ -H "Content-Type: application/json" \ -d '{ "domain": "example.com", "record_types": ["MX", "TXT", "SPF"], "resolver": "google" }'
RESPONSE — 200 OK
{ "status": "ok", "api_version": "2", "request_id": "req_7x8y9z", "timestamp": "2026-04-24T10:00:00Z", "data": { "domain": "example.com", "resolver": "google", "records": { "MX": ["10 mail1.example.com", "20 mail2.example.com"], "TXT": ["v=spf1 ip4:203.0.113.0/24 include:_spf.google.com ~all"], "SPF": ["v=spf1 ip4:203.0.113.0/24 include:_spf.google.com ~all"] } } }

DNS Propagation

POST /api/v2/dns/propagation Check how a DNS record has propagated across multiple global resolvers
ParameterTypeRequiredDescription
domainstringrequiredDomain name to check
record_typestringoptionalRecord type to check. Defaults to A
RESPONSE — 200 OK
{ "status": "ok", "data": { "domain": "example.com", "record_type": "A", "propagated": true, // true if all resolvers agree "resolvers": [ { "name": "Google", "ip": "8.8.8.8", "result": ["93.184.216.34"], "status": "ok" }, { "name": "Cloudflare", "ip": "1.1.1.1", "result": ["93.184.216.34"], "status": "ok" }, { "name": "Quad9", "ip": "9.9.9.9", "result": [], "status": "timeout" } ] } }

WHOIS Lookup

POST /api/v2/whois WHOIS and RDAP data for a domain or IP address
ParameterTypeRequiredDescription
querystringrequiredDomain name or IP address to look up
RESPONSE — 200 OK
{ "status": "ok", "data": { "query": "example.com", "type": "domain", "registrar": "IANA", "created": "1995-08-14", "expires": "2025-08-13", "updated": "2023-08-14", "status": ["clientDeleteProhibited", "clientTransferProhibited"], "nameservers": ["a.iana-servers.net", "b.iana-servers.net"], "raw": "Domain Name: EXAMPLE.COM\nRegistry Domain ID: ..." } }

SSL Certificate Check

POST /api/v2/ssl Inspect the SSL/TLS certificate for a domain
ParameterTypeRequiredDescription
domainstringrequiredDomain to inspect (port 443 assumed)
portintegeroptionalPort to connect to. Defaults to 443
RESPONSE — 200 OK
{ "status": "ok", "data": { "domain": "diginterface.com", "valid": true, "subject": "CN=diginterface.com", "issuer": "Let's Encrypt", "expires": "2026-07-22T12:00:00Z", "days_left": 89, "sans": ["diginterface.com", "www.diginterface.com"], "tls_version": "TLSv1.3", "cipher": "TLS_AES_256_GCM_SHA384" } }

Blacklist Check

POST /api/v2/blacklist Check an IP or domain against major DNS blacklists and URI blocklists
ParameterTypeRequiredDescription
targetstringrequiredIPv4 address or domain name to check
RESPONSE — 200 OK
{ "status": "ok", "data": { "target": "203.0.113.5", "listed": true, "list_count": 2, "results": [ { "list": "zen.spamhaus.org", "listed": true, "reason": "Policy Block List" }, { "list": "bl.spamcop.net", "listed": false, "reason": "" }, { "list": "dnsbl.sorbs.net", "listed": true, "reason": "SPAM source" } ] } }

SPF Record Expander

POST /api/v2/spf/expand Recursively expand an SPF record, following all includes and redirects
ParameterTypeRequiredDescription
domainstringrequiredDomain whose SPF record should be expanded
RESPONSE — 200 OK
{ "status": "ok", "data": { "domain": "example.com", "record": "v=spf1 include:_spf.google.com ~all", "lookup_count": 4, "ip4_count": 6, "ip6_count": 3, "flat_ips": [ { "ip": "74.125.0.0/16", "type": "ip4", "qualifier": "pass", "source": "_spf.google.com" }, { "ip": "209.85.128.0/17", "type": "ip4", "qualifier": "pass", "source": "_spf.google.com" } ] } }

Email Deliverability

POST /api/v2/email/deliverability Full email deliverability check — SPF, DKIM, DMARC, PTR, blacklists and overall score
ParameterTypeRequiredDescription
domainstringrequiredDomain to check deliverability for
dkim_selectorstringoptionalDKIM selector to check (e.g. google)
RESPONSE — 200 OK
{ "status": "ok", "data": { "domain": "example.com", "score": 85, "checks": [ { "name": "SPF Record", "status": "pass", "message": "Valid SPF with ~all policy" }, { "name": "DMARC Record", "status": "pass", "message": "p=reject policy" }, { "name": "DKIM", "status": "warn", "message": "No selector provided" }, { "name": "Blacklists", "status": "pass", "message": "Not listed on any DNSBL" }, { "name": "PTR Record", "status": "pass", "message": "Reverse DNS matches forward" } ] } }

Email Header Analysis

POST /api/v2/email/headers Parse raw email headers into authentication results, relay hops, and a key-header summary

Request Parameters

ParameterTypeRequiredDescription
headers string required The raw email header block as plain text. Line endings may be \r\n, \r or \n; RFC 2822 folded continuation lines are handled. Maximum 200 KB.
REQUEST — curl
curl -X POST https://www.diginterface.com/api/v2/email/headers \ -H "Authorization: Bearer di_a1b2c3d4e5f6g7h8i9j0k1l2" \ -H "Content-Type: application/json" \ -d '{ "headers": "From: alice@example.com\nTo: bob@example.org\nSubject: Meeting\nReceived: from mx.example.com by mail.recipient.org with ESMTPS; Mon, 15 Jan 2024 09:00:05 +0000\nAuthentication-Results: mail.recipient.org; spf=pass; dkim=pass; dmarc=pass" }'
RESPONSE — 200 OK
{ "status": "ok", "data": { "header_count": 5, "key_headers": { "From": ["alice@example.com"], "Subject": ["Meeting"], "Authentication-Results": ["mail.recipient.org; spf=pass; dkim=pass; dmarc=pass"] }, "auth_results": { "spf": { "status": "pass", "details": "SPF PASS ..." }, "dkim": { "status": "pass", "details": "DKIM PASS ..." }, "dmarc": { "status": "pass", "details": "DMARC PASS ..." }, "arc": { "status": "none", "details": "" } }, "relay": { "total_delay": 0, "hops": [ { "hop": 1, "from": "mx.example.com", "by": "mail.recipient.org", "with": "ESMTPS", "time_utc": "2024-01-15 09:00:05 UTC", "delay_seconds": 0, "percent": 0 } ] }, "all_headers": { "From": ["alice@example.com"], "To": ["bob@example.org"], "Received": ["from mx.example.com by mail.recipient.org with ESMTPS ..."] } } }
💡
Multi-valued headers: all_headers and key_headers use a dict[string, string[]] shape — every value is a list. This preserves duplicate headers (typically Received:) in original document order. Even single-value headers come back as one-element lists so callers don't have to type-check.

Hash Text

POST /api/v2/hash/text Compute cryptographic hashes of a text string
ParameterTypeRequiredDescription
textstringrequiredThe text to hash (UTF-8 encoded)
algorithmsstring[]optionalArray of algorithms. Supported: MD5 SHA-1 SHA-256 SHA-384 SHA-512. Defaults to all.
RESPONSE — 200 OK
{ "status": "ok", "data": { "input_length": 11, "hashes": { "MD5": "3e25960a79dbc69b674cd4ec67a72c62", "SHA-1": "7b502c3a1f48c8609ae212cdfb639dee39673f5e", "SHA-256":"a591a6d40bf420404a011733cfb7b190d62c65bf0bcda32b57b277d9ad9f146e" } } }

Hash URL

POST /api/v2/hash/url Fetch a remote file and compute its cryptographic hashes
ParameterTypeRequiredDescription
urlstringrequiredPublic HTTPS URL of the file to fetch and hash. Maximum 512 MB.
algorithmsstring[]optionalHash algorithms to compute. Defaults to ["MD5","SHA-256"]
RESPONSE — 200 OK
{ "status": "ok", "data": { "url": "https://example.com/file.zip", "filename": "file.zip", "size": 1048576, "size_fmt": "1.0 MB", "hashes": { "MD5": "d41d8cd98f00b204e9800998ecf8427e", "SHA-256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" } } }

Domain Age

POST /api/v2/domain/age Compute a domain's age and days-until-expiry from WHOIS
ParameterTypeRequiredDescription
domainstringrequiredDomain to look up (e.g. example.com)
RESPONSE — 200 OK
{ "status": "ok", "data": { "domain": "example.com", "created": "1995-08-14T04:00:00+00:00", "created_human": "14 August 1995", "expires": "2026-08-13T04:00:00+00:00", "expires_human": "13 August 2026", "registrar": "IANA", "status": "clientTransferProhibited", "age": "30 years, 11 months, 14 days", "age_days": 11302, "days_until_expiry": 15 } }

DMARC Analyser

POST /api/v2/dmarc Fetch and parse the _dmarc TXT record for a domain
ParameterTypeRequiredDescription
domainstringrequiredDomain to analyse. Do NOT prepend _dmarc. — the tool adds it.
RESPONSE — 200 OK
{ "status": "ok", "data": { "domain": "example.com", "record": "v=DMARC1; p=reject; rua=mailto:dmarc@example.com; pct=100", "tags": { "v": "DMARC1", "p": "reject", "rua": "mailto:dmarc@example.com", "pct": "100" }, "summary": "DMARC policy=reject, aggregate reports enabled", "warnings": [] } }
💡
A 404 NO_DMARC_RECORD response means _dmarc.<domain> either does not exist or has no v=DMARC1 record.

CIDR / Subnet Info

POST /api/v2/cidr Compute subnet details for a CIDR block or bare IP address
ParameterTypeRequiredDescription
cidrstringrequiredIPv4 or IPv6 CIDR (e.g. 10.0.0.0/8, 2001:db8::/32). A bare address is treated as /32 (v4) or /128 (v6).
RESPONSE — 200 OK
{ "status": "ok", "data": { "cidr": "10.0.0.0/24", "version": 4, "network_address": "10.0.0.0", "broadcast_address": "10.0.0.255", "netmask": "255.255.255.0", "hostmask": "0.0.0.255", "prefix_length": 24, "num_addresses": 256, "usable_hosts": 254, "first_usable": "10.0.0.1", "last_usable": "10.0.0.254", "is_private": true, "is_global": false, "is_multicast": false, "is_reserved": false, "is_loopback": false } }

QR Code Generator

POST /api/v2/qr/generate Generate a QR code as a PNG image or Unicode block-character art
ParameterTypeRequiredDescription
datastringrequiredText or URL to encode. Maximum ~2900 characters.
formatstringoptionalpng (default) returns a base64-encoded image; unicode returns block-character art plus the raw module matrix.
ec_levelstringoptionalError-correction level: L (7%), M (15%, default), Q (25%), H (30%). Higher tolerates more damage but produces a denser code.
box_sizeintegeroptionalPNG only — pixels per QR module. Clamped to [5, 20]. Defaults to 10.
borderintegeroptionalQuiet-zone width in modules. Defaults to 4 for PNG, 2 for unicode.
REQUEST — curl (PNG)
curl -X POST https://www.diginterface.com/api/v2/qr/generate \ -H "Authorization: Bearer di_a1b2c3d4e5f6g7h8i9j0k1l2" \ -H "Content-Type: application/json" \ -d '{ "data": "https://www.diginterface.com", "format": "png", "ec_level": "M", "box_size": 10 }'
RESPONSE — 200 OK (format=png)
{ "status": "ok", "data": { "png_base64": "iVBORw0KGgoAAAANSUhEUgAAAOwAAADsCAYAAA...", "content_type": "image/png" } }
RESPONSE — 200 OK (format=unicode)
{ "status": "ok", "data": { "unicode_art": "███████████████████...\n██ ▄▄▄▄▄ █▄█▀██▄█▀▀...", // half-block-character grid "line_count": 15, "matrix": [ // raw 0/1 module grid, includes quiet zone [0, 0, 0, 0, ...], [0, 1, 1, 1, ...] ] } }
💡
The matrix returned with format=unicode is the raw QR module grid — 1 = dark module, 0 = light — including the quiet-zone border. Callers can render it into their own visual form (e.g. a colored-<td> HTML table for pasting into Word/Outlook).

QR Code Decoder

POST /api/v2/qr/decode Decode QR code(s) or barcode(s) from an image

Accepts either multipart/form-data with an image file field, or application/json with an image_base64 string. Multiple codes in one image are all returned. 5 MB image size cap. Accepts PNG, JPEG, GIF, WebP, and BMP.

ParameterTypeRequiredDescription
imagefilemultipartImage file, submitted as a multipart upload. Preferred for CLI usage.
image_base64stringjsonRaw image bytes, base64-encoded. Preferred for JSON-only callers. Standard or URL-safe alphabet.
REQUEST — curl (multipart upload)
curl -X POST https://www.diginterface.com/api/v2/qr/decode \ -H "Authorization: Bearer di_a1b2c3d4e5f6g7h8i9j0k1l2" \ -F "image=@qr-code.png"
REQUEST — curl (JSON with base64)
curl -X POST https://www.diginterface.com/api/v2/qr/decode \ -H "Authorization: Bearer di_a1b2c3d4e5f6g7h8i9j0k1l2" \ -H "Content-Type: application/json" \ -d '{ "image_base64": "iVBORw0KGgoAAAA..." }'
RESPONSE — 200 OK
{ "status": "ok", "data": { "results": [ { "data": "https://www.diginterface.com", "type": "QRCODE", "rect": { "left": 40, "top": 40, "width": 290, "height": 290 } } ] } }
💡
An empty results list means the image decoded successfully but no QR / barcode was found in it — not an error. Barcodes (EAN, Code 128, etc.) are also detected and returned with the appropriate type value.

List API Keys

GET /api/v2/account/keys List all API keys for the authenticated account
RESPONSE — 200 OK
{ "status": "ok", "data": { "keys": [ { "prefix": "di_a1b2", "name": "Production key", "scopes": "dns,domain,email,utils,account", "rate_limit": 100, "expires_at": "2026-07-26T00:00:00Z", // null if never expires "created_at": "2026-04-27T10:00:00Z", "last_used": "2026-04-27T14:32:00Z", // null if never used "is_active": true } ] } }

API Usage

GET /api/v2/account/usage Current rate limit usage and request history for the authenticated key
RESPONSE — 200 OK
{ "status": "ok", "data": { "key_prefix": "di_a1b2", "requests_today": 27, "requests_limit": 100, "requests_remaining":73, "reset_at": "2026-04-25T00:00:00Z" } }
💡
Ready to get started? Create a free account then head to your account dashboard to generate your first API key.