Deliverlens for developers
Your first API check.
Create a key, choose a service and bring email testing into your application.
1. Create a key and authenticate
Sign in and open API keys. Give the key a name, choose its permissions and select an expiry or No expiry. Copy the key when it appears; it is shown only once.
Send the key in the Authorization: Bearer header from your server. Keep it in a private environment variable, outside browser code, URLs and Git.
export DELIVERLENS_API_KEY='YOUR_API_KEY'| Permission | Allows |
|---|---|
services:read | List services and read your service results. |
services:run | Start an email, DNS or blocklist check. |
tests:create | Create a message-test address. |
tests:read | Read your message-test results. |
analytics:read | Read your account’s API usage analytics. |
Every verified registered customer can create a key, connect MCP and read their own results. Starting checks through API or MCP requires an active paid subscription and the relevant service allowance. Website tools remain available.
2. Check availability and allowance
Read your account’s services before submitting a check. This returns each service’s availability, plan access, remaining usage and reset information. A key does not create a separate allowance.
curl --fail-with-body 'https://api.deliverlens.com/api/v1/account/services' \
-H 'Accept: application/json' \
-H "Authorization: Bearer $DELIVERLENS_API_KEY"Requires services:read. A service must be available, enabled by your plan and have usage remaining.
3. Start a check
This SPF example checks fintrate.com. Generate a new 64-character hexadecimal request_id once for each new check. Reuse that same identifier and input when retrying.
REQUEST_ID="$(openssl rand -hex 32)"
curl --fail-with-body 'https://api.deliverlens.com/api/v1/account/services/spf-checker/runs' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DELIVERLENS_API_KEY" \
--data "{\"target\":\"fintrate.com\",\"request_id\":\"$REQUEST_ID\"}"Requires services:run. Save the returned data.id. A 202 response means the check was queued; it does not mean the check passed. DKIM also requires the published selector. BIMI uses default when no selector is supplied.
4. Read your result
Replace CHECK_RUN_ID with the check ID returned above. Read the status until the job finishes; polling does not start another check.
curl --fail-with-body 'https://api.deliverlens.com/api/v1/account/service-runs/CHECK_RUN_ID' \
-H 'Accept: application/json' \
-H "Authorization: Bearer $DELIVERLENS_API_KEY"Requires services:read. Use data.status to distinguish queued or running checks from completed or failed jobs. Read data.result for the actual findings, evidence and limitations. Only results owned by your account can be read, and expired reports are unavailable.
Test a complete email message
Create a message test, send your email to the address returned by the API, then retrieve the report using its test ID. Use your normal sending platform so the message carries its real authentication headers.
MESSAGE_REQUEST_ID="$(openssl rand -hex 32)"
curl --fail-with-body 'https://api.deliverlens.com/api/v1/account/tests' \
-H 'Accept: application/json' \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $DELIVERLENS_API_KEY" \
--data "{\"request_id\":\"$MESSAGE_REQUEST_ID\"}"
curl --fail-with-body 'https://api.deliverlens.com/api/v1/account/tests/TEST_ID' \
-H 'Accept: application/json' \
-H "Authorization: Bearer $DELIVERLENS_API_KEY"Creation needs tests:create; retrieval needs tests:read. The first received message is used. A fresh message revision needs a new test.
Endpoint reference
These endpoints come from the current API contract. Expand an operation to see its required fields and permission. The OpenAPI document provides the complete machine-readable schemas.
GET/api/v1/account/servicesAvailable services and allowances
Get this account’s service availability, plan allowances and remaining usage before running a check.
Permission: services:read
GET/api/v1/account/service-runs/{checkRun}Read a check result
Read an owned check by ID. Queued or running means the result is not ready. This read does not start another check.
Permission: services:read
POST/api/v1/account/testsCreate a message test
Create a test email address using the account’s existing message-test allowance. Ask before consuming a test. The user must send their message to the returned address.
Permission: tests:create
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
}
},
"required": [
"request_id"
],
"additionalProperties": false
}GET/api/v1/account/tests/{test}Read a message test
Read an owned message test by ID. Waiting means no analysed message is ready. Return the actual evidence and avoid promises about inbox delivery.
Permission: tests:read
POST/api/v1/account/services/email-verifier/runsEmail Verifier
Check an email address for formatting problems and confirm whether its domain is set up to receive email. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "Email address to check, with a public DNS domain."
}
},
"required": [
"request_id",
"target"
],
"additionalProperties": false
}POST/api/v1/account/services/spf-checker/runsSPF Checker
Find a domain’s SPF record and spot common configuration problems. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "A public DNS domain, for example fintrate.com. Do not include a URL or path."
},
"sending_ip": {
"type": "string",
"maxLength": 45,
"description": "Optional public sending IP for an SPF evaluation."
}
},
"required": [
"request_id",
"target"
],
"additionalProperties": false
}POST/api/v1/account/services/dkim-checker/runsDKIM Checker
Look up a DKIM public key and check whether its selector and key material are published correctly. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "A public DNS domain, for example fintrate.com. Do not include a URL or path."
},
"selector": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"description": "Published selector. DKIM requires the selector from a signed message; BIMI defaults to default."
}
},
"required": [
"request_id",
"target",
"selector"
],
"additionalProperties": false
}POST/api/v1/account/services/dmarc-checker/runsDMARC Checker
Find a DMARC record, review its policy and alignment settings, and catch common mistakes. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "A public DNS domain, for example fintrate.com. Do not include a URL or path."
}
},
"required": [
"request_id",
"target"
],
"additionalProperties": false
}POST/api/v1/account/services/bimi-checker/runsBIMI Checker
Check whether a BIMI record is published and review its declared logo and certificate locations. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "A public DNS domain, for example fintrate.com. Do not include a URL or path."
},
"selector": {
"type": "string",
"minLength": 1,
"maxLength": 128,
"description": "Published selector. DKIM requires the selector from a signed message; BIMI defaults to default."
}
},
"required": [
"request_id",
"target"
],
"additionalProperties": false
}POST/api/v1/account/services/domain-blacklist-checker/runsDomain Blacklist Checker
Check whether a domain appears on the reputation sources connected to Deliverlens. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "A public DNS domain, for example fintrate.com. Do not include a URL or path."
}
},
"required": [
"request_id",
"target"
],
"additionalProperties": false
}POST/api/v1/account/services/email-blacklist-checker/runsEmail Blacklist Checker
Review the reputation coverage available for an email address and see whether it applies to the address or its domain. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "Email address to check, with a public DNS domain."
}
},
"required": [
"request_id",
"target"
],
"additionalProperties": false
}POST/api/v1/account/services/ip-blacklist-checker/runsIP Blacklist Checker
Check a public sending IP against the reputation sources connected to Deliverlens. Starts a queued check and uses the current service allowance. Read it with get_check_result. Check availability with list_services first.
Permission: services:run
{
"type": "object",
"properties": {
"request_id": {
"type": "string",
"pattern": "^[a-f0-9]{64}$",
"description": "A new random 64-character lowercase hexadecimal idempotency identifier. Reuse it only when retrying the same operation."
},
"target": {
"type": "string",
"minLength": 1,
"maxLength": 254,
"description": "A public IPv4 or IPv6 address."
}
},
"required": [
"request_id",
"target"
],
"additionalProperties": false
}Limits, retries and key lifetime
- Your plan defines per-minute, daily, monthly, concurrent and per-service limits. Keys and MCP connections share those account limits.
- Back off when you receive
429. RespectRetry-Afterwhen provided and check the account’s usage/reset information. - Retry an interrupted submission with its original
request_idand identical input. Changing the input needs a new identifier. - Poll with a delay and increase the interval while a job is pending. Do not treat a timeout or unavailable provider as a passing check.
- Expiring keys receive expiry notifications. A key with No expiry stays active until revoked; it still obeys account permissions and plan limits.
Handle errors clearly
| Status | What to do |
|---|---|
| 401 | Supply a valid key. Expired and revoked keys cannot authenticate. |
| 403 | Check the key’s permissions and paid subscription access. Free accounts can use website tools. |
| 404 | Check the resource ID and ownership, or the requested service name. |
| 409 | A submission conflicts with an existing request identifier. Retry with the original input. |
| 410 | The report has expired. Start a new check when needed. |
| 422 | Correct the invalid fields described in the response. |
| 429 | A rate, concurrency or usage limit was reached. Wait until the applicable limit resets. |
| 503 | The service or provider is temporarily unavailable. Retry with the same submission identifier. |
Need help with an integration?
Send the endpoint, response status and time of the request. Keep API keys and private message content out of support requests.
Contact our team