Email Threat Intelligence API
Scan any email in under 50ms. Built for carriers, telecoms, and security platforms that need deterministic, low-latency threat scoring at scale.
Quick Start
Three steps to your first scan result.
Request an API key
Contact us at api@glance-co.com or use the form at the bottom of this page. Keys are issued within one business day. Each key is scoped to your organisation and carries a configurable daily quota.
Send a scan request
POST the email metadata to /api/v1/scan with your API key in the X-API-Key header. The minimum required field is from — all other fields increase scoring accuracy.
Act on the verdict
The response returns a threatScore (0–100), a verdict (SAFE, SUSPICIOUS, DANGEROUS), and the specific signals that contributed to the score. Use these to route, quarantine, or block email in your pipeline.
Example request (cURL)
curl -X POST https://api.glance-co.com/api/v1/scan \
-H "Content-Type: application/json" \
-H "X-API-Key: glance_live_xxxxxxxxxxxxxxxx" \
-d '{
"from": "urgent-billing@paypa1-secure.com",
"fromName": "PayPal Security",
"subject": "Your account has been suspended — action required",
"headers": {
"Received": "from mx.paypa1-secure.com (203.0.113.42)",
"Authentication-Results": "spf=fail; dkim=none; dmarc=fail"
}
}'Example response
{
"threatScore": 87,
"verdict": "DANGEROUS",
"signals": [
"spf_fail",
"dmarc_fail",
"homoglyph_domain",
"urgency_keywords",
"domain_age_new"
],
"confidence": 0.9312,
"latencyMs": 34,
"requestId": "f47ac10b-58cc-4372-a567-0e02b2c3d479"
}Authentication
All API requests require an API key passed as an HTTP header. Keys are prefixed with glance_live_ for production and glance_test_ for the sandbox environment.
Header
X-API-Key: glance_live_xxxxxxxxxxxxxxxx- Keys are issued per organisation and can be rotated at any time from your account dashboard.
- Test keys (
glance_test_) return deterministic mock responses and do not count toward your quota. - Never expose your production key in client-side code. All requests should originate from your backend.
Endpoint Reference
/api/v1/scanBase URL: https://api.glance-co.comSynchronously scans an email through Tiers 1–3 of the detection pipeline: deterministic allow/blocklist and domain checks (Tier 1), heuristic pattern analysis including SPF/DKIM/DMARC validation, homoglyph detection, and keyword scoring (Tier 2), and cross-user sender reputation lookup (Tier 3). AI analysis (Tier 4) is not included in the synchronous scan endpoint — it is available via an async callback model on enterprise plans.
Request Schema
Send a JSON body with Content-Type: application/json. Only from is required — every additional field improves detection accuracy.
| Field | Type | Required | Description |
|---|---|---|---|
| from | string | required | Sender email address. Used for domain analysis, reputation lookup, and authentication checks. |
| fromName | string | optional | Display name of the sender. Used for display-name spoofing and brand impersonation detection. |
| subject | string | optional | Email subject line. Used for urgency keyword detection and contextual scoring. |
| body | string | optional | Plain-text or HTML email body. Used for link extraction, keyword analysis, and obfuscation detection. |
| headers | object | optional | Raw SMTP headers as key-value pairs. Enables SPF, DKIM, DMARC validation and received-chain analysis. Recommended for highest accuracy. |
Headers object
Pass raw SMTP headers as a flat key-value object. The most impactful headers for accuracy are Authentication-Results, Received, DKIM-Signature, and Return-Path.
"headers": {
"Authentication-Results": "spf=fail smtp.mailfrom=example.com; dkim=none; dmarc=fail",
"Received": "from mail.suspicious-host.net (198.51.100.7)",
"Return-Path": "<bounce@suspicious-host.net>",
"DKIM-Signature": "v=1; a=rsa-sha256; d=example.com; s=default; ..."
}Response Schema
A successful scan returns HTTP 200 with the following JSON body.
| Field | Type | Required | Description |
|---|---|---|---|
| threatScore | number | required | Integer from 0 to 100. Higher = more dangerous. 0 = no threat signals detected. |
| verdict | string | required | One of SAFE, SUSPICIOUS, or DANGEROUS. Derived from threatScore. |
| signals | string[] | required | Array of signal identifiers that contributed to the score. Empty array if no signals triggered. |
| confidence | number | required | Float from 0.0 to 1.0 expressing the model's confidence in the verdict. |
| latencyMs | number | required | Server-side processing time in milliseconds. Does not include network round-trip. |
| requestId | string | required | UUID v4 for this scan request. Include in support tickets for debugging. |
Verdict Table
The verdict field is derived from the threatScore. Use it to make routing decisions without threshold arithmetic.
| Verdict | Score Range | Recommended Action |
|---|---|---|
| SAFE | 0 – 29 | Deliver normally. No threat signals detected. |
| SUSPICIOUS | 30 – 69 | Route to spam folder, flag for review, or trigger secondary verification. Inspect signals for context. |
| DANGEROUS | 70 – 100 | Quarantine or block. High confidence of phishing, spoofing, or malware delivery. |
Signal Reference
The signals array contains string identifiers for every detection rule that fired. Use these to build downstream logic — for example, treating homoglyph_domain as grounds for immediate block regardless of overall score.
| Signal | Severity | Description |
|---|---|---|
| spf_fail | HIGH | The sending IP is not authorised to send mail for the claimed domain per the SPF record. |
| dkim_fail | HIGH | DKIM signature is absent, invalid, or does not match the signing domain. |
| dmarc_fail | HIGH | Message fails DMARC policy alignment (SPF and DKIM both unaligned or failed). |
| homoglyph_domain | CRITICAL | Sender domain contains lookalike Unicode characters designed to impersonate a known brand (e.g. gοogle.com with a Cyrillic "o"). |
| urgency_keywords | MEDIUM | Subject or body contains high-pressure language patterns associated with social engineering (e.g. "act immediately", "account suspended"). |
| disposable_email | HIGH | Sender address is from a known disposable or temporary email provider. |
| domain_age_new | MEDIUM | Sender domain was registered within the last 30 days — a strong signal for purpose-built fraud infrastructure. |
| vt_malicious_url | CRITICAL | One or more links in the email were flagged as malicious by VirusTotal's aggregated 70+ engine scan. |
| ipqs_malicious_url | CRITICAL | One or more URLs received a high-risk or phishing verdict from IPQS (IPQualityScore). |
| alienvault_otx_listed | HIGH | Sender domain or IP is listed in an active AlienVault OTX threat intelligence pulse. |
| hibp_breach | LOW | Sender address appears in a known data breach via Have I Been Pwned — indicates credential exposure risk. |
Note: The signal set is continuously expanded as new threat patterns are identified. Your integration should handle unknown signal identifiers gracefully (e.g., by logging and treating them as generic risk indicators).
Rate Limits
1,000 scans/day
Default quota
Per API key, all plans
00:00 UTC daily
Reset schedule
Quota does not roll over
On request
Custom quotas
Enterprise and carrier plans
When the daily quota is reached, all subsequent requests return HTTP 429 until the quota resets. The response body includes a resetAt timestamp so your system can schedule retries precisely.
429 response body
{
"statusCode": 429,
"message": "Daily scan quota exceeded",
"resetAt": "2026-04-09T00:00:00.000Z"
}Carriers and security platforms requiring higher throughput can contact us to discuss custom SLA agreements with per-minute burst limits and dedicated infrastructure.
Error Reference
| Code | Name | Details |
|---|---|---|
| 400 | Bad Request | The `from` field is missing or malformed. Check the request body. |
| 401 | Unauthorized | The `X-API-Key` header is missing, expired, or invalid. |
| 429 | Quota Exceeded | Daily scan quota has been reached. Response includes a `resetAt` ISO-8601 timestamp. |
| 500 | Internal Error | An unexpected error occurred during scanning. Retry with exponential backoff. Contact support with the `requestId` if the issue persists. |
400 Bad Request — example
{
"statusCode": 400,
"message": "Validation failed",
"errors": [
{ "field": "from", "message": "from is required" }
]
}Code Examples
cURL
curl -X POST https://api.glance-co.com/api/v1/scan \
-H "Content-Type: application/json" \
-H "X-API-Key: glance_live_xxxxxxxxxxxxxxxx" \
-d '{
"from": "no-reply@paypa1-secure.net",
"fromName": "PayPal",
"subject": "Confirm your identity to restore access",
"headers": {
"Authentication-Results": "spf=fail; dkim=none; dmarc=fail"
}
}'Node.js (fetch)
const scanEmail = async ({ from, fromName, subject, headers }) => {
const response = await fetch('https://api.glance-co.com/api/v1/scan', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': process.env.GLANCE_API_KEY,
},
body: JSON.stringify({ from, fromName, subject, headers }),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`Glance scan failed: ${error.message}`);
}
return response.json();
// { threatScore, verdict, signals, confidence, latencyMs, requestId }
};
// Usage
const result = await scanEmail({
from: 'sender@example.com',
fromName: 'Example Sender',
subject: 'Invoice #1042',
headers: { 'Authentication-Results': 'spf=pass; dkim=pass; dmarc=pass' },
});
if (result.verdict === 'DANGEROUS') {
await quarantineMessage(messageId);
}Python (requests)
import os
import requests
GLANCE_API_KEY = os.environ["GLANCE_API_KEY"]
GLANCE_API_URL = "https://api.glance-co.com/api/v1/scan"
def scan_email(from_addr, from_name=None, subject=None, headers=None):
payload = {"from": from_addr}
if from_name:
payload["fromName"] = from_name
if subject:
payload["subject"] = subject
if headers:
payload["headers"] = headers
resp = requests.post(
GLANCE_API_URL,
json=payload,
headers={
"Content-Type": "application/json",
"X-API-Key": GLANCE_API_KEY,
},
timeout=5,
)
resp.raise_for_status()
return resp.json()
# Usage
result = scan_email(
from_addr="billing@paypa1-secure.com",
from_name="PayPal Billing",
subject="Your account has been limited",
headers={"Authentication-Results": "spf=fail; dkim=none; dmarc=fail"},
)
print(f"Verdict: {result['verdict']} Score: {result['threatScore']}")
print(f"Signals: {', '.join(result['signals'])}")
if result["verdict"] == "DANGEROUS":
quarantine_message(message_id)Request API Access
The Glance Threat Intelligence API is available to carriers, email security vendors, telecoms, and enterprise security teams. API keys are issued after a brief qualification conversation to ensure the integration is a good fit.
B2B / Enterprise API
Custom quotas, SLA agreements, dedicated infrastructure, and direct engineering support. Suitable for carriers and high-volume deployments.
Request API AccessConsumer Product
Protecting individual inboxes, families, and small teams from phishing, scams, and fraud. Includes the Circle of Trust gatekeeper model.
Create Free Account