Hookroast
Sign in

API Reference

Integrate HookRoast's reputation engine into your own apps, and try every endpoint live.

The HookRoast API is REST over HTTPS. All requests and responses are JSON. The base URL is:

base url
https://api.hookroast.com/api/v1

Create an API key on the Developers page (sign-in required). Every call draws from your monthly credit wallet.

Live console

Paste an API key to run the Try it panels against the real API. Calls spend credits. Your key is stored only in this browser. Don't use a production key on a shared machine.

No key set. Try it panels will prompt you.

Authentication

Pass your API key in the x-api-key header, or as a bearer token. Keys look like hr_live_… and are shown only once at creation.

curl
curl https://api.hookroast.com/api/v1/reputation \
  -X POST \
  -H "x-api-key: hr_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"domain":"acme.io"}'

Or Authorization: Bearer hr_live_your_key_here. A missing or revoked key returns 401.

Rate limits

Requests are rate limited per API key (default 60 requests / 60s). Every response includes:

response headers
x-ratelimit-limit: 60
x-ratelimit-remaining: 59
x-ratelimit-reset: 1782684309

Exceeding the limit returns 429 TOO_MANY_REQUESTS with a retry-after header (seconds).

Credits

Each call spends credits from your monthly wallet: a reputation scan costs 5 credits, a bulk scan 5 × number of targets, and email validation 1 credit per email. When the wallet is exhausted the API returns 403 FORBIDDEN. Paid plans can buy top-up credits from the Billing page.

Errors

Errors use standard HTTP status codes and a consistent JSON body:

error shape
{ "error": "FORBIDDEN", "message": "…human readable…" }
  • 400 / 422 VALIDATION_ERROR: bad request body
  • 401 UNAUTHORIZED: missing/invalid API key
  • 403 FORBIDDEN: out of credits
  • 404 NOT_FOUND: unknown id
  • 429 TOO_MANY_REQUESTS: rate limited

Reputation scan

Start a scan for a single email address or domain. Scans run asynchronously: create one, then poll the GET endpoint until status is COMPLETED.

POST/api/v1/reputation

Create a scan. The body must contain exactly one of the fields below. Returns the scan id to poll.

Body parameters

emailstringoptional

Email address to scan. Provide this or `domain` (exactly one).

domainstringoptional

Bare domain to scan, e.g. acme.io. Provide this or `email` (exactly one).

Response fields

idstring

Unique scan id. Use it to poll the GET endpoint.

statusstring

PENDING · PROCESSING · COMPLETED · FAILED.

emailstring | null

The email scanned, or null for a domain scan.

domainstring

The domain scanned.

example response
{ "id": "b5f7c8ac-…", "status": "PENDING", "email": null, "domain": "acme.io" }
request
curl https://api.hookroast.com/api/v1/reputation \
  -X POST \
  -H "x-api-key: hr_live_…" \
  -H "Content-Type: application/json" \
  -d '{"domain":"acme.io"}'
POSThttps://api.hookroast.com/api/v1/reputation
Headersx-api-key: not setcontent-type: application/json
Show as cURL
curl https://api.hookroast.com/api/v1/reputation \
  -X POST \
  -H "x-api-key: hr_live_your_key"
 \
  -H "Content-Type: application/json" \
  -d '{
  "domain": "acme.io"
}'

GET/api/v1/reputation/:id

Fetch a scan. Poll until status is COMPLETED. The report includes the overall score, per-category scores, verified analyzer data, and AI analysis.

Path parameters

idstringrequired

The scan id returned by POST /reputation.

Response fields

idstring

The scan id.

statusstring

Poll until COMPLETED (or FAILED).

overallScoreinteger | null

Overall reputation 0-100; null until completed.

gradestring | null

Excellent · Good · Fair · Poor.

reportobject | null

Full report; null until completed.

report.confidenceinteger

0-100; share of analyzers that succeeded.

report.categoryScoresarray

[{ category, score }] for each scored category.

report.analysisobject

Verified per-analyzer data, keyed by analyzer.

report.aiobject

AI insights: trustScore, riskLevel, replyProbability, summary, recommendations[].

