Skip to content

Run checks and wait for results

How-to guide
For:
Developers

The HostRepute API runs three kinds of one-off check on any domain or IP, whether your team monitors it or not. Blocklist and certificate checks run in the background: you start one, then read its async API scan status until it ends, or pass a callback_url and HostRepute tells you when it’s done. An email authentication check runs while you wait and returns its result straight away. Each check uses 1 credit.

Check Start it Read the result How it runs
Blocklist POST /api/v1/blacklist/check GET /api/v1/blacklist/status/{uuid} In the background
Certificate POST /api/v1/certificates/check GET /api/v1/certificates/status/{uuid} In the background
Email authentication POST /api/v1/deliverability/check GET /api/v1/deliverability/status/{uuid} While you wait

The paths keep the API’s older words: blacklist for blocklist and deliverability for email authentication.

  • A team API token with the abilities for the checks you run: blacklist:check and blacklist:read, certificate:check and certificate:read, or deliverability:check and deliverability:read. Read Authentication and API tokens and the token abilities.
  • Credits. The team needs 1 credit for each check it starts. Read Credits to see the balance and buy more.
  • For a callback: an https endpoint with a public address. The polling example below uses jq to read JSON.

The examples read your token from the HOSTREPUTE_TOKEN environment variable.

Start a blocklist check and poll its status

Section titled “Start a blocklist check and poll its status”
  1. Start the check with the domain or IP in host. To use the blocklists of a check profile other than your default one, add its UUID as data_source_group_uuid.

    Start a blocklist check
    curl -s -X POST https://app.hostrepute.com/api/v1/blacklist/check \
    -H "Authorization: Bearer $HOSTREPUTE_TOKEN" \
    -H "Accept: application/json" \
    -H "Content-Type: application/json" \
    -d '{"host": "example.net"}'

    HostRepute answers 201 Created right away, before any blocklist has answered. Keep the uuid:

    Response (shortened)
    {
    "data": {
    "uuid": "01a178db-d833-70d2-8436-d39da22fcd8a",
    "host": "example.net",
    "status": "processing",
    "is_completed": false,
    "callback_status": null,
    "data_source_count": 4,
    "completed_source_count": 0,
    "progress_percent": 0,
    "started_at": "2026-10-26T15:37:16.000000Z",
    "completed_at": null
    }
    }
  2. Read the status every few seconds until status is completed or failed. While the check runs, status is pending or processing, and completed_source_count and progress_percent show how many blocklists have answered.

    Wait for the check to end
    SCAN_UUID=01a178db-d833-70d2-8436-d39da22fcd8a
    while true; do
    STATUS=$(curl -s "https://app.hostrepute.com/api/v1/blacklist/status/$SCAN_UUID" \
    -H "Authorization: Bearer $HOSTREPUTE_TOKEN" \
    -H "Accept: application/json" | jq -r '.data.status')
    echo "$STATUS"
    case "$STATUS" in
    completed | failed) break ;;
    pending | processing) sleep 5 ;;
    *) echo "Unexpected response, stopping" >&2; break ;;
    esac
    done
  3. Read the result. result appears once the check has ended:

    Show which blocklists list the domain or IP
    curl -s "https://app.hostrepute.com/api/v1/blacklist/status/$SCAN_UUID" \
    -H "Authorization: Bearer $HOSTREPUTE_TOKEN" \
    -H "Accept: application/json" |
    jq '.data.result | {is_listed, listed_count, total_count, failed_count, listed_on: [.data_sources[] | select(.is_listed) | .data_source_name]}'
    Output
    {
    "is_listed": true,
    "listed_count": 1,
    "total_count": 4,
    "failed_count": 0,
    "listed_on": [
    "black.uribl.com"
    ]
    }

Each entry in result.data_sources is one blocklist: is_listed says whether it lists the domain or IP, and source_status is failed when that blocklist didn’t answer. A blocklist that didn’t answer is a warning, not a listing. When no blocklist answered at all, the whole check is failed, error_message says why, result holds only an error message, and the credit is refunded.

The 120 requests a minute your team can make cover polling too, so one request every few seconds per check leaves room for the rest of your integration. Read Rate limits.

The official SDKs have check-and-wait helpers that run this loop for you, but they aren’t published yet.

A certificate check works the same way, at /api/v1/certificates. Besides host, you can set protocol (https, tls, or starttls_smtp, starttls_imap, starttls_pop3, starttls_ldap or starttls_ftp), port (the protocol’s usual port when you leave it out) and sni:

Check the certificate of a mail server over STARTTLS
curl -s -X POST https://app.hostrepute.com/api/v1/certificates/check \
-H "Authorization: Bearer $HOSTREPUTE_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"host": "smtp.example.com", "protocol": "starttls_smtp", "port": 587}'
  • The response starts at status pending. Poll GET /api/v1/certificates/status/{uuid} until status is completed or failed.
  • HostRepute checks every IP address the host resolves to. In the result, result.status is the certificate’s health (healthy, expiring, expired, invalid or failed), result.certificate_grade its grade from A+ to F, and result.days_remaining how long it’s still valid. Read Monitor TLS certificates for what the checks mean.
  • When HostRepute can’t get a certificate from any of the host’s addresses, it tries twice more, 30 and then 60 seconds later, and status stays processing meanwhile. After the third failure the check is failed and the credit is refunded.

