v1 API

API Reference

The MFA Intelligence API provides programmatic access to our made-for-advertising domain intelligence. Integrate MFA detection into your ad-tech stack, brand safety tools, or custom workflows.

Base URLhttps://mfa.redvolcano.uk/api/v1

Authentication

All API requests require an API key. Create and manage keys from the API Keys page in your dashboard.

Never share your API key publicly. If compromised, revoke it immediately from the API Keys page and create a new one.

  • Precedence: if both are present, the Authorization header wins — the ?api_key= query param is ignored even if the header is malformed.
  • Case: the Bearer scheme is matched case-insensitively (bearer, BEARER, etc. all work).
  • Caching: all responses carry Cache-Control: private, no-store. Safe to use with ?api_key= since intermediaries will not retain the body.
  • Duplicate params: repeating a query key (e.g. ?tier=red&tier=amber) returns 400 — we do not pick one silently.
  • Methods: only the methods documented for each endpoint are accepted. Other verbs return 405 with an Allow header.
httpBearer Token (recommended)
GET /api/v1/feed HTTP/1.1
Host: mfa.redvolcano.uk
Authorization: Bearer mfa_your_api_key_here
httpQuery Parameter
GET /api/v1/feed?api_key=mfa_your_api_key_here

Rate Limits

Rate limit headers are returned on every response from a valid API key (including 404 and 429). 401 responses omit them because there is no authenticated key to identify a bucket.

X-RateLimit-LimitMax requests per hour
X-RateLimit-RemainingRemaining in current window
X-RateLimit-ResetUnix timestamp of window reset
httpResponse Headers
HTTP/1.1 200 OK
Content-Type: application/json
X-RateLimit-Limit: 100000
X-RateLimit-Remaining: 99847
X-RateLimit-Reset: 1712700000

Endpoints

GET/api/v1/feed

Returns a paginated list of MFA-flagged domains with scores, tiers, and detection signals. Invalid query values return 400 rather than being silently clamped or ignored — the response body lists each field that failed validation.

Parameters

pageinteger

Page number, min 1 (default: 1)

limitinteger

Results per page, 1–100 (default: 50). Values outside this range return 400.

tierstring

Filter by tier: red, amber, yellow

searchstring

Substring match on domain, max 100 chars

sortstring

Sort by: score, domain, created_at (default: score)

orderstring

Sort order: asc, desc (default: desc)

curlRequest
curl "https://mfa.redvolcano.uk/api/v1/feed?tier=red&limit=10" \
  -H "Authorization: Bearer mfa_your_key_here"
jsonResponse
{
  "domains": [
    {
      "id": 1,
      "domain": "example-mfa.com",
      "score": 87,
      "tier": "red",
      "created_at": "2026-03-15T10:30:00Z",
      "breakdown": [
        { "key": "ads_txt", "label": "Monetization",
          "score": 22, "max": 25 }
      ],
      "signals": [
        { "key": "excessive_ads", "label": "Excessive Ads" }
      ]
    }
  ],
  "total": 1523,
  "page": 1,
  "totalPages": 31,
  "isLimited": false,
  "totalAvailable": 1523
}
GET/api/v1/stats

Returns aggregate statistics about the MFA domain feed — total count and breakdown by tier.

curlRequest
curl "https://mfa.redvolcano.uk/api/v1/stats" \
  -H "Authorization: Bearer mfa_your_key_here"
jsonResponse
{
  "total": 10103,
  "red": 69,
  "amber": 1913,
  "yellow": 8121
}
GET/api/v1/domain/:domain

Look up a specific domain. Returns the full detection record if found, or 404 if the domain is not in the feed.

Parameters

domainstringrequired

The domain to look up (path parameter)

curlRequest
curl "https://mfa.redvolcano.uk/api/v1/domain/example-mfa.com" \
  -H "Authorization: Bearer mfa_your_key_here"
jsonResponse
{
  "domain": "example-mfa.com",
  "score": 87,
  "tier": "red",
  "created_at": "2026-03-15T10:30:00Z",
  "breakdown": [
    { "key": "ads_txt", "label": "Monetization",
      "score": 22, "max": 25 },
    { "key": "content", "label": "Content",
      "score": 18, "max": 20 }
  ],
  "signals": [
    { "key": "excessive_ads", "label": "Excessive Ads" },
    { "key": "thin_content", "label": "Thin Content" }
  ]
}
POST/api/v1/domain-checks

Submit one domain, or a bulk list of up to 1,000, for an MFA assessment and ongoing monitoring. Fresh results (under 24 hours) return immediately; otherwise poll the supplied result URL. New crawls are limited to 1,000 per organisation per UTC day. Cached results and requests that join an active scan do not use crawl quota. Requested scans assess MFA signals only—clone analysis is not run.

Parameters

domainstring

A single hostname or HTTP/HTTPS URL.

domainsstring[]

Bulk alternative to domain; 1–1,000 values.

curlRequest
curl -X POST "https://mfa.redvolcano.uk/api/v1/domain-checks" \
  -H "Authorization: Bearer mfa_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"domain":"example.com"}'
jsonResponse
HTTP/1.1 202 Accepted
X-Scan-Limit: 1000
X-Scan-Remaining: 999

{
  "id": "2fac35c7-6b35-4429-b42c-a2bd0f06f149",
  "status": "queued",
  "total": 1,
  "completed": 0,
  "items": [{ "domain": "example.com", "status": "queued" }],
  "resultUrl": "/api/v1/domain-checks/2fac35c7-6b35-4429-b42c-a2bd0f06f149"
}
GET/api/v1/domain-checks/:id

