@knownagents/sdk 1.7.0 → 1.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Known Agents SDK
2
2
 
3
- [![NPM version](https://img.shields.io/npm/v/@knownagents/sdk.svg)](https://npmjs.org/package/@knownagents/sdk) ![npm bundle size](https://img.shields.io/bundlephobia/minzip/@knownagents/sdk)
3
+ [![NPM version](https://img.shields.io/npm/v/@knownagents/sdk.svg)](https://npmjs.org/package/@knownagents/sdk)
4
4
 
5
5
  This library provides convenient access to [Known Agents](https://knownagents.com/) from server-side TypeScript or JavaScript.
6
6
 
@@ -53,7 +53,6 @@ const knownAgents = new KnownAgents("YOUR_ACCESS_TOKEN")
53
53
 
54
54
  app.use((req, res, next) => {
55
55
  const start = Date.now()
56
-
57
56
  res.on('finish', () => {
58
57
  const duration = Date.now() - start
59
58
  knownAgents.trackVisit(req, res, duration)
@@ -81,10 +80,10 @@ If your website is correctly connected, you should see visits from the Known Age
81
80
 
82
81
  Protect sensitive content from unwanted access and scraping. Generate a continuously updating robots.txt that stays up to date with [all current and future bots](https://knownagents.com/agents) in the specified categories automatically.
83
82
 
84
- Use the `generateRobotsTxt` function. Select which `AgentType`s you want to block, and a string specifying which URLs are disallowed (e.g. `"/"` to disallow all paths).
83
+ Use the `generateRobotsTXT` function. Select which `AgentType`s you want to block, and a string specifying which URLs are disallowed (e.g. `"/"` to disallow all paths).
85
84
 
86
85
  ```ts
87
- const robotsTxt = await knownAgents.generateRobotsTxt([
86
+ const robotsTxt = await knownAgents.generateRobotsTXT([
88
87
  AgentType.AIDataScraper,
89
88
  AgentType.Scraper,
90
89
  AgentType.IntelligenceGatherer,
@@ -96,6 +95,35 @@ const robotsTxt = await knownAgents.generateRobotsTxt([
96
95
 
97
96
  The return value is a plain text robots.txt string. Generate a `robotsTxt` periodically (e.g. once per day), then cache and serve it from your website's `/robots.txt` endpoint.
98
97
 
98
+ ## How To Use Agent Verification ([Full Docs](https://knownagents.com/docs/verification))
99
+
100
+ Use the `verifyAgent` function to [identify](https://knownagents.com/agents) and verify agents from network requests using Web Bot Auth (HTTP message signatures), IP matching, or other available methods. This can be useful for implementing access policies based on verified agent identity.
101
+
102
+ Call `verifyAgent` with the incoming request.
103
+
104
+ ```ts
105
+ const verification = await knownAgents.verifyAgent(request)
106
+
107
+ if (verification.result === "verified") {
108
+ // Agent is legitimate
109
+ } else if (verification.result === "verification_failed") {
110
+ // Agent is not legitimate
111
+ }
112
+ ```
113
+
114
+ The function returns an object with the following fields:
115
+
116
+ - `result`: The verification result:
117
+ - `"verified"`: The agent is identified and verified
118
+ - `"verification_failed"`: The agent was identified but could not be verified
119
+ - `"unknown_agent"`: The agent is not in our database
120
+ - `"not_verifiable"`: The agent cannot be verified (no verification method available)
121
+ - `agent_id`: The unique ID of the agent (if identified)
122
+ - `agent_token`: The name of the agent (e.g. `"Googlebot"`) (if identified)
123
+ - `agent_url`: The documentation URL of the agent (if identified)
124
+ - `agent_type_name`: The type of agent (e.g. `"AI Agent"`) (if identified)
125
+ - `operator_name`: The company behind the agent (e.g. `"Google"`) (if identified)
126
+
99
127
  ## Requirements
100
128
 
101
129
  TypeScript >= 4.7 is supported.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { IncomingMessage, ServerResponse } from "http";
2
2
  export interface Request {
3
- /** The path of the request's URL (e.g. "/about") */
3
+ /** The URL of the request, including the path and query string (e.g. "/about?foo=bar") */
4
4
  path: string;
5
5
  /** The request's HTTP method (e.g. "GET", "POST") */
6
6
  method: string;
@@ -11,6 +11,23 @@ export interface Response {
11
11
  /** The HTTP response status code */
12
12
  statusCode: number;
13
13
  }
14
+ /**
15
+ * The result of an agent verification check.
16
+ */
17
+ export interface VerificationResult {
18
+ /** The verification result */
19
+ result: "verified" | "verification_failed" | "unknown_agent" | "not_verifiable";
20
+ /** The unique ID of the agent (if identified) */
21
+ agent_id?: string;
22
+ /** The name of the agent (e.g. "Googlebot") (if identified) */
23
+ agent_token?: string;
24
+ /** The documentation URL of the agent (if identified) */
25
+ agent_url?: string;
26
+ /** The type of agent (e.g. "AI Agent") (if identified) */
27
+ agent_type_name?: string;
28
+ /** The company behind the agent (e.g. "Google") (if identified) */
29
+ operator_name?: string;
30
+ }
14
31
  /**
15
32
  * Agent types that can be controlled with robots.txt rules.
16
33
  */
@@ -41,12 +58,11 @@ export declare class KnownAgents {
41
58
  /**
42
59
  * Tracks an agent visit in Known Agents agent analytics.
43
60
  *
44
- * @param visitRequest - The incoming visit request.
45
- * @param visitResponse - The outgoing visit response (optional).
61
+ * @param request - The incoming request.
62
+ * @param response - The outgoing response (optional).
46
63
  * @param responseDurationInMilliseconds - The response duration in milliseconds (optional).
47
64
  */
48
- trackVisit(request: Request, response?: Response, responseDurationInMilliseconds?: number): void;
49
- trackVisit(request: IncomingMessage, response?: ServerResponse, responseDurationInMilliseconds?: number): void;
65
+ trackVisit(request: Request | IncomingMessage, response?: Response | ServerResponse, responseDurationInMilliseconds?: number): void;
50
66
  /**
51
67
  * Generates a `robots.txt` file that disallows the specified agent types.
52
68
  * Cache and serve this string at your website’s `/robots.txt` endpoint.
@@ -56,7 +72,15 @@ export declare class KnownAgents {
56
72
  * @returns The generated `robots.txt` as a string.
57
73
  * @throws If the API call fails or returns a non-200 status.
58
74
  */
59
- generateRobotsTxt(agentTypes: AgentType[], disallow?: string): Promise<string>;
75
+ generateRobotsTXT(agentTypes: AgentType[], disallow?: string): Promise<string>;
76
+ /**
77
+ * Verifies if an agent request is legitimate by checking it against Known Agents.
78
+ *
79
+ * @param request - The incoming request.
80
+ * @returns A promise that resolves to the verification result.
81
+ * @throws If the API call fails or returns a non-200 status.
82
+ */
83
+ verifyAgent(request: Request | IncomingMessage): Promise<VerificationResult>;
60
84
  private filterHeaders;
61
85
  }
62
86
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAItD,MAAM,WAAW,OAAO;IACpB,oDAAoD;IACpD,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;CACzD;AAED,MAAM,WAAW,QAAQ;IACrB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,oBAAY,SAAS;IACjB,OAAO,aAAa;IACpB,WAAW,iBAAiB;IAC5B,aAAa,oBAAoB;IACjC,eAAe,sBAAsB;IACrC,QAAQ,aAAa;IACrB,eAAe,qBAAqB;IACpC,OAAO,YAAY;IACnB,aAAa,mBAAmB;IAChC,oBAAoB,0BAA0B;IAC9C,OAAO,YAAY;IACnB,UAAU,gBAAgB;IAC1B,mBAAmB,0BAA0B;IAC7C,eAAe,qBAAqB;IACpC,mBAAmB,0BAA0B;CAChD;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IAEpC;;;;OAIG;gBACS,WAAW,EAAE,MAAM;IAI/B;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,QAAQ,EAAE,8BAA8B,CAAC,EAAE,MAAM,GAAG,IAAI;IAChG,UAAU,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,cAAc,EAAE,8BAA8B,CAAC,EAAE,MAAM,GAAG,IAAI;IA4B9G;;;;;;;;OAQG;IACG,iBAAiB,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,QAAQ,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAuBzF,OAAO,CAAC,aAAa;CAcxB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,MAAM,CAAA;AAItD,MAAM,WAAW,OAAO;IACpB,0FAA0F;IAC1F,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAA;IACd,iCAAiC;IACjC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,SAAS,CAAC,CAAA;CACzD;AAED,MAAM,WAAW,QAAQ;IACrB,oCAAoC;IACpC,UAAU,EAAE,MAAM,CAAA;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B,8BAA8B;IAC9B,MAAM,EAAE,UAAU,GAAG,qBAAqB,GAAG,eAAe,GAAG,gBAAgB,CAAA;IAC/E,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+DAA+D;IAC/D,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,yDAAyD;IACzD,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,0DAA0D;IAC1D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,mEAAmE;IACnE,aAAa,CAAC,EAAE,MAAM,CAAA;CACzB;AAED;;GAEG;AACH,oBAAY,SAAS;IACjB,OAAO,aAAa;IACpB,WAAW,iBAAiB;IAC5B,aAAa,oBAAoB;IACjC,eAAe,sBAAsB;IACrC,QAAQ,aAAa;IACrB,eAAe,qBAAqB;IACpC,OAAO,YAAY;IACnB,aAAa,mBAAmB;IAChC,oBAAoB,0BAA0B;IAC9C,OAAO,YAAY;IACnB,UAAU,gBAAgB;IAC1B,mBAAmB,0BAA0B;IAC7C,eAAe,qBAAqB;IACpC,mBAAmB,0BAA0B;CAChD;AAED,qBAAa,WAAW;IACpB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAQ;IAEpC;;;;OAIG;gBACS,WAAW,EAAE,MAAM;IAI/B;;;;;;OAMG;IACH,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,EAAE,QAAQ,CAAC,EAAE,QAAQ,GAAG,cAAc,EAAE,8BAA8B,CAAC,EAAE,MAAM,GAAG,IAAI;IAqBnI;;;;;;;;OAQG;IACG,iBAAiB,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,QAAQ,GAAE,MAAY,GAAG,OAAO,CAAC,MAAM,CAAC;IAqBzF;;;;;;OAMG;IACG,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAuBlF,OAAO,CAAC,aAAa;CAcxB"}
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.KnownAgents = exports.AgentType = void 0;
4
- const NODE_PACKAGE_VERSION = "1.7.0";
4
+ const NODE_PACKAGE_VERSION = "1.9.0";
5
5
  /**
6
6
  * Agent types that can be controlled with robots.txt rules.
7
7
  */
@@ -31,12 +31,14 @@ class KnownAgents {
31
31
  constructor(accessToken) {
32
32
  this.accessToken = accessToken;
33
33
  }
34
- trackVisit(visitRequest, visitResponse, responseDurationInMilliseconds) {
35
- const request = "path" in visitRequest ? visitRequest : {
36
- path: visitRequest.url ? new URL(visitRequest.url, "https://example.org/").pathname : "/",
37
- method: visitRequest.method ?? "GET",
38
- headers: visitRequest.headers
39
- };
34
+ /**
35
+ * Tracks an agent visit in Known Agents agent analytics.
36
+ *
37
+ * @param request - The incoming request.
38
+ * @param response - The outgoing response (optional).
39
+ * @param responseDurationInMilliseconds - The response duration in milliseconds (optional).
40
+ */
41
+ trackVisit(request, response, responseDurationInMilliseconds) {
40
42
  fetch("https://api.knownagents.com/visits", {
41
43
  method: "POST",
42
44
  headers: {
@@ -44,10 +46,10 @@ class KnownAgents {
44
46
  "Content-Type": "application/json"
45
47
  },
46
48
  body: JSON.stringify({
47
- request_path: request.path,
49
+ request_path: "path" in request ? request.path : request.url,
48
50
  request_method: request.method,
49
51
  request_headers: this.filterHeaders(request.headers),
50
- response_status_code: visitResponse?.statusCode,
52
+ response_status_code: response?.statusCode,
51
53
  response_duration_in_milliseconds: responseDurationInMilliseconds,
52
54
  node_package_version: NODE_PACKAGE_VERSION,
53
55
  created: new Date().toISOString()
@@ -65,7 +67,7 @@ class KnownAgents {
65
67
  * @returns The generated `robots.txt` as a string.
66
68
  * @throws If the API call fails or returns a non-200 status.
67
69
  */
68
- async generateRobotsTxt(agentTypes, disallow = "/") {
70
+ async generateRobotsTXT(agentTypes, disallow = "/") {
69
71
  const response = await fetch("https://api.knownagents.com/robots-txts", {
70
72
  method: "POST",
71
73
  headers: {
@@ -85,6 +87,33 @@ class KnownAgents {
85
87
  throw new Error(`Known Agents failed to generate robots.txt: ${response.status} ${response.statusText}`);
86
88
  }
87
89
  }
90
+ /**
91
+ * Verifies if an agent request is legitimate by checking it against Known Agents.
92
+ *
93
+ * @param request - The incoming request.
94
+ * @returns A promise that resolves to the verification result.
95
+ * @throws If the API call fails or returns a non-200 status.
96
+ */
97
+ async verifyAgent(request) {
98
+ const response = await fetch("https://api.knownagents.com/agent-verifications", {
99
+ method: "POST",
100
+ headers: {
101
+ "Authorization": `Bearer ${this.accessToken}`,
102
+ "Content-Type": "application/json"
103
+ },
104
+ body: JSON.stringify({
105
+ request_path: "path" in request ? request.path : request.url,
106
+ request_headers: this.filterHeaders(request.headers),
107
+ node_package_version: NODE_PACKAGE_VERSION
108
+ })
109
+ });
110
+ if (response.ok) {
111
+ return await response.json();
112
+ }
113
+ else {
114
+ throw new Error(`Known Agents failed to verify agent: ${response.status} ${response.statusText}`);
115
+ }
116
+ }
88
117
  // Helpers
89
118
  filterHeaders(headers) {
90
119
  const excludedHeaders = new Set([
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@knownagents/sdk",
3
- "version": "1.7.0",
4
- "description": "The official Node.js SDK for Known Agents: AI agent analytics (bot traffic), LLM referral tracking, automatic robots.txt",
3
+ "version": "1.9.0",
4
+ "description": "The official Node.js SDK for Known Agents: AI agent analytics (bot traffic), LLM referral tracking, automatic robots.txt, agent verification",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -13,13 +13,22 @@
13
13
  "ai scrapers",
14
14
  "ai crawlers",
15
15
  "ai bots",
16
+ "bot detection",
17
+ "crawler detection",
18
+ "llm analytics",
16
19
  "robots.txt",
17
20
  "automatic robots.txt",
18
21
  "robots.txt generator",
19
22
  "web scraping",
20
23
  "ai blocking",
21
24
  "bot blocking",
22
- "block ai bots",
25
+ "agent verification",
26
+ "bot verification",
27
+ "verify ai agents",
28
+ "web bot auth",
29
+ "http signatures",
30
+ "security",
31
+ "typescript",
23
32
  "express middleware"
24
33
  ],
25
34
  "main": "dist/index.js",
package/src/index.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { IncomingMessage, ServerResponse } from "http"
2
2
 
3
- const NODE_PACKAGE_VERSION = "1.7.0"
3
+ const NODE_PACKAGE_VERSION = "1.9.0"
4
4
 
5
5
  export interface Request {
6
- /** The path of the request's URL (e.g. "/about") */
6
+ /** The URL of the request, including the path and query string (e.g. "/about?foo=bar") */
7
7
  path: string
8
8
  /** The request's HTTP method (e.g. "GET", "POST") */
9
9
  method: string
@@ -16,6 +16,24 @@ export interface Response {
16
16
  statusCode: number
17
17
  }
18
18
 
19
+ /**
20
+ * The result of an agent verification check.
21
+ */
22
+ export interface VerificationResult {
23
+ /** The verification result */
24
+ result: "verified" | "verification_failed" | "unknown_agent" | "not_verifiable"
25
+ /** The unique ID of the agent (if identified) */
26
+ agent_id?: string
27
+ /** The name of the agent (e.g. "Googlebot") (if identified) */
28
+ agent_token?: string
29
+ /** The documentation URL of the agent (if identified) */
30
+ agent_url?: string
31
+ /** The type of agent (e.g. "AI Agent") (if identified) */
32
+ agent_type_name?: string
33
+ /** The company behind the agent (e.g. "Google") (if identified) */
34
+ operator_name?: string
35
+ }
36
+
19
37
  /**
20
38
  * Agent types that can be controlled with robots.txt rules.
21
39
  */
@@ -51,19 +69,11 @@ export class KnownAgents {
51
69
  /**
52
70
  * Tracks an agent visit in Known Agents agent analytics.
53
71
  *
54
- * @param visitRequest - The incoming visit request.
55
- * @param visitResponse - The outgoing visit response (optional).
72
+ * @param request - The incoming request.
73
+ * @param response - The outgoing response (optional).
56
74
  * @param responseDurationInMilliseconds - The response duration in milliseconds (optional).
57
75
  */
58
- trackVisit(request: Request, response?: Response, responseDurationInMilliseconds?: number): void
59
- trackVisit(request: IncomingMessage, response?: ServerResponse, responseDurationInMilliseconds?: number): void
60
- trackVisit(visitRequest: Request | IncomingMessage, visitResponse?: Response | ServerResponse, responseDurationInMilliseconds?: number): void {
61
- const request: Request = "path" in visitRequest ? visitRequest : {
62
- path: visitRequest.url ? new URL(visitRequest.url, "https://example.org/").pathname : "/",
63
- method: visitRequest.method ?? "GET",
64
- headers: visitRequest.headers
65
- }
66
-
76
+ trackVisit(request: Request | IncomingMessage, response?: Response | ServerResponse, responseDurationInMilliseconds?: number): void {
67
77
  fetch("https://api.knownagents.com/visits", {
68
78
  method: "POST",
69
79
  headers: {
@@ -71,10 +81,10 @@ export class KnownAgents {
71
81
  "Content-Type": "application/json"
72
82
  },
73
83
  body: JSON.stringify({
74
- request_path: request.path,
84
+ request_path: "path" in request ? request.path : request.url,
75
85
  request_method: request.method,
76
86
  request_headers: this.filterHeaders(request.headers),
77
- response_status_code: visitResponse?.statusCode,
87
+ response_status_code: response?.statusCode,
78
88
  response_duration_in_milliseconds: responseDurationInMilliseconds,
79
89
  node_package_version: NODE_PACKAGE_VERSION,
80
90
  created: new Date().toISOString()
@@ -83,7 +93,7 @@ export class KnownAgents {
83
93
  console.error(`Known Agents failed to track visit: ${error.message}`)
84
94
  })
85
95
  }
86
-
96
+
87
97
  /**
88
98
  * Generates a `robots.txt` file that disallows the specified agent types.
89
99
  * Cache and serve this string at your website’s `/robots.txt` endpoint.
@@ -93,7 +103,7 @@ export class KnownAgents {
93
103
  * @returns The generated `robots.txt` as a string.
94
104
  * @throws If the API call fails or returns a non-200 status.
95
105
  */
96
- async generateRobotsTxt(agentTypes: AgentType[], disallow: string = "/"): Promise<string> {
106
+ async generateRobotsTXT(agentTypes: AgentType[], disallow: string = "/"): Promise<string> {
97
107
  const response = await fetch("https://api.knownagents.com/robots-txts", {
98
108
  method: "POST",
99
109
  headers: {
@@ -113,6 +123,34 @@ export class KnownAgents {
113
123
  throw new Error(`Known Agents failed to generate robots.txt: ${response.status} ${response.statusText}`)
114
124
  }
115
125
  }
126
+
127
+ /**
128
+ * Verifies if an agent request is legitimate by checking it against Known Agents.
129
+ *
130
+ * @param request - The incoming request.
131
+ * @returns A promise that resolves to the verification result.
132
+ * @throws If the API call fails or returns a non-200 status.
133
+ */
134
+ async verifyAgent(request: Request | IncomingMessage): Promise<VerificationResult> {
135
+ const response = await fetch("https://api.knownagents.com/agent-verifications", {
136
+ method: "POST",
137
+ headers: {
138
+ "Authorization": `Bearer ${this.accessToken}`,
139
+ "Content-Type": "application/json"
140
+ },
141
+ body: JSON.stringify({
142
+ request_path: "path" in request ? request.path : request.url,
143
+ request_headers: this.filterHeaders(request.headers),
144
+ node_package_version: NODE_PACKAGE_VERSION
145
+ })
146
+ })
147
+
148
+ if (response.ok) {
149
+ return await response.json()
150
+ } else {
151
+ throw new Error(`Known Agents failed to verify agent: ${response.status} ${response.statusText}`)
152
+ }
153
+ }
116
154
 
117
155
  // Helpers
118
156