example response
{
  "id": "b5f7c8ac-…",
  "status": "COMPLETED",
  "overallScore": 84,
  "grade": "Good",
  "report": {
    "confidence": 100,
    "categoryScores": [ { "category": "Deliverability", "score": 88 } ],
    "ai": {
      "trustScore": 84, "riskLevel": "Low", "replyProbability": 70, "summary": "…",
      "recommendations": [ { "problem": "…", "impact": "Medium", "recommendation": "…", "expectedImprovement": "+5 points" } ]
    }
  }
}
request
curl https://api.hookroast.com/api/v1/reputation/SCAN_ID \
  -X GET \
  -H "x-api-key: hr_live_…"
GEThttps://api.hookroast.com/api/v1/reputation/:id
Headersx-api-key: not set
Show as cURL
curl https://api.hookroast.com/api/v1/reputation/:id \
  -X GET \
  -H "x-api-key: hr_live_your_key"

Bulk reputation

Score many emails/domains in one job (up to 1,000 targets). Targets can mix emails and bare domains.

POST/api/v1/bulk-reputation

Submit a batch of targets. Returns a job id to poll.

Body parameters

targetsstring[]required

Array of emails and/or bare domains to score. 1-1,000 entries.

Response fields

idstring

Job id. Use it to poll the GET endpoint.

statusstring

PENDING · PROCESSING · COMPLETED · FAILED.

totalCountinteger

Number of targets queued.

example response
{ "id": "4102e918-…", "status": "PENDING", "totalCount": 2 }
request
curl https://api.hookroast.com/api/v1/bulk-reputation \
  -X POST \
  -H "x-api-key: hr_live_…" \
  -H "Content-Type: application/json" \
  -d '{"targets":["stripe.com","example.org"]}'
POSThttps://api.hookroast.com/api/v1/bulk-reputation
Headersx-api-key: not setcontent-type: application/json
Show as cURL
curl https://api.hookroast.com/api/v1/bulk-reputation \
  -X POST \
  -H "x-api-key: hr_live_your_key"
 \
  -H "Content-Type: application/json" \
  -d '{
  "targets": ["stripe.com", "example.org"]
}'

GET/api/v1/bulk-reputation/:id

Fetch the job with per-target results once processing completes.

Path parameters

idstringrequired

The job id returned by POST /bulk-reputation.

Response fields

idstring

The job id.

statusstring

Poll until COMPLETED (or FAILED).

totalCountinteger

Total targets in the job.

completedCountinteger

Targets scored so far.

itemsarray

Per-target results (see fields below).

items[].targetstring

The email or domain scored.

items[].statusstring

COMPLETED or FAILED for that target.

items[].overallScoreinteger | null

Overall reputation 0-100.

items[].gradestring | null

Excellent · Good · Fair · Poor.

items[].riskLevelstring | null

Low · Medium · High · Critical.

items[].reportobject | null

Full report for that target.

example response
{
  "id": "4102e918-…", "status": "COMPLETED", "totalCount": 2, "completedCount": 2,
  "items": [ { "target": "stripe.com", "status": "COMPLETED", "overallScore": 86, "grade": "Good", "riskLevel": "Low" } ]
}
request
curl https://api.hookroast.com/api/v1/bulk-reputation/JOB_ID \
  -X GET \
  -H "x-api-key: hr_live_…"
GEThttps://api.hookroast.com/api/v1/bulk-reputation/:id
Headersx-api-key: not set
Show as cURL
curl https://api.hookroast.com/api/v1/bulk-reputation/:id \
  -X GET \
  -H "x-api-key: hr_live_your_key"

Real-time verify

Verify a single email address synchronously: one request, one VALID/INVALID answer. Built for signup forms and lead capture, so you can block disposable and undeliverable addresses before they enter your product. Costs 1 credit per call.

POST/api/v1/verify

Also available as GET /api/v1/verify?email=jane@acme.io for easy wiring into form validators. Responses typically return in 1-3 seconds (the SMTP probe dominates); set a client timeout of at least 10 seconds.

Body parameters

emailstringrequired

The email address to verify.

Response fields

emailstring

The normalized email address.

statusstring

VALID or INVALID.

reasonstring | null

