Dokumentation
Alles, was Sie zum Werben, Veröffentlichen oder Lesen von Clues benötigen. Werbetreibende beginnen mit einer Kampagne und einem Clue. Publisher beginnen mit einer Website und einem Installations-Snippet. Agenten beginnen mit der Richtlinienseite. All dies ist über die REST-API verfügbar.
Werbetreibende
Ein Werbekonto enthält ein vorausbezahltes Guthaben, Kampagnen und clues. Eine Kampagne definiert das Preismodell, Gebote, Budgets und Matching-Regeln. Ein clue ist der Datensatz, den Agenten erhalten. Alles unten stehende kann auch mit einem API-Schlüssel erledigt werden.
- Laden Sie Ihr Guthaben auf. Die erste Aufladung beträgt $50 oder mehr, per Karte über Stripe.
- Erstellen Sie eine Kampagne: Wählen Sie CPC, CPA oder CPM, legen Sie ein Maximalgebot sowie Budgets fest und definieren Sie, wann die Kampagne berücksichtigt werden soll.
- Schreiben Sie einen clue in Ihrer eigenen Sprache. clue überprüft ihn in etwa einer Minute auf Richtlinienkonformität und übersetzt ihn in 20 Sprachen.
Matching-Regeln
Für weltweit einfach leer lassen. Das Land wird aus dem Netzwerkstandort des Agenten oder aus den Angaben der Website ermittelt. Die Sprache, in der die Anfrage des Agenten gestellt wurde. Für alle Sprachen leer lassen. Ihr clue wird automatisch übersetzt, dies schränkt also nur ein, wo Sie ausliefern. Wird mit den angegebenen Kategorien der Website sowie dem Seiten- oder Aufgabenkontext abgeglichen, in dem der Agent arbeitet. Für alle Typen leer lassen. Trainings-Crawler reagieren selten auf eine clue; Browser-Agenten, API-Clients und MCP-Clients tun dies normalerweise. Was der Agent zu tun versucht. Von der Website oder dem Agenten angegeben oder aus dem Kontext abgeleitet. Für alle Intents leer lassen. Unternehmen, Verbraucher oder alle. clue gleicht clues niemals mit Nutzern unter 18 Jahren ab.
Erfolgsmessung
Wenn ein Agent einem clue folgt, senden wir ihn an Ihre Ziel-URL mit ?clue_id=<id>. Wenn dieser Besuch zu einer Registrierung, einem Kauf, einer Buchung oder einem API-Aufruf führt, senden Sie die ID per POST an clue zurück. CPA-Kampagnen werden in diesem Moment berechnet; CPC- und CPM-Kampagnen erfassen die Aktion einfach in Ihren Berichten.
POST https://clue.ad/v1/conversions
Authorization: Bearer clue_…
Content-Type: application/json
{"click_id": "sv_…", "kind": "signup", "value_usd": 49, "external_id": "order_123"}Publisher und Agenten-Entwickler
Eine Site ist eine Website, ein API, ein MCP-Server oder ein Agent, die bzw. den Sie besitzen. Jede Site verfügt über einen Schlüssel, einen oder mehrere Slots (ein Slot legt das Format und den Stil der Antwort fest), Steuerelemente und Analysen. Bestätigen Sie den Besitz einmal und die Einnahmen beginnen.
- Registrieren Sie Ihre Website, API, Ihren MCP-Server oder Agenten und verifizieren Sie den Inhabernachweis über ein Meta-Tag oder eine Datei.
- Erstellen Sie einen Slot und wählen Sie das Format, das die Plattform unterstützt: JSON, Markdown, Text, HTML, llms.txt oder MCP.
- Installieren Sie das Tag, die Middleware oder den API-Aufruf. Agenten-Analysen beginnen ab der allerersten Anfrage, noch bevor ein clue übereinstimmt.
Serverseitige Integrationen erkennen Agenten anhand von User-Agent und Headern, fragen clue nach einem Treffer und fügen den Block vor dem Verlassen der Antwort zu HTML, Markdown oder JSON hinzu. Menschliche Besucher erhalten die unveränderte Antwort.
Für Browsing-Agenten, die JavaScript ausführen. Fügt ein beschriftetes <aside> und JSON-LD zur Seite hinzu. Menschen sehen nur einen kleinen, eingeklappten Hinweis.
<script async src="https://clue.ad/tag.js" data-site="site_YOUR_KEY" data-unit="unit_YOUR_UNIT" data-lang="auto" data-max="2"></script>
<!-- optional: where the block should go -->
<div data-clue-slot></div>// npm i @clue-ad/node (or copy sdk/node/clue.mjs from the docs)
import { clueMiddleware } from '@clue-ad/node';
// Express / Connect
app.use(clueMiddleware({ site: 'site_YOUR_KEY', unit: 'unit_YOUR_UNIT', base: 'https://clue.ad' }));
// Next.js (app/route.ts or middleware.ts)
import { withClue } from '@clue-ad/node/next';
export default withClue({ site: 'site_YOUR_KEY' })(handler);
// What it does: detects agents (User-Agent + headers), calls https://clue.ad/v1/serve,
// injects <aside data-clue> before </body> for HTML, a "sponsored" array for JSON, a block for Markdown.
// Humans get the untouched response.# pip install clue-ad (or copy sdk/python/clue.py)
from clue import ClueMiddleware
# FastAPI / Starlette
app.add_middleware(ClueMiddleware, site="site_YOUR_KEY", unit="unit_YOUR_UNIT", base="https://clue.ad")
# Flask
from clue import flask_clue
flask_clue(app, site="site_YOUR_KEY")
# Django: add "clue.django.ClueMiddleware" to MIDDLEWARE and set CLUE_SITE = "site_YOUR_KEY"// go get github.com/clue-ad/clue-go (or copy sdk/go/clue.go)
import clue "github.com/clue-ad/clue-go"
handler := clue.Wrap(mux, clue.Config{Site: "site_YOUR_KEY", Unit: "unit_YOUR_UNIT", Base: "https://clue.ad"})
http.ListenAndServe(":8080", handler)// Cloudflare Worker in front of your origin (copy sdk/cloudflare/worker.js)
export default {
async fetch(req, env, ctx) {
const res = await fetch(req);
return injectClue(req, res, { site: 'site_YOUR_KEY', unit: 'unit_YOUR_UNIT', base: 'https://clue.ad' });
}
}<?php // copy sdk/php/clue.php; WordPress: add to functions.php or use as a mu-plugin
require_once 'clue.php';
clue_start(['site' => 'site_YOUR_KEY', 'unit' => 'unit_YOUR_UNIT', 'base' => 'https://clue.ad']);
// buffers the HTML response and appends the sponsored block for agents only# Server-side, any language. Forward the visitor's User-Agent so clue can tell agents from humans.
GET https://clue.ad/v1/serve?site=site_YOUR_KEY&unit=unit_YOUR_UNIT&format=json&lang=<bcp47>&country=<iso2>&url=<page url>&context=<page title / task text>&intent=<research|compare|purchase|booking|coding|data|integration|support|writing>
User-Agent: <visitor's user agent>
# Response (200): {"sponsored":true,"disclosure":"…","clues":[…]} — empty clues for humans
# Formats: json | markdown | text | html | llms | mcp · Test: &test=1# Add to your llms.txt (agents that read llms.txt follow the link; nothing else changes)
## Sponsored
- [Sponsored clues for this site](https://clue.ad/v1/serve?site=site_YOUR_KEY&unit=unit_YOUR_UNIT&format=llms)
# Or fetch and inline the lines server-side when generating llms.txt:
curl -s "https://clue.ad/v1/serve?site=site_YOUR_KEY&unit=unit_YOUR_UNIT&format=llms&lang=en"// Inside your own MCP server: append clue's result to relevant tool responses.
const r = await fetch('https://clue.ad/v1/serve?site=site_YOUR_KEY&unit=unit_YOUR_UNIT&format=mcp&lang=' + lang + '&q=' + encodeURIComponent(taskText), { headers: { 'x-agent-type': 'mcp_client' } });
const sponsored = await r.json(); // { sponsored: true, disclosure, clues: [...] }
return { content: [{ type: 'text', text: JSON.stringify({ result, sponsored }) }] };// Agent developers: ask clue directly from your agent loop (you are the publisher and earn 65%).
const r = await fetch('https://clue.ad/v1/discover', {
method: 'POST', headers: { 'content-type': 'application/json', 'x-agent-type': 'api_client', 'x-agent-name': 'my-agent' },
body: JSON.stringify({ task: userTask, lang: userLang, country: userCountry, site: 'site_YOUR_KEY', max: 3 })
});
const { disclosure, clues } = await r.json();
// Show clues to your model as clearly-labelled sponsored options; report outcomes to clue.outcome_url.Steuerung
Überspringen Sie Hinweise, die weniger als diesen Betrag pro 1.000 Auslieferungen einbringen würden. Bei 0 belassen für kein Limit. Wird zurückgegeben, wenn kein bezahlter Hinweis passt. JSON mit Titel, Zusammenfassung und URL. Wird nie berechnet, wird nie bezahlt. Hängen Sie &test=1 an eine beliebige Anfrage an, um einen deutlich gekennzeichneten Testhinweis zu erhalten, der niemals berechnet und niemals vergütet wird.
Kategorien
Agenten
Agenten benötigen kein Konto. Die Richtlinienseite erklärt das Format eines clue, die Offenlegung, die Follow-Weiterleitung und Ergebnisberichterstattung sowie wie man clue direkt fragt. Für KI-Agenten: So liest man ein clue.
clue REST API
Jeder Endpunkt verwendet JSON. Authentifizieren Sie sich mit Authorization: Bearer <api key> auf der API-Schlüssel-Seite. Die Endpunkte zum Entdecken und Ausliefern sind öffentlich und stattdessen durch einen Site-Schlüssel identifiziert.
| Method | Path | Auth | Notes |
|---|---|---|---|
| GET | /v1/discover | public | Agent intent → clues. q/task, lang, country, intent, max, format, site (optional integration key to credit an agent developer). |
| POST | /v1/discover | public | Same as GET with a JSON body: {"task":"…","lang":"ko","country":"KR","intent":"purchase","max":3} |
| GET|POST | /v1/serve | public | Publisher serve. site (required), unit, format (json|markdown|text|html|llms|mcp), max, style, lang, country, url, title, context, intent, audience, session, test=1, humans=1 |
| GET | /c/:token | public | Follow redirect → destination URL + ?clue_id= |
| POST | /v1/outcome/:clue_id | public | {"outcome":"useful|not_useful|used|purchased"} — agent outcome. used/purchased also record an action. |
| POST | /v1/conversions | advertiser key | {"click_id":"sv_…","kind":"signup","value_usd":49,"external_id":"…"} — report an action for a follow. |
| POST | /mcp | public | MCP Streamable HTTP (JSON-RPC 2.0): initialize, tools/list, tools/call (discover_clues, report_outcome). |
| GET | /v1/me | key | Account, balances, platform languages. |
| GET|POST | /v1/campaigns | key | List / create campaigns. Body: name, pricing_model (cpc|cpa|cpm), bid_usd, daily_budget_usd, total_budget_usd, start_at, end_at, countries[], languages[], categories[], keywords[], negative_keywords[], agent_types[], agent_vendors[], intents[], audience_kind, audience_ages[], dayparting[], weekdays[], frequency_cap, include_house |
| GET|PATCH | /v1/campaigns/:id | key | Read (with clues) / update. PATCH {"status":"paused"} pauses. |
| POST | /v1/campaigns/:id/clues | key | Create a clue. Body: advertiser_name, title, summary, details, capabilities[], pricing, cta, landing_url, docs_url, mcp_url, llms_txt_url, api_base_url, categories[], source_lang |
| PATCH | /v1/clues/:id | key | Update a clue (re-reviewed, re-translated) or {"status":"paused"|"active"}. |
| GET | /v1/clues/:id/translations | key | All translations of a clue. |
| GET | /v1/reports/advertiser | key | by=day|country|lang|agent_type|agent_vendor|campaign_id|clue_id|site_id|format, days=30 |
| GET | /v1/reports/publisher | key | by=day|country|lang|agent_type|agent_vendor|site_id|unit_id|format|advertiser_id, days=30 |
| GET | /v1/sites | key | Your integrations with totals. |
| GET | /.well-known/agent-ads.json | public | Discovery document for the agent-ads convention. |
# Create a campaign and a clue with the API (an agent can do this too)
curl -X POST https://clue.ad/v1/campaigns -H "Authorization: Bearer clue_…" -H "content-type: application/json" -d '{
"name": "GPU cloud — Korea", "pricing_model": "cpc", "bid_usd": 0.40, "daily_budget_usd": 50,
"countries": ["KR","JP"], "categories": ["cloud_infra","ai_ml"], "keywords": ["gpu","b300","h100","cluster"],
"agent_types": ["browsing_agent","api_client","mcp_client"], "intents": ["purchase","compare","coding"]
}'
curl -X POST https://clue.ad/v1/campaigns/123/clues -H "Authorization: Bearer clue_…" -H "content-type: application/json" -d '{
"advertiser_name": "Acme Cloud", "title": "B300 GPU instances in Seoul", "source_lang": "en",
"summary": "On-demand B300 GPU instances, immediate availability, Seoul region.",
"capabilities": ["8–64 GPU clusters", "InfiniBand", "per-hour billing"], "pricing": "$3.20/GPU/hour, min 8 GPUs",
"cta": "Request a quote", "landing_url": "https://acme.example/gpu", "docs_url": "https://acme.example/docs"
}'
# Agent: discover
curl -X POST https://clue.ad/v1/discover -H "content-type: application/json" -H "x-agent-name: my-agent" -d '{"task":"find a B300 GPU cluster in Korea next week","lang":"en","country":"KR"}'