Skip to content

Verify page

Fromenance is a communication provenance platform, and the verify page is the second way a customer can ask “did you send this?”: they paste the message, upload the .eml, upload a screenshot, or type the reference code on a page on your domain and the verdict renders on the page. It needs no mailbox, no reply identity, and no account.

By the end you will have a site key bound to your page’s origin, the widget on yourdomain.com/verify in your branding, and a verdict rendering on the page.

The page is yours: northfieldbank.example/verify or any URL on an origin you allow. Fromenance serves only the script and an optional iframe document from cdn.fromenance.com; there is no hosted verify page on fromenance.com, and the customer never sees the Fromenance name. The widget posts to api.fromenance.com/v1/public/submit with your site key and renders the response in your branding.

Admin app: Verify page, New site key, name it, and add the allowed origins. Or:

Terminal window
curl -X POST https://api.fromenance.com/v1/site-keys \
-H "Authorization: Bearer fr_live_..." \
-H "Content-Type: application/json" \
-d '{"name":"Public verify page","allowed_origins":["https://northfieldbank.example","https://www.northfieldbank.example"],"normal_rate_per_minute":60}'
Field Notes
public_key sk_pub_.... Public by design; it is bound to the origins below, so it is useless elsewhere
allowed_origins Up to 20 full origins (https://host). Requests whose Origin is not in the list are rejected
normal_rate_per_minute 5 to 6,000, default 60. Above this rate the key requires a Turnstile token (see below)
turnstile_required true requires Turnstile on every submission
theme Free form key value pairs used by the admin app preview

The response includes embed.script and embed.iframe, ready to paste, and the admin app shows a live preview of the widget with your name, logo, and accent colour from Settings, Branding.

Script tag (recommended)

<div id="fromenance-verify"></div>
<script
src="https://cdn.fromenance.com/verify.js"
data-site-key="sk_pub_..."
data-target="#fromenance-verify"
data-institution="Northfield Bank"
data-theme="auto"
async
></script>

Attributes:

Attribute Notes
data-site-key Required
data-target CSS selector of the container; a div is inserted before the script when omitted
data-institution The name shown in “Did this message come from Northfield Bank?”
data-theme light, dark, or auto (follows the visitor’s system setting)
data-accent Button and link colour, for example #0f4c81. The verdict card also picks up the accent set in Settings, Branding
data-turnstile Your Cloudflare Turnstile site key, needed when the key is or can become Turnstile gated
data-api Only for staging; defaults to https://api.fromenance.com

The script also exposes window.Fromenance.mount({ siteKey, target, institutionName, theme, accent, turnstileSiteKey, onVerdict }) for single page applications, and window.Fromenance.version.

Iframe

<iframe
src="https://cdn.fromenance.com/embed.html?key=sk_pub_...&name=Northfield%20Bank&theme=auto"
title="Verify a message"
style="width:100%;min-height:520px;border:0"
></iframe>

Query parameters mirror the data attributes: key, name, theme, accent, turnstile, api. The iframe posts two messages to the parent window: { type: "fromenance:height", height } whenever its content height changes, so you can resize it, and { type: "fromenance:verdict", verdict } after each answer. The allowed origin check applies to the page that embeds the iframe, so add your site’s origin to the site key, not cdn.fromenance.com.

A message textarea, an optional reference code field, an optional field for the address that received the message (recommended, since the recipient is half of the strongest match), and file inputs for an .eml or a screenshot (PNG, JPEG, WebP, up to 6 MB). Text and .eml answer in under three seconds; screenshots show “Reading the screenshot” while OCR runs and answer within about fifteen seconds.

The verdict card carries your logo, the outcome label (Verified, Not verified, Known fraud), the locked verdict text, a next step that includes your fraud contact, and a link to your support URL. Outcomes use the same three colours as the admin app and nothing else in the widget uses them.

Pass onVerdict to mount() or listen for the iframe message to record analytics or route the customer:

window.Fromenance.mount({
siteKey: "sk_pub_...",
target: document.querySelector("#fromenance-verify"),
institutionName: "Northfield Bank",
onVerdict: (v) => {
analytics.track("verify_result", { outcome: v.outcome, rule: v.rule, submission: v.submission_id });
if (v.outcome === "known_fraud") location.assign("/security/report-fraud");
},
});

The verdict object is the same one the verify page API returns.

  • 60 submissions per minute per IP address and 600 per minute per site key. Over the limit the API answers 429 with Retry-After and the widget shows “Too many checks right now”.
  • When a site key exceeds its normal_rate_per_minute, or has turnstile_required set, the API answers 428 turnstile-required. The widget then loads Cloudflare Turnstile with the site key from data-turnstile, and resubmits with the token once the challenge passes. Without data-turnstile the customer sees “Please complete the security check” and cannot continue, so set it if your page can see bursts.

The address the customer types is hashed with your tenant secret to compare against registrations, stored encrypted only so the submission can be linked to a later forward, and purged 30 days after the verdict. Uploaded .eml files and screenshots are stored encrypted under your tenant prefix and follow your retention setting. The widget never sets cookies.