invalid_format · disposable_domain · domain_not_found · mailbox_not_found (null when valid).

example response
{ "email": "jane@acme.io", "status": "VALID", "reason": null }
request
curl https://api.hookroast.com/api/v1/verify \
  -X POST \
  -H "x-api-key: hr_live_…" \
  -H "Content-Type: application/json" \
  -d '{"email":"jane@acme.io"}'
POSThttps://api.hookroast.com/api/v1/verify
Headersx-api-key: not setcontent-type: application/json
Show as cURL
curl https://api.hookroast.com/api/v1/verify \
  -X POST \
  -H "x-api-key: hr_live_your_key"
 \
  -H "Content-Type: application/json" \
  -d '{
  "email": "jane@acme.io"
}'

Email validation

Validate a list of email addresses for format, domain deliverability (MX), disposable providers, and, where reachable, mailbox existence over SMTP. Runs asynchronously; poll the GET endpoint for results. Costs 1 credit per email.

POST/api/v1/email-validation

Submit a batch of emails. Returns a job id to poll.

Body parameters

emailsstring[]required

Email addresses to validate. 1-5,000 entries.

Response fields

idstring

Job id. Use it to poll the GET endpoint.

statusstring

PENDING · PROCESSING · COMPLETED · FAILED.

totalCountinteger

Number of emails submitted.

example response
{ "id": "9c1e…", "status": "PENDING", "totalCount": 2 }
request
curl https://api.hookroast.com/api/v1/email-validation \
  -X POST \
  -H "x-api-key: hr_live_…" \
  -H "Content-Type: application/json" \
  -d '{"emails":["jane@acme.io","ghost@acme.io"]}'
POSThttps://api.hookroast.com/api/v1/email-validation
Headersx-api-key: not setcontent-type: application/json
Show as cURL
curl https://api.hookroast.com/api/v1/email-validation \
  -X POST \
  -H "x-api-key: hr_live_your_key"
 \
  -H "Content-Type: application/json" \
  -d '{
  "emails": ["jane@acme.io", "ghost@acme.io"]
}'

GET/api/v1/email-validation/:id

Fetch the job with per-email results once validation completes.

Path parameters

idstringrequired

The job id returned by POST /email-validation.

Response fields

idstring

The job id.

statusstring

Poll until COMPLETED (or FAILED).

totalCountinteger

Total emails in the job.

validCountinteger

Emails found valid.

invalidCountinteger

Emails found invalid.

resultsarray

Per-email outcomes (see fields below).

results[].emailstring

The normalized email address.

results[].statusstring

VALID or INVALID.

results[].reasonstring | null

invalid_format · disposable_domain · domain_not_found · mailbox_not_found (null when valid).

example response
{
  "id": "9c1e…", "status": "COMPLETED", "totalCount": 2, "validCount": 1, "invalidCount": 1,
  "results": [
    { "email": "jane@acme.io", "status": "VALID", "reason": null },
    { "email": "ghost@acme.io", "status": "INVALID", "reason": "mailbox_not_found" }
  ]
}
request
curl https://api.hookroast.com/api/v1/email-validation/JOB_ID \
  -X GET \
  -H "x-api-key: hr_live_…"
GEThttps://api.hookroast.com/api/v1/email-validation/:id
Headersx-api-key: not set
Show as cURL
curl https://api.hookroast.com/api/v1/email-validation/:id \
  -X GET \
  -H "x-api-key: hr_live_your_key"

Webhooks

Register webhook URLs on the Developers page to be notified when scans finish, instead of polling. Events: reputation.completed, bulk_reputation.completed. We POST:

POST body to your URL
{
  "event": "reputation.completed",
  "data": { "scanId": "b5f7c8ac-…" },
  "timestamp": "2026-06-29T12:00:00.000Z"
}

Each delivery is signed: x-hookroast-signature is the hex HMAC-SHA256 of the raw request body using the signing secret shown when you created the webhook. Verify it before trusting the payload:

node verification
import { createHmac, timingSafeEqual } from "crypto";

function verify(rawBody, signature, secret) {
  const expected = createHmac("sha256", secret).update(rawBody).digest("hex");
  return expected.length === signature.length &&
    timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}