fray

Bring your ad blocker
into the fray.

Send reports of scam and fraud ads with your users' informed and explicit consent. Fray investigates the accounts behind them and files evidence with the platforms.

You get a free feed of confirmed scams to help protect your users.

We've been running Fray in our own ad blocker since early 2025.

What your reports can uncover

Scammers can recognise automated crawlers and show them a harmless page. They can also target ads at a particular country or audience. Our own checks can miss the scam or fraud ad that appears in a person's browser.

Your client can report that ad even when it blocks it. We check the advertiser against the brand's registered accounts and investigate the evidence. An unlisted account alone is not proof of a scam or fraud. The platform decides whether to remove an ad or account.

What you get

  • A feed of confirmed scams. Signed, versioned JSON, pushed when a case is confirmed and filed, before it reaches public blocklists. It uses the same format family as the public watchlist.
  • Investigation and reporting handled by us. We verify reports, collect evidence, file it with platforms and deal with disputes.
  • Credit for your contribution. If we publish a case you helped identify, we name your organization if you want us to.

Participation and the feed are free for contributors. Marcode funds Fray through its paid fraud detection work.

What you need to build

You run a token issuer on your server and add reporting to your browser extension. The protocol, relay and token issuers are open source. The collection SDK is being prepared for public release.

  1. Runs on your server Run a token issuer using the TypeScript or Python reference implementation. This provides your users with batches of blind-signed reporting tokens, so token use cannot be linked to the account that requested them.
  2. Runs in your browser extension Request a fixed batch of tokens once a day, regardless of browsing activity. This keeps token requests independent of when a user sees an ad.
  3. Runs in your browser extension For a watched domain, retrieve the advertiser details in the browser and compare its account with the published authorized accounts. Only an account absent from a closed list is eligible for a report. In the optional delegated mode, Fray performs this lookup and check instead.

The collection SDK is not available to download yet. Contact us about integration. Reporting requires authenticated gateway keys, informed and explicit user opt-in, and a fixed token schedule.

The Fray registry publishes watched domains and their authorized advertiser accounts. Each partner’s token issuer publishes its configuration at /.well-known/fray.json and its public signing keys at /.well-known/jwks.json.

The protocol, envelope schema and server reference implementations are published at github.com/jointhefray/fray under the MIT and Apache-2.0 licenses. The collection SDK is not included in this release.

Partners must explain what ad evidence is collected, how it is used and who receives it, and enable participation only after the user actively opts in. Users must be able to withdraw their consent and stop future reporting.

How reports protect privacy

No user data is ever collected.

Report schema

We call each ad report a sighting. Before sending it, the client checks the advertiser against the watchlist, removes search text and account identifiers, and attaches a single-use blind-signed token. By default the report carries the advertiser details and none of Google’s lookup values. It can still be linked: the click URL and ad HTML keep the platform’s click parameters, such as gclid, with a precise click timestamp the platform can match to its own records. A partner can opt in to sending the user’s search query, and must disclose that to its users first. A partner can also choose delegated mode, and must disclose that too: the client skips its own lookup and sends Google’s page lookup token and per-ad batch codes instead, for Fray to resolve. Those values are tied to the user’s Google session and can link reports to a Google page or request, and ads are sent before their account is checked. Fray's collector verifies each report's token, stores accepted reports and queues them for investigation.

Report format and data flow

The path of one sighting

Your user's browser

  1. An ad for a brand on the public watchlist appears in the browser. By default, the browser looks up the advertiser and checks its account locally. Authorized accounts and inconclusive checks do not generate reports.
  2. The extension attaches a blind-signed reporting token (RFC 9474 blind RSA) from its daily pool. One token per sighting, single use, unlinkable to any account or to any other token.

Example report