An email authentication check answers in the same request, so there is nothing to poll. Name the checks you want in checks, or leave out both checks and data_source_group_uuid to run all 13:

Check SPF, DMARC and MX records
curl -s -X POST https://app.hostrepute.com/api/v1/deliverability/check \
-H "Authorization: Bearer $HOSTREPUTE_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"host": "example.com", "checks": ["spf_record", "dmarc_record", "mx_health"]}'
  • data.status is the overall result: passed, warning or failed. Each entry in data.result.checks has its own status (passed, warning, failed or skipped) and a message. The email authentication checks list what each one verifies.
  • meta.credit_cost is what the check cost and meta.credits_remaining the team’s balance after it.
  • With data_source_group_uuid and no checks, the check profile’s email authentication checks run.
  • GET /api/v1/deliverability/status/{uuid} reads a stored result again for as long as your plan keeps email authentication history (see Plans and limits), then answers 404.

Add callback_url to a blocklist or certificate check, and HostRepute sends a POST to that URL when the check ends:

Start a blocklist check with a callback
curl -s -X POST https://app.hostrepute.com/api/v1/blacklist/check \
-H "Authorization: Bearer $HOSTREPUTE_TOKEN" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"host": "example.net", "callback_url": "https://hooks.example.com/hostrepute/scans"}'
  • The URL must use https, be at most 2,048 characters, and resolve only to public addresses. HostRepute checks it when you start the check and again before it sends the callback. Receive webhooks lists the rules.
  • The callback is a blacklist.scan.completed or certificate.scan.completed event, sent whether the check completed or failed. Its data.status says which.
  • callback_status in the status response tracks delivery: null before HostRepute sends it, then retrying, sent or failed (a certificate check also shows sending while the request is in flight).
  • A blocklist check that times out, or that HostRepute can’t queue, ends failed without a callback. If you rely on callbacks, still poll a check whose callback hasn’t arrived after 15 minutes.

Blocklist, certificate and email authentication checks cost 1 credit each, as the credit costs list:

  • HostRepute takes the credit when the check starts. When the team has too few credits, it answers 402 Payment Required and starts nothing:

    402 Payment Required
    {
    "message": "Insufficient credits.",
    "required_credits": 1,
    "available_credits": 0
    }
  • A check that fails is refunded, once: a blocklist check that no blocklist answered, that couldn’t finish or be queued, or that timed out; a certificate check that failed after its retries; an email authentication check that couldn’t run. A check that runs and finds problems, such as a listing or a missing DMARC record, keeps its credit.

  • There is no idempotency key. Every request that HostRepute accepts starts a new check and uses another credit, so never repeat a request that got a 2xx answer. Repeat one only after a 429 (wait for Retry-After) or an error that shows nothing started. If a request times out before you get an answer, the check may have started anyway, and the API has no list of the checks you started to look it up.

Errors describes every error body the API returns.

SettingDefaultHow to change
Callback URL (callback_url) of a blocklist or certificate check2,048 characters, HTTPS, public addresses onlyFixed
A blocklist check started through the API that hasn't endedMarked failed and refunded 15 minutes after it started, without a callbackFixed
A certificate check that can't get a certificate from the hostTried 3 times, 30 and then 60 seconds apart, then marked failed and refundedFixed
  • The status response shows status completed, is_completed true and progress_percent 100, and result holds the answers.
  • With a callback, callback_status is sent and your endpoint logged the event.
  • For an email authentication check, meta.credits_remaining went down by 1.
  • 402 with "Insufficient credits." The team’s balance is lower than required_credits. Buy credits as described in Credits, then start the check again.
  • 403 with "This action is unauthorized." The token lacks the ability the endpoint needs, for example blacklist:read for the status request. Create a token that has it.
  • 422 on callback_url. The callback URL must be a valid HTTPS URL. means it isn’t an https URL; The callback url must be a public HTTPS webhook URL. means its host is local, private or doesn’t resolve.
  • 422 on data_source_group_uuid. The UUID isn’t a check profile of your team, or that profile has no blocklists. List your profiles with GET /api/v1/data-source-groups.
  • 404 on a status request. The UUID is wrong or belongs to another team, or an email authentication result is older than your plan’s history.
  • The check ended failed. For a blocklist check, error_message says whether the blocklists didn’t answer or the check timed out. It isn’t a listing, and the credit is refunded; start it again later.
  • A certificate check stays processing for over a minute. HostRepute couldn’t reach the host and is trying again. It ends failed after the third try.
  • callback_status is failed. Your endpoint didn’t answer with a 2xx status in time, redirected, or its address stopped being public. Receive webhooks explains the retries.