Poll an asynchronous request. A completed assessment includes the usual score, tier, breakdown, signals and verdict. If no usable ads.txt is available, the result is inconclusive and does not overwrite the last valid assessment.

Parameters

iduuidrequired

Request ID returned by submission.

pageinteger

Item page for bulk requests (default: 1).

limitinteger

Items per page, 1–100 (default: 100).

curlRequest
curl "https://mfa.redvolcano.uk/api/v1/domain-checks/2fac35c7-6b35-4429-b42c-a2bd0f06f149" \
  -H "Authorization: Bearer mfa_your_key_here"
jsonResponse
{
  "id": "2fac35c7-6b35-4429-b42c-a2bd0f06f149",
  "status": "completed",
  "total": 1,
  "completed": 1,
  "items": [{
    "domain": "example.com",
    "status": "completed",
    "nextScanAt": "2026-08-23T14:00:00Z",
    "result": {
      "verdict": "mfa_risk_detected",
      "score": 54,
      "tier": "amber",
      "breakdown": [],
      "signals": []
    }
  }]
}
DELETE/api/v1/monitored-domains/:domain

Stop the day 5/15/30/60/90 and every-30-days monitoring schedule for your organisation. Monitoring continues if another organisation still tracks the same domain. Use GET on the same path to inspect its schedule and current assessment.

Parameters

domainstringrequired

The monitored domain (path parameter).

curlRequest
curl -X DELETE "https://mfa.redvolcano.uk/api/v1/monitored-domains/example.com" \
  -H "Authorization: Bearer mfa_your_key_here"
jsonResponse
{ "success": true }
GET/api/v1/rings

Returns MFA ring data — clusters of domains sharing identical ads.txt configurations, indicating coordinated MFA networks. Only hashes with 5 or more domains are returned, sorted by size descending.

curlRequest
curl "https://mfa.redvolcano.uk/api/v1/rings" \
  -H "Authorization: Bearer mfa_your_key_here"
jsonResponse
{
  "rings": [
    {
      "hash": "a1b2c3d4e5f6",
      "size": 12,
      "domains": [
        {
          "domain": "site-a.com",
          "tier": "red",
          "score": 87,
          "created_at": "2026-03-27T20:39:01Z"
        }
      ],
      "tiers": { "red": 4, "amber": 6, "yellow": 2 }
    }
  ],
  "totalRings": 82,
  "totalDomainsInRings": 1532
}
GET/api/v1/feed/export

Export up to 50,000 matching domains as JSON (default) or CSV. Subject to a separate daily export quota.

Parameters

formatstring

Export format: json or csv (default: json)

tierstring

Filter by tier: red, amber, yellow

curlRequest
# Default — JSON array of domain records
curl "https://mfa.redvolcano.uk/api/v1/feed/export?tier=red" \
  -H "Authorization: Bearer mfa_your_key_here"

# CSV download
curl "https://mfa.redvolcano.uk/api/v1/feed/export?format=csv" \
  -H "Authorization: Bearer mfa_your_key_here" \
  -o mfa-intelligence.csv
jsonResponse
[
  {
    "id": 1,
    "domain": "example-mfa.com",
    "score": 87,
    "tier": "red",
    "created_at": "2026-03-15T10:30:00Z",
    "breakdown": [
      { "key": "ads_txt", "label": "Monetization",
        "score": 22, "max": 25 }
    ],
    "signals": [
      { "key": "excessive_ads", "label": "Excessive Ads" }
    ]
  }
]

CSV format (when ?format=csv)

Signals are joined with ; and wrapped in double quotes. The response carries Content-Type: text/csv and a filename disposition header so browsers download it.

csvCSV response body
domain,score,tier,detected_at,signals
example-mfa.com,87,red,2026-03-15T10:30:00Z,"Excessive Ads;Thin Content"
another-site.com,72,amber,2026-03-16T08:14:22Z,"Low Content Ratio"

Code Examples

pythonPython
import requests

API_KEY = "mfa_your_key_here"
BASE = "https://mfa.redvolcano.uk/api/v1"
headers = {"Authorization": f"Bearer {API_KEY}"}

# Get red-tier domains
resp = requests.get(f"{BASE}/feed", headers=headers,
                    params={"tier": "red", "limit": 100})
data = resp.json()

for d in data["domains"]:
    print(f"{d['domain']} — Score: {d['score']} ({d['tier']})")

# Check a specific domain
resp = requests.get(f"{BASE}/domain/example.com", headers=headers)
if resp.status_code == 200:
    print("Found:", resp.json())
elif resp.status_code == 404:
    print("Not in MFA Intelligence")
javascriptJavaScript / Node.js
const API_KEY = "mfa_your_key_here";
const BASE = "https://mfa.redvolcano.uk/api/v1";
const headers = { Authorization: `Bearer ${API_KEY}` };

// Get feed with filters
const res = await fetch(`${BASE}/feed?tier=red&limit=50`, { headers });
const data = await res.json();
console.log(`Found ${data.total} domains`);

// Export full feed as JSON
const exportRes = await fetch(`${BASE}/feed/export`, { headers });
const allDomains = await exportRes.json();

Error Codes

CodeMeaningDescription
400Bad RequestA query parameter failed validation. Body includes a details array with the failing field(s).
401UnauthorizedMissing or invalid API key
403ForbiddenAPI access not available for your account
404Not FoundThe requested domain was not found in the feed
405Method Not AllowedThe method is unsupported for that endpoint. The response includes an Allow header.
429Too Many RequestsRate limit exceeded — check X-RateLimit-Reset header
500Server ErrorInternal error. Please try again later

All errors return a JSON body with an error field.

MFA Intelligence API v1 — Powered by Red Volcano