{
  "v": 3,
  "kind": "sighting",
  "watchlist_version": 12,
  "platform": "google.com",
  "surface": "search",
  "observed_hour": "2026-10-14T14:00:00Z",
  "ads": [
    {
      "brand": "example-fashion.com",
      "observed_domain": "example-fashion.com",
      "creative": {
        "title": "Example Fashion Clearance — 90% Off Everything",
        "body": "Final closing down sale. All stock must go today.",
        "display_url": "example-fashion.com/sale",
        "click_url": "https://www.googleadservices.com/pagead/aclk?sa=L&ai=Cg4x…opaque…&gclid=EAIa…opaque…&adurl=https%3A%2F%2Fexamplefashion-outlet.shop%2Fsale"
      },
      "advertiser": {
        "id": "AR55554444111122223333",
        "name": "Example Outlet Trading Ltd",
        "country": "United Kingdom",
        "targeting": [[17, 1], [10, null]]
      },
      "ad_html": "<div data-text-ad=\"1\"><a href=\"https://www.googleadservices.com/pagead/aclk?sa=L&amp;ai=Cg4x…opaque…&amp;gclid=EAIa…opaque…&amp;adurl=https%3A%2F%2Fexamplefashion-outlet.shop%2Fsale\"><span>Example Fashion Clearance — 90% Off Everything</span></a><span>example-fashion.com/sale</span></div>"
    }
  ],
  "token": {
    "issuer": "issuer.partner.example",
    "kid": "ep-2026-10",
    "meta": 1,
    "msg": "qL7…base64…",
    "sig": "hJ2…base64…"
  }
}

Fictional default-mode sighting. It carries no Google lookup values: the client looked up the advertiser itself, and advertiser holds the result. Its targeting holds the platform’s “why this ad” reason codes as bare numbers, not the values behind them. It can still be linked: click_url and ad_html keep the platform’s click parameters, and gclid carries a precise click timestamp the platform can match to its own records. observed_hour is rounded down to the hour, which does not hide that timestamp. brand identifies the watchlist match; ads holds the qualifying ads from one results page; token is a single-use blind signature, and meta is the issuer-assigned value, one of four, that selects its signing key. Search text and dynamically inserted keywords are stripped from the creative, click_url and ad_html, preserving the remaining evidence, unless the partner sends the search query as keyword, in which case they are left as shown. In delegated mode, a partner choice that must be disclosed, the envelope instead carries the page’s lookup.atParameter and a batch_code per ad, and no advertiser. The click links are shortened for display; see the click-URL rules. The token fields are abbreviated too, and that is the only reason this sample won’t validate against the report schema as-is. Full field definitions.

Excluded from reports

  • what the user searched for, unless the partner has opted in and told its users
  • any other page they visited
  • name, email, or account
  • a persistent extension identifier

The relay receives the client connection and encrypted bytes. The inbound gateway receives the relay’s connection and decrypts the report. The relay passes on only the client’s country and device type, never its IP address or browser details. Fray currently controls both services; independent operation remains a deployment requirement for the full trust separation. Relay operation and partner controls.

The relay

  1. The encrypted report reaches the OHTTP relay. The relay forwards ciphertext to the fixed inbound gateway without the client’s cookies, authorization or identifying HTTP headers.

The inbound gateway decrypts the report. The relay has no decryption key.

Fray

  1. The inbound gateway passes the report to Fray's collector.
  2. The collector verifies and spends the token, then queues accepted evidence for investigation. Analysts can review a report from its first sighting; repeat sightings raise its priority.
Privacy controls and technical references.

Privacy controls

  • No extension account, cookie or persistent client ID in the report, and by default none of Google’s lookup values. Reports remain correlatable: the platform’s click parameters in the click URL and ad HTML can be matched to its own records. Delegated mode, a partner choice that must be disclosed, also sends Google’s session-bound lookup values. spec/envelope.md · spec/protocol.md §6.3
  • Blind-signed, rate-limited reporting tokens: RFC 9474 RSABSSA, partner-run issuers, published epoch keys. spec/protocol.md · TypeScript issuer · Python issuer
  • Encrypted transport separates the client connection at the relay from report contents at the gateway. spec/relay.md
  • Reports require a watched domain and, by default, a locally confirmed mismatch against its authorized advertiser accounts; in delegated mode Fray confirms the mismatch before using the report. the current watchlist
  • Search text and dynamically inserted keywords are stripped from the ad creative and URL while the remaining evidence is retained. Display URLs lose their query strings; click URLs retain unrelated parameters: click-URL handling. A partner may opt in to sending the search query itself, and must disclose it; the creative, click URL and ad HTML are then sent without keyword redaction. Client sanitization requirements
  • The relay derives the client’s country from its connection and a coarse device type, such as Android mobile or Windows desktop, from its browser. It passes on only those two values. spec/relay.md
  • The observation time is rounded to the hour. That does not hide the precise click timestamp in the gclid kept in the click URL and ad HTML, or, in delegated mode, the one in Google’s lookup token. spec/envelope.md
  • Reports are sanitized in the client so an analyst can review the first sighting. Cloaking and targeting can prevent us from seeing the ad on our own machines. spec/protocol.md §6.1
  • The collector flags a candidate at three distinct-token sightings (K=3). Tokens do not prove three independent people. They do not establish fraud. We try to reproduce every candidate on our own machines and record whether we succeed. Filings identify their evidence source. We publish a case only after platform enforcement action. spec/protocol.md §6 and §6.1 (the publication gate)

