FirstSales DNS API
DNS record and deliverability diagnostics.
DNS record and deliverability diagnostics.
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
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.curl "https://apis.io/api/v1/apis/firstsales-io:firstsales-io-dns-api"
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.
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: 3.2.0
info:
title: Firstsales Io DNS API
version: 1.0.0
contact:
name: FirstSales Support
email: firstsales@support.communicate.so
url: https://firstsales.io
license:
name: Terms of Service
url: https://firstsales.io/terms-of-service/
termsOfService: https://firstsales.io/terms-of-service/
x-apiVersioning:
strategy: url-path
current: v1
pattern: https://firstsales.io/api/v1/{operation}
policyUrl: https://firstsales.io/developers/#versioning
note: A breaking change ships under a new prefix (/api/v2/); v1 keeps its contract. The unprefixed /api/{operation} form is an unversioned alias of the current version and may change without notice - call the /api/v1/ form.
x-deprecationPolicy:
minimumNoticeDays: 180
signalling: 'A deprecated version''s responses carry Deprecation: true and a Sunset header with the retirement date (RFC 8594), plus a Link rel="deprecation" to the migration notes.'
announcement: https://firstsales.io/developers/#deprecation-policy
policyUrl: https://firstsales.io/developers/#deprecation-policy
currentlyDeprecated: []
description: 'Operations tagged DNS across 2 of this provider''s published API definitions: firstsales-io-openapi.json, openapi.json. Each path carries the servers of the definition it was published in.'
servers:
- url: https://firstsales.io
description: Production
security: []
tags:
- name: DNS
description: DNS record and deliverability diagnostics.
paths:
/api/v1/dns/check:
post:
operationId: checkDnsRecord
summary: Run one specific DNS/email-authentication/security check against a domain
description: 'Single-check DNS diagnostic tool: pass a `checkType` (spf, dkim, dmarc, mx, general, blacklist, iprep, ptr, tls, bimi, arc, ns, txt, cname, a, aaaa, soa, whois, availability, propagation, authority, dnssec, deliverability, smtp, or port) and get back pass/warn/fail sub-checks plus a 0-100 score. Use `dns/validate` instead if you need SPF+DKIM+DMARC+MX together in one call. Rate limit: 10 requests/minute per IP.'
tags:
- DNS
security: []
x-rateLimit:
limit: 10
windowSeconds: 60
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
domain:
type: string
description: Domain name, or an IPv4 address when checkType is iprep/ptr.
checkType:
type: string
enum:
- spf
- dkim
- dmarc
- mx
- general
- blacklist
- iprep
- ptr
- tls
- bimi
- arc
- ns
- txt
- cname
- a
- aaaa
- soa
- whois
- availability
- propagation
- authority
- dnssec
- deliverability
- smtp
- port
selector:
type: string
description: Optional DKIM selector (alphanumeric + hyphens, max 63 chars); only used when checkType is dkim.
required:
- domain
- checkType
responses:
'200':
description: Check result for the requested checkType.
content:
application/json:
schema:
$ref: '#/components/schemas/DnsCheckResult'
'400':
description: Invalid request — bad input, missing field, or malformed value.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit exceeded for this endpoint. Wait Retry-After seconds and retry.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
servers:
- url: https://firstsales.io
description: Production
/api/v1/dns/dkim:
post:
operationId: checkDkimRecord
summary: Look up and validate a domain's DKIM record
description: 'Auto-detects common DKIM selectors (or uses the selector you pass in manual mode), then reports key type, estimated key strength, testing-mode flag, and validity. Use this for a DKIM-focused check with more detail than dns/check''s generic dkim type. Rate limit: 10 requests/minute per IP.'
tags:
- DNS
security: []
x-rateLimit:
limit: 10
windowSeconds: 60
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
domain:
type: string
selector:
type: string
description: DKIM selector, e.g. `google`. Required when mode is 'manual'.
mode:
type: string
enum:
- auto
- manual
description: Defaults to auto-detect of common selectors.
required:
- domain
responses:
'200':
description: DKIM lookup result.
content:
application/json:
schema:
$ref: '#/components/schemas/DkimResult'
'400':
description: Invalid request — bad input, missing field, or malformed value.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Domain does not exist or has no DNS records.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit exceeded for this endpoint. Wait Retry-After seconds and retry.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
servers:
- url: https://firstsales.io
description: Production
/api/v1/dns/validate:
post:
operationId: validateDnsAuthentication
summary: Run SPF, DKIM, DMARC, and MX checks together with a confidence score
description: 'Multi-check email-authentication validator: runs SPF/DKIM/DMARC/MX in parallel (or a subset via `checks`) and returns a combined confidence_score. Use this for a one-call deliverability audit instead of four separate dns/check calls. Rate limit: 10 requests/minute per IP.'
tags:
- DNS
security: []
x-rateLimit:
limit: 10
windowSeconds: 60
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
domain:
type: string
checks:
type: array
items:
type: string
enum:
- spf
- dkim
- dmarc
- mx
description: Subset of checks to run. Defaults to all four.
options:
type: object
properties:
dkimSelector:
type: string
description: Optional DKIM selector override.
required:
- domain
responses:
'200':
description: Combined authentication validation result.
content:
application/json:
schema:
$ref: '#/components/schemas/DnsValidateResult'
'400':
description: Invalid request — bad input, missing field, or malformed value.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: Domain does not exist or has no DNS records.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit exceeded for this endpoint. Wait Retry-After seconds and retry.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
servers:
- url: https://firstsales.io
description: Production
/api/v1/dns/reverse:
post:
operationId: reverseDnsLookup
summary: Reverse-DNS (PTR) lookup for an IPv4 address, with forward-confirmation
description: 'Looks up PTR hostnames for an IPv4 address and re-resolves each hostname''s A records to check they point back to the original IP (forward-confirmed reverse DNS, a common sending-IP reputation signal). Rejects private/reserved IPs. Rate limit: 10 requests/minute per IP.'
tags:
- DNS
security: []
x-rateLimit:
limit: 10
windowSeconds: 60
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
ip:
type: string
format: ipv4
example: 203.0.113.10
required:
- ip
responses:
'200':
description: Reverse DNS lookup result.
content:
application/json:
schema:
$ref: '#/components/schemas/ReverseDnsResult'
'400':
description: Invalid request — bad input, missing field, or malformed value.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: Rate limit exceeded for this endpoint. Wait Retry-After seconds and retry.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
headers:
RateLimit-Limit:
description: Requests allowed in the current window.
schema:
type: integer
RateLimit-Remaining:
description: Requests still available in the current window.
schema:
type: integer
RateLimit-Reset:
description: Seconds until the current window resets.
schema:
type: integer
RateLimit-Policy:
description: Policy in the form "<limit>;w=<window seconds>".
schema:
type: string
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
servers:
- url: https://firstsales.io
description: Production
components:
schemas:
Error:
type: object
description: Shared error envelope used by public endpoints and the rate-limit wrapper. Mail-tester handler errors use MailTesterError.
properties:
error:
type: string
description: Machine-readable error code, e.g. `invalid_input`.
message:
type: string
description: Human-readable explanation.
hint:
type: string
description: How to fix the request.
required:
- error
- message
- hint
ReverseDnsResult:
type: object
properties:
ip:
type: string
hostnames:
type: array
items:
type: string
forwardResults:
type: array
items:
type: object
properties:
hostname:
type: string
forwardIps:
type: array
items:
type: string
matches:
type: boolean
required:
- hostname
- forwardIps
- matches
ptrError:
type:
- string
- 'null'
ipClass:
type: object
networkType:
type: string
required:
- ip
- hostnames
- forwardResults
- networkType
DkimResult:
type: object
properties:
domain:
type: string
selector:
type: string
recordFound:
type: boolean
validStructure:
type: boolean
publicKeyPresent:
type: boolean
rawRecord:
type: string
status:
type: string
enum:
- Valid
- Invalid
- Not Found
details:
type: object
properties:
versionTag:
type: boolean
keyType:
type: string
estimatedKeyBits:
type:
- number
- 'null'
testingMode:
type: boolean
allSelectorsFound:
type: array
items:
type: string
message:
type: string
required:
- domain
- selector
- recordFound
- validStructure
- publicKeyPresent
- rawRecord
- status
DnsCheckResult:
type: object
description: Generic result shape shared by all dns/check checkTypes.
properties:
exists:
type: boolean
records:
type: array
items:
type: string
checks:
type: array
items:
type: object
properties:
label:
type: string
status:
type: string
enum:
- pass
- warn
- fail
detail:
type: string
required:
- label
- status
- detail
score:
type: number
minimum: 0
maximum: 100
error:
type: string
message:
type: string
required:
- exists
DnsValidateResult:
type: object
properties:
domain:
type: string
spf:
type: object
dkim:
type: object
dmarc:
type: object
mx:
type: object
confidence_score:
type: number
minimum: 0
maximum: 100
metadata:
type: object
properties:
cached:
type: boolean
duration_ms:
type: number
required:
- cached
- duration_ms
required:
- domain
- metadata
x-refined-from:
- firstsales-io-openapi.json
- openapi.json
x-apiVersioning:
strategy: url-path
current: v1
pattern: https://firstsales.io/api/v1/{operation}
policyUrl: https://firstsales.io/developers/#versioning
note: A breaking change ships under a new prefix (/api/v2/); v1 keeps its contract. The unprefixed /api/{operation} form is an unversioned alias of the current version and may change without notice - call the /api/v1/ form.
x-deprecationPolicy:
minimumNoticeDays: 180
signalling: 'A deprecated version''s responses carry Deprecation: true and a Sunset header with the retirement date (RFC 8594), plus a Link rel="deprecation" to the migration notes.'
announcement: https://firstsales.io/developers/#deprecation-policy
policyUrl: https://firstsales.io/developers/#deprecation-policy
currentlyDeprecated: []