Dokumentacja
Wszystko, co niezbędne do reklamowania, publikowania i odczytywania wskazówek. Reklamodawcy zaczynają od kampanii i wskazówki. Wydawcy zaczynają od jednej witryny i jednego fragmentu kodu instalacyjnego. Agenci zaczynają od strony zasad. Wszystko to jest dostępne przez API REST.
Reklamodawcy
Konto reklamodawcy zawiera przedpłacone saldo, kampanie i clue. Kampania definiuje model cenowy, stawki, budżety i zasady dopasowywania. Clue to rekord, który otrzymują agenci. Wszystko poniżej można wykonać również za pomocą klucza API.
- Doładuj saldo. Pierwsze doładowanie wynosi 50 USD lub więcej, kartą przez Stripe.
- Utwórz kampanię: wybierz CPC, CPA lub CPM, ustaw stawkę maksymalną oraz budżety i zdefiniuj, kiedy kampania powinna być brana pod uwagę.
- Napisz clue w swoim języku. clue weryfikuje je pod kątem zasad w około minutę i tłumaczy na 20 języków.
Zasady dopasowania
Pozostaw puste dla zasięgu globalnego. Kraj pochodzi z lokalizacji sieciowej agenta lub z informacji przekazanych przez witrynę. Język, w którym pytał agent. Pozostaw puste dla dowolnego języka. Twoje clue jest tłumaczone automatycznie, więc ogranicza to jedynie miejsce wyświetlania. Dopasowywane do zadeklarowanych kategorii witryny oraz kontekstu strony lub zadania, nad którym pracuje agent. Pozostaw puste dla wszystkich typów. Crawlery trenujące rzadko reagują na clue; agenci przeglądający, klienci API i klienci MCP zazwyczaj tak. Co agent próbuje zrobić. Zadeklarowane przez witrynę lub agenta bądź wywnioskowane z kontekstu. Pozostaw puste dla wszystkich intencji. Firmy, konsumenci lub ktokolwiek. clue nigdy nie dopasowuje wskazówek dla użytkowników poniżej 18 roku życia.
Raportowanie wyników
Gdy agent śledzi clue, wysyłamy go pod adres URL docelowy z parametrem ?clue_id=<id>. Kiedy ta wizyta zamieni się w rejestrację, zakup, rezerwację lub wywołanie API, prześlij ID z powrotem do clue metodą POST. Kampanie CPA są rozliczane w tym momencie; kampanie CPC i CPM po prostu rejestrują działanie w Twoich raportach.
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"}Wydawcy i deweloperzy agentów
Witryna to strona internetowa, API, serwer MCP lub agent, którego jesteś właścicielem. Każda witryna ma klucz, jeden lub więcej slotów (slot określa format i styl odpowiedzi), kontrolery oraz analitykę. Zweryfikuj własność raz, a zarobki się rozpoczną.
- Zarejestruj swoją witrynę, API, serwer MCP lub agenta i zweryfikuj własność za pomocą znacznika meta lub pliku.
- Utwórz miejsce docelowe i wybierz format obsługiwany przez powierzchnię: JSON, Markdown, tekst, HTML, llms.txt lub MCP.
- Zainstaluj znacznik, oprogramowanie pośredniczące lub wywołanie API. Analityka agentów rozpoczyna się od pierwszego żądania, jeszcze zanim clue zostanie dopasowane.
Integracje po stronie serwera wykrywają agentów na podstawie nagłówka User-Agent i nagłówków, pytają clue o dopasowanie i dodają blok do HTML, Markdown lub JSON zanim odpowiedź opuści Twój serwer. Odwiedzający będący ludźmi otrzymują niezmienioną odpowiedź.
Dla agentów przeglądających, które wykonują JavaScript. Dodaje do strony etykietowany element <aside> oraz JSON-LD. Ludzie widzą tylko małą, zwiniętą notatkę.
<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.Sterowanie
Pomijaj clue, które przyniosłyby Ci mniej niż ta kwota za 1 000 wyświetleń. Pozostaw wartość 0, aby nie ustawiać minimum. Zwracane, gdy żadne płatne clue nie pasuje. JSON z tytułem, podsumowaniem i URL. Nigdy nie jest rozliczane ani opłacane. Dodaj &test=1 do dowolnego żądania, aby otrzymać wyraźnie oznaczoną wskazówkę testową, która nie podlega opłatom ani wypłatom.
Kategorie
Agenci
Agenci nie potrzebują konta. Strona zasad wyjaśnia format clue, ujawnienie, przekierowanie przejścia i raportowanie wyników oraz sposób bezpośredniego zadawania pytań clue. Dla agentów AI: jak odczytać clue.
clue REST API
Każdy endpoint obsługuje format JSON. Uwierzytelniaj się za pomocą nagłówka Authorization: Bearer <klucz api> dostępnego na stronie kluczy API. Endpointy discover i serve są publiczne i zamiast tego są identyfikowane przez klucz witryny.
| 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"}'