Code and specifications

Retention and deletion · Data use · Security

Note about the ad's own click URL: The client strips the user's search query and dynamically inserted keywords from the ad creative and URL before submission. Matching text is redacted in place, preserving the rest of the creative and the URL's unrelated paths and parameters. A keyword match does not cause the whole field to be dropped.

For click URLs, the client checks decoded text, including encoded parameters, for the full query and its terms of length ≥ 3 at word boundaries. The remaining platform-issued identifiers can help identify the ad in a filing and can be correlated with the platform's own records. A redacted URL is evidence and may no longer function as a click link; the client never follows it. Reports carry no Google lookup values by default, but the ad HTML keeps the same click links, and their gclid carries a precise click timestamp that the hour-rounded observation time does not hide. Delegated mode, a partner choice that must be disclosed, also sends Google’s lookup values, which can link reports to a Google page or request. Malformed, unsafe or oversized URLs remain excluded. Display URLs lose query strings and fragments. Full text: sanitization rules in fray-oss/spec/envelope.md.

Your controls as a partner

  • The watchlist is published and versioned; clients only ever report against a list anyone can read.
  • Per-partner issuer keys mean your stream is attributable to you and no one else.
  • You control token issuance and can switch off reporting in your client.
  • You can leave at any time. On revocation, your stream's raw history is deleted. Aggregates and published case material remain. Retention and deletion.
  • The relay: you can run your own from the reference relay implementation, and the client protocol is identical either way, so switching operators is a relay-URL config change on the client and nothing more. The target architecture is an independently operated relay, run by a partner or a neutral third party. Fray currently operates it, which means the IP split is a policy control (separate process, no-log discipline, auditable config), and not yet an architectural guarantee.

FAQ

Can you link reports to someone's browsing history?

Reports exclude browsing URLs and extension account identifiers. They exclude search text unless the partner has opted in to sending the search query and disclosed it to its users. By default they exclude Google’s lookup values too; a partner that uses delegated mode sends them and must disclose it, and those values can connect reports to a Google page or request. OHTTP separates the client connection from the report receiver; it does not remove correlation through what the report itself carries.

Reports keep the ad’s click links, in the click URL and ad HTML. The ad platform can match their parameters, including the precise click timestamp in gclid, to its own records. Click-URL handling.

Who is the data shared with?

Brands receive evidence of scam and fraud ads impersonating them: the ad, its destination and the advertiser account behind it. They receive no competitive intelligence, category or market analysis, or other commercially sensitive information. No user data is ever collected. Click-URL handling.

Ad networks receive evidence from our own machines where we can reproduce the ad, or sanitized reports where cloaking or targeting prevents that. Law enforcement receives case material where applicable. Contributing partners receive the confirmed-scam feed. The ad data is used only to identify scams, malvertising, and fraud. Fray keeps raw reports for up to 90 days. Raw reports are never sold or licensed.

Fray and Marcode's commercial business share the same analysts and systems. There is no ring-fence between them.

What can our engineers review?
The issuer keys, sanitization requirements, report schema, watchlist, relay and token issuer implementations are public. The collection SDK is pending release. Code and specifications.

Join the fray

[email protected]

Tell us which ad blocker or privacy tool you build and which browsers or platforms it supports. We can discuss how reporting would fit your product. Technical questions about the code or protocol are welcome at the same address.