Knocklog API
Analytics for AI agents: which AI agents visit a website, whether they are real, and what AI assistants send it.
Base URL https://api.knocklog.ai. Machine-readable description: openapi.json (OpenAPI 3.1).
Getting started
Check a site, no key needed
curl "https://api.knocklog.ai/v1/scan?domain=example.com"Create a project and keep both keys
curl -X POST "https://api.knocklog.ai/v1/projects" \ -H "Content-Type: application/json" \ -d '{"domain": "example.com"}'Install the collector from install.methods, or send access logs
curl -X POST "https://api.knocklog.ai/v1/logs" \ -H "Authorization: Bearer $KNOCKLOG_INGEST_KEY" \ -H "Content-Type: text/plain" \ --data-binary @access.logRead the report
curl "https://api.knocklog.ai/v1/traffic?days=30" \ -H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY"
Keys
Creating a project returns two keys, shown only once. Send them as Authorization: Bearer <key>.
- Ingest key (
kl_ing_…): sends traffic and nothing else. It is safe in a collector that runs on the site. - Admin key (
kl_adm_…): reads reports and manages the project. Keep it on a server, never in a page.
Lost the ingest key? Issue a new one with the admin key.
Errors and changes
Errors are JSON with a stable code: {"error": {"code": "plan_required", "message": "…"}}. 401 means a missing or invalid key, 403 a key that cannot do this, 402 a feature outside the project's plan and 429 too many requests. New fields can appear in any response; ignore the ones you do not know.
For AI agents
The same features are available over the Model Context Protocol, so Claude, ChatGPT and other agents can use Knocklog in the conversation:
https://api.knocklog.ai/mcp/directory: public tools (check a site, identify a request, list agents), no sign-in.https://api.knocklog.ai/mcp/account: one project's report and account, with OAuth sign-in.https://api.knocklog.ai/mcp: every tool, with keys as arguments.
Agents
Identify AI agents and check websites. No key needed.
GET /v1/agents
List known AI agents. No key
The directory of AI agents and crawlers: operator, purpose, User-Agent and robots.txt tokens, whether they obey robots.txt, what the operator publishes to recognise them, and the operator's documentation.
| Parameter | In | Notes |
|---|---|---|
class | query | Only agents of this class. One of: training_crawler, ai_search_crawler, user_action_agent, agentic_browser, coding_agent, search_engine, preview_fetcher, ads_checker, automation_client, scraper |
curl "https://api.knocklog.ai/v1/agents"200The directory400Invalid request
POST /v1/classify
Identify and verify one request. No key
Says whether a request came from an AI agent, which one, and whether it really is that agent. Pass at least the User-Agent or the headers; the IP address and URL make the answer more precise.
curl -X POST "https://api.knocklog.ai/v1/classify" \
-H "Content-Type: application/json" \
-d '{
"user_agent": "Mozilla/5.0; compatible; GPTBot/1.4; +https://openai.com/gptbot",
"ip": "20.171.206.10",
"url": "https://example.com/pricing"
}'200What the request is400Invalid request429Too many requests; retry later
GET /v1/scan
Check how a site treats AI agents. No key
Reads the site's robots.txt, homepage, llms.txt and markdown support, and returns a score from 0 to 100, what each known agent may access, and what to fix. Results are cached for a short time.
| Parameter | In | Notes |
|---|---|---|
domain | query, required | |
fresh | query | Skip the cache. One of: 1 |
curl "https://api.knocklog.ai/v1/scan?domain=example.com"200The site's readiness for AI agents400Invalid request429Too many requests; retry later
POST /v1/scan
Check how a site treats AI agents (JSON body). No key
curl -X POST "https://api.knocklog.ai/v1/scan" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com"}'200The site's readiness for AI agents400Invalid request429Too many requests; retry later
Projects
Create a project and send its traffic.
POST /v1/projects
Create a project. No key
Creates a project for a website. Returns the ingest and admin keys (shown only once) and install instructions with ready-to-paste code for the site's hosting. With email, the weekly summary is offered to that address, which must confirm by email.
curl -X POST "https://api.knocklog.ai/v1/projects" \
-H "Content-Type: application/json" \
-d '{"domain":"example.com","name":"Example"}'201Project created400Invalid request429Too many requests; retry later
POST /v1/events
Send requests from a collector. Optional: ingest key
Sends up to 100 requests the site received. With the ingest key they are classified and stored in the project. Without a key they are only classified and returned, so anyone can try the classifier on their own traffic.
Send each agent request with its IP address and headers (never cookies or authorization). For people's page views, send only HTML pages and keep the query string to utm_* parameters.
curl -X POST "https://api.knocklog.ai/v1/events" \
-H "Authorization: Bearer $KNOCKLOG_INGEST_KEY" \
-H "Content-Type: application/json" \
-d '{
"events": [
{
"timestamp": "2026-11-09T11:59:00Z",
"method": "GET",
"url": "https://example.com/pricing",
"ip": "20.171.206.10",
"status": 200,
"headers": {
"user-agent": "Mozilla/5.0; compatible; GPTBot/1.4; +https://openai.com/gptbot"
}
}
]
}'202Accepted. With a key: counts of what was stored. Without a key: one detection per event.400Invalid request401Missing or invalid key413Request too large429Too many requests; retry later
POST /v1/logs
Import access logs. Ingest key
Imports Apache or Nginx access log lines (combined format, as in cPanel Raw Access). Send the lines as text/plain, or as JSON {"log": "…", "host": "…"}. Up to 2 MiB per request; send larger logs in consecutive chunks. Re-sending a chunk is safe: duplicates are ignored.
| Parameter | In | Notes |
|---|---|---|
host | query | Subdomain the log belongs to, if not the project's main host |
ips | query | Whether the first field is the visitor's IP (direct) or a proxy's (proxy). One of: auto, direct, proxy. Default: auto |
live | query | Set by log shippers that send every few minutes, so the project is watched like a live collector. One of: 1 |
curl -X POST "https://api.knocklog.ai/v1/logs" \
-H "Authorization: Bearer $KNOCKLOG_INGEST_KEY"202Imported400Invalid request401Missing or invalid key413Request too large429Too many requests; retry later
Reports
Read what agents did on the site (admin key).
GET /v1/traffic
Traffic report. Admin key
What agents did on the site over the last N days: agent requests and people's page views, agents by class and by name, how many were verified or impostors, the pages agents read most, visits and leads sent by AI assistants, and a daily series. Companies that visited are listed on Business and up. The window is capped by the plan's history.
| Parameter | In | Notes |
|---|---|---|
days | query | Default: 30 |
curl "https://api.knocklog.ai/v1/traffic" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY"200The report400Invalid request401Missing or invalid key403The key cannot do this (for example an ingest key on an admin endpoint)
Account
Plan, keys, emails and integrations (admin key).
GET /v1/plans
List plans. No key
curl "https://api.knocklog.ai/v1/plans"200Plans and limits
GET /v1/plan
Plan and usage. Ingest key or admin key
The project's plan, this month's usage and the next plan up. Works with either key.
curl "https://api.knocklog.ai/v1/plan" \
-H "Authorization: Bearer $KNOCKLOG_INGEST_KEY"200Plan and usage401Missing or invalid key
GET /v1/account
Account overview. Admin key
Plan and usage, every benefit with whether the plan includes it and whether it is available today, when data last arrived, the summary contact, a checklist of first steps with live status, and the code snippets for the site (leads from AI, badge).
| Parameter | In | Notes |
|---|---|---|
lang | query | Language of titles and texts. One of: en, pt |
curl "https://api.knocklog.ai/v1/account" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY"200The account401Missing or invalid key403The key cannot do this (for example an ingest key on an admin endpoint)
GET /v1/ready-files
Ready-made robots.txt and llms.txt (Pro). Admin key
A draft llms.txt built from the site's homepage, and robots.txt lines for two AI policies. Review them before publishing.
| Parameter | In | Notes |
|---|---|---|
lang | query | Language of titles and texts. One of: en, pt |
curl "https://api.knocklog.ai/v1/ready-files" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY"200The drafts401Missing or invalid key402Not included in the project's plan403The key cannot do this (for example an ingest key on an admin endpoint)
POST /v1/keys/ingest
New ingest key. Admin key
Issues a new ingest key and returns the install code with it filled in. The previous ingest key stops working within a minute, so update the collector right away.
| Parameter | In | Notes |
|---|---|---|
lang | query | Language of titles and texts. One of: en, pt |
curl -X POST "https://api.knocklog.ai/v1/keys/ingest" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY"201New key401Missing or invalid key403The key cannot do this (for example an ingest key on an admin endpoint)429Too many requests; retry later
POST /v1/project/summary
Weekly summary by email. Admin key
Sends a confirmation link to the address. The weekly summary and account notices start once it is confirmed.
curl -X POST "https://api.knocklog.ai/v1/project/summary" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","lang":"en"}'202Confirmation sent400Invalid request401Missing or invalid key403The key cannot do this (for example an ingest key on an admin endpoint)429Too many requests; retry later
POST /v1/integrations
Webhook, Slack and company emails. Admin key
Sets where Knocklog sends events as they happen (see Webhooks). webhookUrl takes a Slack incoming webhook or any public https endpoint (Business and up); null removes it. When a URL is set, the response includes a webhookSecret once: JSON deliveries carry x-knocklog-signature: sha256=<HMAC-SHA256 of the body>. companyEmails turns the email to the contact when a company visits on or off (Enterprise). test: true sends a test event.
curl -X POST "https://api.knocklog.ai/v1/integrations" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"webhookUrl": "https://hooks.slack.com/services/T000/B000/XXXX"
}'200Saved settings400Invalid request401Missing or invalid key402Not included in the project's plan403The key cannot do this (for example an ingest key on an admin endpoint)
POST /v1/install/cloudflare
Install the collector on Cloudflare. Admin key
For sites whose DNS is on Cloudflare. Send a Cloudflare API token with Workers Scripts (edit), Workers Routes (edit) and Zone (read) permissions; GET /v1/account returns a link that creates one with exactly these permissions. Knocklog deploys the collector Worker and its routes and does not keep the token.
curl -X POST "https://api.knocklog.ai/v1/install/cloudflare" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"token":"<Cloudflare API token>"}'201Installed400Invalid request401Missing or invalid key403The key cannot do this (for example an ingest key on an admin endpoint)429Too many requests; retry later
POST /v1/billing/checkout
Checkout link for a paid plan. Admin key
Returns a checkout page where the site owner reviews the price and pays. The plan changes as soon as payment completes.
curl -X POST "https://api.knocklog.ai/v1/billing/checkout" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{"plan":"pro"}'200Checkout link400Invalid request401Missing or invalid key403The key cannot do this (for example an ingest key on an admin endpoint)429Too many requests; retry later503Temporarily unavailable
POST /v1/billing/portal
Link to manage the subscription. Admin key
A short-lived link to see invoices, change the card, switch plans or cancel. Only for projects with a paid subscription.
curl -X POST "https://api.knocklog.ai/v1/billing/portal" \
-H "Authorization: Bearer $KNOCKLOG_ADMIN_KEY"200Portal link400Invalid request401Missing or invalid key403The key cannot do this (for example an ingest key on an admin endpoint)429Too many requests; retry later503Temporarily unavailable
Badge
The public "AI-ready" badge.
GET /v1/badge/{project}.json
Badge status. No key
Whether the project is receiving the site's traffic, as shown by the badge.
| Parameter | In | Notes |
|---|---|---|
project | path, required |
curl "https://api.knocklog.ai/v1/badge/p0123456789abcdef0123.json"200Status404Not found
GET /v1/badge/{project}.svg
Badge image. No key
| Parameter | In | Notes |
|---|---|---|
project | path, required | |
lang | query | One of: en, pt |
curl "https://api.knocklog.ai/v1/badge/p0123456789abcdef0123.svg"200SVG image404Not found
Webhooks
Set a URL with POST /v1/integrations (Business and up) and Knocklog posts events as they happen. Slack incoming webhooks receive a readable message; any other https URL receives JSON:
{
"type": "lead.from_ai",
"project": "p0123456789abcdef0123",
"site": "https://example.com",
"occurredAt": "2026-11-09T14:02:11.000Z",
"data": {
"assistant": "ChatGPT",
"action": "whatsapp",
"page": "/contact"
}
}company.visited: people from an identified company's network visited the site. At most once per company per day;data.interestis true when they saw pricing, contact or similar pages.lead.from_ai: someone who arrived from an AI assistant sent a form or tapped WhatsApp, phone or email.
JSON deliveries carry x-knocklog-signature: sha256=<HMAC-SHA256 of the body>, made with the secret returned once when you set the URL. Check it before trusting a delivery:
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody: the request body exactly as received (a string or Buffer).
function isFromKnocklog(rawBody, signatureHeader, secret) {
const expected = "sha256=" + createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(expected);
const b = Buffer.from(signatureHeader ?? "");
return a.length === b.length && timingSafeEqual(a, b);
}Questions or a missing endpoint: contact@knocklog.ai.