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.

TerminalDeliverlens
export DELIVERLENS_API_KEY='YOUR_API_KEY'
API key permissions
PermissionAllows
services:readList services and read your service results.
services:runStart an email, DNS or blocklist check.
tests:createCreate a message-test address.
tests:readRead your message-test results.
analytics:readRead 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.

TerminalDeliverlens
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.

TerminalDeliverlens
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.

TerminalDeliverlens
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.

TerminalDeliverlens
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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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

JSON schemaDeliverlens
{
    "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. Respect Retry-After when provided and check the account’s usage/reset information.
  • Retry an interrupted submission with its original request_id and 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

API error status codes
StatusWhat to do
401Supply a valid key. Expired and revoked keys cannot authenticate.
403Check the key’s permissions and paid subscription access. Free accounts can use website tools.
404Check the resource ID and ownership, or the requested service name.
409A submission conflicts with an existing request identifier. Retry with the original input.
410The report has expired. Start a new check when needed.
422Correct the invalid fields described in the response.
429A rate, concurrency or usage limit was reached. Wait until the applicable limit resets.
503The 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

Choose what this browser may remember and whether Google Analytics may measure site use. Advertising storage and personalization stay disabled.

Choices stay in this browser when storage is available. Rejecting preferences removes the saved theme, not your ability to change appearance for the current page. You can withdraw analytics consent here at any time.