pounce-agent-data 1.0.1 → 2.0.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/dist/index.d.ts +134 -192
- package/dist/index.js +120 -237
- package/package.json +15 -24
- package/README.md +0 -62
- package/dist/index.d.mts +0 -204
- package/dist/index.mjs +0 -218
package/dist/index.d.ts
CHANGED
|
@@ -1,204 +1,146 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Pounce Agent Data SDK
|
|
3
|
-
*
|
|
4
|
-
* Minimal client for the Pounce Agent Data API.
|
|
5
|
-
* Supports recent signals, semantic search, signal details, and SSE streaming.
|
|
2
|
+
* Pounce Agent Data SDK — TypeScript client for the Pounce v2 Entity API.
|
|
6
3
|
*
|
|
7
4
|
* @example
|
|
8
|
-
* ```
|
|
9
|
-
* import {
|
|
10
|
-
*
|
|
11
|
-
* const client = new PounceAgentDataClient({ apiKey: 'pounce_live_xxx' });
|
|
12
|
-
*
|
|
13
|
-
* // Recent signals
|
|
14
|
-
* const { json, rateLimit } = await client.recentSignals({ limit: 10, category: 'saas' });
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { PounceClient } from 'pounce-agent-data';
|
|
15
7
|
*
|
|
16
|
-
*
|
|
17
|
-
* const
|
|
18
|
-
*
|
|
19
|
-
* // Stream new signals
|
|
20
|
-
* for await (const signal of client.stream({ minScore: 70 })) {
|
|
21
|
-
* console.log(signal);
|
|
22
|
-
* }
|
|
8
|
+
* const client = new PounceClient({ apiKey: 'your_key' });
|
|
9
|
+
* const { data } = await client.search({ q: 'AI companies', country: 'CH' });
|
|
10
|
+
* data.items.forEach(c => console.log(c.canonical_name, c.primary_domain));
|
|
23
11
|
* ```
|
|
24
12
|
*/
|
|
25
|
-
|
|
26
|
-
limit?: number;
|
|
27
|
-
remaining?: number;
|
|
28
|
-
resetUnix?: number;
|
|
29
|
-
};
|
|
30
|
-
type Signal = {
|
|
31
|
-
signalId: string;
|
|
32
|
-
domain: string;
|
|
33
|
-
companyName?: string | null;
|
|
34
|
-
category?: string | null;
|
|
35
|
-
subcategory?: string | null;
|
|
36
|
-
signalScore: number;
|
|
37
|
-
trustScore?: number | null;
|
|
38
|
-
intentTags?: string[] | null;
|
|
39
|
-
techStack?: string[] | null;
|
|
40
|
-
country?: string | null;
|
|
41
|
-
description?: string | null;
|
|
42
|
-
detectedAt?: string | null;
|
|
43
|
-
uiUrl?: string | null;
|
|
44
|
-
};
|
|
45
|
-
type AgentDataRecentSignal = {
|
|
13
|
+
export interface EntitySummary {
|
|
46
14
|
id: number;
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
intent_tags?: string[] | null;
|
|
81
|
-
country?: string | null;
|
|
82
|
-
ui_url?: string | null;
|
|
83
|
-
};
|
|
84
|
-
type SemanticSearchResponse = {
|
|
85
|
-
items: SemanticSearchItem[];
|
|
86
|
-
count: number;
|
|
87
|
-
query_tokens?: number;
|
|
88
|
-
};
|
|
89
|
-
type SignalDetailResponse = {
|
|
90
|
-
signal_id: string;
|
|
91
|
-
domain: string;
|
|
92
|
-
company_name?: string | null;
|
|
93
|
-
category?: string | null;
|
|
94
|
-
subcategory?: string | null;
|
|
95
|
-
signal_score: number;
|
|
96
|
-
trust_score?: number | null;
|
|
97
|
-
intent_tags?: string[] | null;
|
|
98
|
-
tech_stack?: string[] | null;
|
|
99
|
-
country?: string | null;
|
|
100
|
-
description?: string | null;
|
|
101
|
-
social_links?: Record<string, string> | null;
|
|
102
|
-
detected_at?: string | null;
|
|
103
|
-
ui_url?: string | null;
|
|
104
|
-
};
|
|
105
|
-
type AgentDataUsageResponse = {
|
|
106
|
-
api_key_prefix: string;
|
|
107
|
-
usage: {
|
|
108
|
-
period_start: string;
|
|
109
|
-
period_end: string;
|
|
110
|
-
used: number;
|
|
111
|
-
limit: number;
|
|
112
|
-
remaining: number;
|
|
113
|
-
reset_at: string;
|
|
114
|
-
};
|
|
115
|
-
};
|
|
116
|
-
type RecentSignalsOptions = {
|
|
117
|
-
hours?: number;
|
|
118
|
-
limit?: number;
|
|
119
|
-
minScore?: number;
|
|
120
|
-
category?: string;
|
|
121
|
-
country?: string;
|
|
122
|
-
tlds?: string[];
|
|
123
|
-
};
|
|
124
|
-
type SemanticSearchOptions = {
|
|
125
|
-
limit?: number;
|
|
126
|
-
minScore?: number;
|
|
127
|
-
category?: string;
|
|
128
|
-
country?: string;
|
|
129
|
-
tlds?: string[];
|
|
130
|
-
};
|
|
131
|
-
type StreamOptions = {
|
|
132
|
-
minScore?: number;
|
|
133
|
-
category?: string;
|
|
134
|
-
since?: string;
|
|
135
|
-
};
|
|
136
|
-
declare class PounceAgentDataClient {
|
|
137
|
-
private readonly apiKey;
|
|
138
|
-
private readonly baseUrl;
|
|
139
|
-
constructor(options: {
|
|
140
|
-
apiKey: string;
|
|
141
|
-
baseUrl?: string;
|
|
142
|
-
});
|
|
143
|
-
private extractRateLimit;
|
|
144
|
-
private getJson;
|
|
145
|
-
private postJson;
|
|
146
|
-
/**
|
|
147
|
-
* Get recent B2B signals.
|
|
148
|
-
*/
|
|
149
|
-
recentSignals(options?: RecentSignalsOptions): Promise<{
|
|
150
|
-
json: RecentSignalsResponse;
|
|
151
|
-
rateLimit: RateLimitInfo;
|
|
15
|
+
canonical_name: string | null;
|
|
16
|
+
country: string | null;
|
|
17
|
+
city: string | null;
|
|
18
|
+
trust_tier: number;
|
|
19
|
+
quality_score: number;
|
|
20
|
+
primary_domain: string | null;
|
|
21
|
+
categories: Record<string, unknown> | null;
|
|
22
|
+
first_seen_at: string | null;
|
|
23
|
+
}
|
|
24
|
+
export interface SemanticSearchItem extends EntitySummary {
|
|
25
|
+
description: string | null;
|
|
26
|
+
employee_estimate: number | null;
|
|
27
|
+
relevance_score: number;
|
|
28
|
+
}
|
|
29
|
+
export interface EntityDetail extends EntitySummary {
|
|
30
|
+
legal_name: string | null;
|
|
31
|
+
lei: string | null;
|
|
32
|
+
region: string | null;
|
|
33
|
+
tech_stack: Record<string, unknown> | null;
|
|
34
|
+
keywords: string[] | null;
|
|
35
|
+
description: string | null;
|
|
36
|
+
employee_estimate: number | null;
|
|
37
|
+
revenue_estimate_usd: number | null;
|
|
38
|
+
founded_year: number | null;
|
|
39
|
+
legal_form: string | null;
|
|
40
|
+
is_verified: boolean;
|
|
41
|
+
intent_signals: Record<string, unknown> | null;
|
|
42
|
+
social_links: Record<string, string> | null;
|
|
43
|
+
last_enriched_at: string | null;
|
|
44
|
+
domains: Array<{
|
|
45
|
+
domain: string;
|
|
46
|
+
is_primary: boolean;
|
|
47
|
+
source: string | null;
|
|
152
48
|
}>;
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
* @param options - Search options
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```typescript
|
|
161
|
-
* const { json } = await client.search('AI startups in healthcare', { limit: 10 });
|
|
162
|
-
* for (const item of json.items) {
|
|
163
|
-
* console.log(`${item.domain}: similarity=${item.similarity.toFixed(2)}`);
|
|
164
|
-
* }
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
search(query: string, options?: SemanticSearchOptions): Promise<{
|
|
168
|
-
json: SemanticSearchResponse;
|
|
169
|
-
rateLimit: RateLimitInfo;
|
|
49
|
+
registrations: Array<{
|
|
50
|
+
registry: string;
|
|
51
|
+
registry_id: string;
|
|
52
|
+
legal_name: string | null;
|
|
170
53
|
}>;
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
json: SignalDetailResponse;
|
|
176
|
-
rateLimit: RateLimitInfo;
|
|
54
|
+
financials: Array<{
|
|
55
|
+
source: string;
|
|
56
|
+
fiscal_year: number | null;
|
|
57
|
+
revenue: number | null;
|
|
177
58
|
}>;
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
usage(): Promise<{
|
|
182
|
-
json: AgentDataUsageResponse;
|
|
183
|
-
rateLimit: RateLimitInfo;
|
|
59
|
+
connections: Array<{
|
|
60
|
+
connected_entity_id: number;
|
|
61
|
+
connection_type: string;
|
|
184
62
|
}>;
|
|
185
|
-
/**
|
|
186
|
-
* Stream new signals in real-time via SSE.
|
|
187
|
-
*
|
|
188
|
-
* @param options - Stream options
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```typescript
|
|
192
|
-
* for await (const signal of client.stream({ minScore: 70 })) {
|
|
193
|
-
* console.log(`New signal: ${signal.domain} (score=${signal.signalScore})`);
|
|
194
|
-
* }
|
|
195
|
-
* ```
|
|
196
|
-
*
|
|
197
|
-
* @note This is an async generator. Make sure to handle connection errors and reconnect if needed.
|
|
198
|
-
*/
|
|
199
|
-
stream(options?: StreamOptions): AsyncGenerator<Signal, void, unknown>;
|
|
200
|
-
private parseSignal;
|
|
201
63
|
}
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
64
|
+
export interface SearchResponse {
|
|
65
|
+
items: EntitySummary[];
|
|
66
|
+
total: number;
|
|
67
|
+
limit: number;
|
|
68
|
+
offset: number;
|
|
69
|
+
}
|
|
70
|
+
export interface SemanticSearchResponse {
|
|
71
|
+
items: SemanticSearchItem[];
|
|
72
|
+
total: number;
|
|
73
|
+
query: string;
|
|
74
|
+
}
|
|
75
|
+
export interface BulkResponse {
|
|
76
|
+
items: EntitySummary[];
|
|
77
|
+
not_found: string[];
|
|
78
|
+
}
|
|
79
|
+
export interface MatchScoreResponse {
|
|
80
|
+
entity_a_id: number;
|
|
81
|
+
entity_b_id: number;
|
|
82
|
+
score: number;
|
|
83
|
+
grade: string;
|
|
84
|
+
dimensions: {
|
|
85
|
+
offering_fit: number;
|
|
86
|
+
timing: number;
|
|
87
|
+
trust: number;
|
|
88
|
+
reciprocity: number;
|
|
89
|
+
};
|
|
90
|
+
evidence: string[];
|
|
91
|
+
}
|
|
92
|
+
export interface StatsResponse {
|
|
93
|
+
total_entities: number;
|
|
94
|
+
verified_entities: number;
|
|
95
|
+
countries_covered: number;
|
|
96
|
+
api_version: string;
|
|
97
|
+
}
|
|
98
|
+
export interface RateLimitInfo {
|
|
99
|
+
remaining: number;
|
|
100
|
+
creditsUsed: number;
|
|
101
|
+
}
|
|
102
|
+
export interface ApiResponse<T> {
|
|
103
|
+
data: T;
|
|
104
|
+
rateLimit: RateLimitInfo;
|
|
105
|
+
}
|
|
106
|
+
export declare class PounceError extends Error {
|
|
107
|
+
statusCode: number;
|
|
108
|
+
detail: unknown;
|
|
109
|
+
constructor(statusCode: number, detail: unknown);
|
|
110
|
+
}
|
|
111
|
+
export interface PounceClientOptions {
|
|
112
|
+
apiKey?: string;
|
|
113
|
+
baseUrl?: string;
|
|
114
|
+
timeout?: number;
|
|
115
|
+
}
|
|
116
|
+
export declare class PounceClient {
|
|
117
|
+
private apiKey;
|
|
118
|
+
private baseUrl;
|
|
119
|
+
private timeout;
|
|
120
|
+
constructor(options?: PounceClientOptions);
|
|
121
|
+
private request;
|
|
122
|
+
/** Search companies with filters (1 credit). */
|
|
123
|
+
search(options?: {
|
|
124
|
+
q?: string;
|
|
125
|
+
country?: string;
|
|
126
|
+
category?: string;
|
|
127
|
+
minTrustTier?: number;
|
|
128
|
+
limit?: number;
|
|
129
|
+
offset?: number;
|
|
130
|
+
}): Promise<ApiResponse<SearchResponse>>;
|
|
131
|
+
/** AI semantic search by natural language (2 credits). */
|
|
132
|
+
semanticSearch(query: string, options?: {
|
|
133
|
+
country?: string;
|
|
134
|
+
limit?: number;
|
|
135
|
+
}): Promise<ApiResponse<SemanticSearchResponse>>;
|
|
136
|
+
/** Look up a company by domain (1 credit). */
|
|
137
|
+
lookup(domain: string): Promise<ApiResponse<EntitySummary>>;
|
|
138
|
+
/** Get full company profile by ID (1 credit). */
|
|
139
|
+
detail(entityId: number): Promise<ApiResponse<EntityDetail>>;
|
|
140
|
+
/** Bulk lookup by domains, max 100 (1 credit per found). */
|
|
141
|
+
bulkLookup(domains: string[]): Promise<ApiResponse<BulkResponse>>;
|
|
142
|
+
/** Compute match score between two companies (3 credits, Business+). */
|
|
143
|
+
matchScore(entityAId: number, entityBId: number): Promise<ApiResponse<MatchScoreResponse>>;
|
|
144
|
+
/** Get public platform statistics (free, no auth). */
|
|
145
|
+
stats(): Promise<ApiResponse<StatsResponse>>;
|
|
146
|
+
}
|
package/dist/index.js
CHANGED
|
@@ -1,244 +1,127 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
};
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
PounceAgentDataClient: () => PounceAgentDataClient,
|
|
24
|
-
PounceClient: () => PounceClient
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(index_exports);
|
|
27
|
-
var PounceAgentDataClient = class {
|
|
28
|
-
apiKey;
|
|
29
|
-
baseUrl;
|
|
30
|
-
constructor(options) {
|
|
31
|
-
this.apiKey = options.apiKey;
|
|
32
|
-
this.baseUrl = (options.baseUrl ?? "https://api.pounce.ch").replace(/\/$/, "");
|
|
33
|
-
if (!this.apiKey.startsWith("pounce_live_")) {
|
|
34
|
-
throw new Error("Invalid API key format (expected pounce_live_...)");
|
|
1
|
+
/**
|
|
2
|
+
* Pounce Agent Data SDK — TypeScript client for the Pounce v2 Entity API.
|
|
3
|
+
*
|
|
4
|
+
* @example
|
|
5
|
+
* ```ts
|
|
6
|
+
* import { PounceClient } from 'pounce-agent-data';
|
|
7
|
+
*
|
|
8
|
+
* const client = new PounceClient({ apiKey: 'your_key' });
|
|
9
|
+
* const { data } = await client.search({ q: 'AI companies', country: 'CH' });
|
|
10
|
+
* data.items.forEach(c => console.log(c.canonical_name, c.primary_domain));
|
|
11
|
+
* ```
|
|
12
|
+
*/
|
|
13
|
+
const API_BASE = 'https://api.pounce.ch';
|
|
14
|
+
const V2_PREFIX = '/api/v1/v2';
|
|
15
|
+
export class PounceError extends Error {
|
|
16
|
+
constructor(statusCode, detail) {
|
|
17
|
+
super(`Pounce API error ${statusCode}: ${JSON.stringify(detail)}`);
|
|
18
|
+
this.statusCode = statusCode;
|
|
19
|
+
this.detail = detail;
|
|
20
|
+
this.name = 'PounceError';
|
|
35
21
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
async getJson(path, params) {
|
|
45
|
-
const url = new URL(this.baseUrl + path);
|
|
46
|
-
if (params) {
|
|
47
|
-
for (const [k, v] of Object.entries(params)) {
|
|
48
|
-
if (v !== void 0) url.searchParams.set(k, String(v));
|
|
49
|
-
}
|
|
22
|
+
}
|
|
23
|
+
export class PounceClient {
|
|
24
|
+
constructor(options = {}) {
|
|
25
|
+
this.apiKey = options.apiKey || process.env.POUNCE_API_KEY || '';
|
|
26
|
+
this.baseUrl = (options.baseUrl || process.env.POUNCE_API_BASE || API_BASE).replace(/\/$/, '');
|
|
27
|
+
this.timeout = options.timeout || 30000;
|
|
50
28
|
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
29
|
+
async request(method, path, options) {
|
|
30
|
+
let url = `${this.baseUrl}${V2_PREFIX}${path}`;
|
|
31
|
+
if (options?.params) {
|
|
32
|
+
const searchParams = new URLSearchParams();
|
|
33
|
+
for (const [key, value] of Object.entries(options.params)) {
|
|
34
|
+
if (value !== undefined && value !== null) {
|
|
35
|
+
searchParams.set(key, String(value));
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
const qs = searchParams.toString();
|
|
39
|
+
if (qs)
|
|
40
|
+
url += `?${qs}`;
|
|
41
|
+
}
|
|
42
|
+
const controller = new AbortController();
|
|
43
|
+
const timeoutId = setTimeout(() => controller.abort(), this.timeout);
|
|
44
|
+
try {
|
|
45
|
+
const response = await fetch(url, {
|
|
46
|
+
method,
|
|
47
|
+
headers: {
|
|
48
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
49
|
+
'Content-Type': 'application/json',
|
|
50
|
+
'User-Agent': 'pounce-agent-data/2.0.0 typescript',
|
|
51
|
+
},
|
|
52
|
+
body: options?.body ? JSON.stringify(options.body) : undefined,
|
|
53
|
+
signal: controller.signal,
|
|
54
|
+
});
|
|
55
|
+
const rateLimit = {
|
|
56
|
+
remaining: parseInt(response.headers.get('x-ratelimit-remaining') || '-1', 10),
|
|
57
|
+
creditsUsed: parseInt(response.headers.get('x-credits-used') || '0', 10),
|
|
58
|
+
};
|
|
59
|
+
if (!response.ok) {
|
|
60
|
+
let detail;
|
|
61
|
+
try {
|
|
62
|
+
detail = await response.json();
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
detail = await response.text();
|
|
66
|
+
}
|
|
67
|
+
throw new PounceError(response.status, detail);
|
|
68
|
+
}
|
|
69
|
+
const data = (await response.json());
|
|
70
|
+
return { data, rateLimit };
|
|
71
|
+
}
|
|
72
|
+
finally {
|
|
73
|
+
clearTimeout(timeoutId);
|
|
74
|
+
}
|
|
62
75
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const rateLimit = this.extractRateLimit(res);
|
|
78
|
-
if (!res.ok) {
|
|
79
|
-
const text = await res.text();
|
|
80
|
-
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
76
|
+
/** Search companies with filters (1 credit). */
|
|
77
|
+
async search(options = {}) {
|
|
78
|
+
const params = {
|
|
79
|
+
limit: options.limit || 25,
|
|
80
|
+
offset: options.offset || 0,
|
|
81
|
+
min_trust_tier: options.minTrustTier || 3,
|
|
82
|
+
};
|
|
83
|
+
if (options.q)
|
|
84
|
+
params.q = options.q;
|
|
85
|
+
if (options.country)
|
|
86
|
+
params.country = options.country.toUpperCase();
|
|
87
|
+
if (options.category)
|
|
88
|
+
params.category = options.category;
|
|
89
|
+
return this.request('GET', '/entities/search', { params });
|
|
81
90
|
}
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
async recentSignals(options = {}) {
|
|
92
|
-
const { hours = 24, limit = 100, minScore = 50, category, country, tlds } = options;
|
|
93
|
-
return this.getJson("/api/v1/agent-data/signals/recent", {
|
|
94
|
-
hours,
|
|
95
|
-
limit,
|
|
96
|
-
min_score: minScore,
|
|
97
|
-
category,
|
|
98
|
-
country,
|
|
99
|
-
tlds: tlds?.join(",")
|
|
100
|
-
});
|
|
101
|
-
}
|
|
102
|
-
/**
|
|
103
|
-
* Semantic search for signals using natural language.
|
|
104
|
-
*
|
|
105
|
-
* @param query - Natural language search query
|
|
106
|
-
* @param options - Search options
|
|
107
|
-
*
|
|
108
|
-
* @example
|
|
109
|
-
* ```typescript
|
|
110
|
-
* const { json } = await client.search('AI startups in healthcare', { limit: 10 });
|
|
111
|
-
* for (const item of json.items) {
|
|
112
|
-
* console.log(`${item.domain}: similarity=${item.similarity.toFixed(2)}`);
|
|
113
|
-
* }
|
|
114
|
-
* ```
|
|
115
|
-
*/
|
|
116
|
-
async search(query, options = {}) {
|
|
117
|
-
const { limit = 20, minScore = 50, category, country, tlds } = options;
|
|
118
|
-
const body = {
|
|
119
|
-
query,
|
|
120
|
-
limit,
|
|
121
|
-
min_score: minScore
|
|
122
|
-
};
|
|
123
|
-
const filters = {};
|
|
124
|
-
if (category) filters.category = category;
|
|
125
|
-
if (country) filters.country = country;
|
|
126
|
-
if (tlds) filters.tlds = tlds;
|
|
127
|
-
if (Object.keys(filters).length > 0) body.filters = filters;
|
|
128
|
-
return this.postJson(
|
|
129
|
-
"/api/v1/agent-data/search/semantic",
|
|
130
|
-
body
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
/**
|
|
134
|
-
* Get full details for a specific signal.
|
|
135
|
-
*/
|
|
136
|
-
async signalDetail(signalId) {
|
|
137
|
-
return this.getJson(
|
|
138
|
-
`/api/v1/agent-data/signals/${encodeURIComponent(signalId)}`
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
/**
|
|
142
|
-
* Get API usage information for your account.
|
|
143
|
-
*/
|
|
144
|
-
async usage() {
|
|
145
|
-
return this.getJson("/api/v1/agent-data/usage");
|
|
146
|
-
}
|
|
147
|
-
/**
|
|
148
|
-
* Stream new signals in real-time via SSE.
|
|
149
|
-
*
|
|
150
|
-
* @param options - Stream options
|
|
151
|
-
*
|
|
152
|
-
* @example
|
|
153
|
-
* ```typescript
|
|
154
|
-
* for await (const signal of client.stream({ minScore: 70 })) {
|
|
155
|
-
* console.log(`New signal: ${signal.domain} (score=${signal.signalScore})`);
|
|
156
|
-
* }
|
|
157
|
-
* ```
|
|
158
|
-
*
|
|
159
|
-
* @note This is an async generator. Make sure to handle connection errors and reconnect if needed.
|
|
160
|
-
*/
|
|
161
|
-
async *stream(options = {}) {
|
|
162
|
-
const { minScore = 50, category, since } = options;
|
|
163
|
-
const url = new URL(`${this.baseUrl}/api/v1/agent-data/streams/signals`);
|
|
164
|
-
url.searchParams.set("min_score", String(minScore));
|
|
165
|
-
if (category) url.searchParams.set("category", category);
|
|
166
|
-
if (since) url.searchParams.set("since", since);
|
|
167
|
-
const res = await fetch(url.toString(), {
|
|
168
|
-
method: "GET",
|
|
169
|
-
headers: {
|
|
170
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
171
|
-
Accept: "text/event-stream"
|
|
172
|
-
}
|
|
173
|
-
});
|
|
174
|
-
if (!res.ok) {
|
|
175
|
-
const text = await res.text();
|
|
176
|
-
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
91
|
+
/** AI semantic search by natural language (2 credits). */
|
|
92
|
+
async semanticSearch(query, options) {
|
|
93
|
+
return this.request('POST', '/entities/search/semantic', {
|
|
94
|
+
body: {
|
|
95
|
+
query,
|
|
96
|
+
country: options?.country?.toUpperCase(),
|
|
97
|
+
limit: options?.limit || 25,
|
|
98
|
+
},
|
|
99
|
+
});
|
|
177
100
|
}
|
|
178
|
-
|
|
179
|
-
|
|
101
|
+
/** Look up a company by domain (1 credit). */
|
|
102
|
+
async lookup(domain) {
|
|
103
|
+
return this.request('GET', '/entities/lookup', {
|
|
104
|
+
params: { domain },
|
|
105
|
+
});
|
|
180
106
|
}
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
yield this.parseSignal(parsed);
|
|
201
|
-
} catch {
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
eventType = null;
|
|
205
|
-
dataBuffer = [];
|
|
206
|
-
continue;
|
|
207
|
-
}
|
|
208
|
-
if (trimmed.startsWith(":")) {
|
|
209
|
-
continue;
|
|
210
|
-
}
|
|
211
|
-
if (trimmed.startsWith("event:")) {
|
|
212
|
-
eventType = trimmed.slice(6).trim();
|
|
213
|
-
} else if (trimmed.startsWith("data:")) {
|
|
214
|
-
dataBuffer.push(trimmed.slice(5).trim());
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
} finally {
|
|
219
|
-
reader.releaseLock();
|
|
107
|
+
/** Get full company profile by ID (1 credit). */
|
|
108
|
+
async detail(entityId) {
|
|
109
|
+
return this.request('GET', `/entities/${entityId}`);
|
|
110
|
+
}
|
|
111
|
+
/** Bulk lookup by domains, max 100 (1 credit per found). */
|
|
112
|
+
async bulkLookup(domains) {
|
|
113
|
+
return this.request('POST', '/entities/bulk', {
|
|
114
|
+
body: { domains: domains.slice(0, 100) },
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
/** Compute match score between two companies (3 credits, Business+). */
|
|
118
|
+
async matchScore(entityAId, entityBId) {
|
|
119
|
+
return this.request('POST', '/matching/score', {
|
|
120
|
+
body: { entity_a_id: entityAId, entity_b_id: entityBId },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
/** Get public platform statistics (free, no auth). */
|
|
124
|
+
async stats() {
|
|
125
|
+
return this.request('GET', '/stats');
|
|
220
126
|
}
|
|
221
|
-
|
|
222
|
-
parseSignal(raw) {
|
|
223
|
-
return {
|
|
224
|
-
signalId: raw.signal_id ?? String(raw.id),
|
|
225
|
-
domain: raw.domain,
|
|
226
|
-
companyName: raw.title,
|
|
227
|
-
category: raw.category,
|
|
228
|
-
subcategory: raw.subcategory,
|
|
229
|
-
signalScore: raw.signal_score,
|
|
230
|
-
intentTags: raw.intent_tags,
|
|
231
|
-
techStack: raw.tech_stack,
|
|
232
|
-
country: raw.country,
|
|
233
|
-
description: raw.description,
|
|
234
|
-
detectedAt: raw.discovered_at ?? raw.scanned_at,
|
|
235
|
-
uiUrl: raw.ui_url
|
|
236
|
-
};
|
|
237
|
-
}
|
|
238
|
-
};
|
|
239
|
-
var PounceClient = PounceAgentDataClient;
|
|
240
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
241
|
-
0 && (module.exports = {
|
|
242
|
-
PounceAgentDataClient,
|
|
243
|
-
PounceClient
|
|
244
|
-
});
|
|
127
|
+
}
|
package/package.json
CHANGED
|
@@ -1,46 +1,37 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pounce-agent-data",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "TypeScript SDK for the Pounce
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "TypeScript SDK for the Pounce v2 Entity API — search, look up, and enrich 59M+ verified B2B companies.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
|
-
"module": "dist/index.mjs",
|
|
7
6
|
"types": "dist/index.d.ts",
|
|
8
|
-
"exports": {
|
|
9
|
-
".": {
|
|
10
|
-
"import": "./dist/index.mjs",
|
|
11
|
-
"require": "./dist/index.js",
|
|
12
|
-
"types": "./dist/index.d.ts"
|
|
13
|
-
}
|
|
14
|
-
},
|
|
15
7
|
"files": [
|
|
16
8
|
"dist"
|
|
17
9
|
],
|
|
18
10
|
"scripts": {
|
|
19
|
-
"build": "
|
|
11
|
+
"build": "tsc",
|
|
20
12
|
"prepublishOnly": "npm run build"
|
|
21
13
|
},
|
|
22
14
|
"keywords": [
|
|
23
15
|
"pounce",
|
|
24
16
|
"b2b",
|
|
25
|
-
"
|
|
26
|
-
"ai",
|
|
27
|
-
"agents",
|
|
17
|
+
"companies",
|
|
28
18
|
"api",
|
|
29
|
-
"sdk"
|
|
19
|
+
"sdk",
|
|
20
|
+
"ai",
|
|
21
|
+
"agents"
|
|
30
22
|
],
|
|
31
|
-
"author": "Pounce
|
|
23
|
+
"author": "Pounce",
|
|
32
24
|
"license": "MIT",
|
|
33
|
-
"repository": {
|
|
34
|
-
"type": "git",
|
|
35
|
-
"url": "https://gitlab.pounce.ch/pounce/pounce.git",
|
|
36
|
-
"directory": "sdk/ts"
|
|
37
|
-
},
|
|
38
|
-
"homepage": "https://pounce.ch/developers",
|
|
39
25
|
"devDependencies": {
|
|
40
|
-
"
|
|
26
|
+
"@types/node": "^25.3.0",
|
|
41
27
|
"typescript": "^5.0.0"
|
|
42
28
|
},
|
|
43
29
|
"engines": {
|
|
44
30
|
"node": ">=18.0.0"
|
|
45
|
-
}
|
|
31
|
+
},
|
|
32
|
+
"repository": {
|
|
33
|
+
"type": "git",
|
|
34
|
+
"url": "https://gitlab.pounce.ch/pounce/pounce.git"
|
|
35
|
+
},
|
|
36
|
+
"homepage": "https://pounce.ch/developers"
|
|
46
37
|
}
|
package/README.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Pounce Agent Data SDK
|
|
2
|
-
|
|
3
|
-
TypeScript SDK for the [Pounce Agent Data API](https://pounce.ch/developers) - Connect your AI agents to 500k+ B2B company signals.
|
|
4
|
-
|
|
5
|
-
## Installation
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
npm install pounce-agent-data
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Quick Start
|
|
12
|
-
|
|
13
|
-
```typescript
|
|
14
|
-
import { PounceClient } from 'pounce-agent-data';
|
|
15
|
-
|
|
16
|
-
const client = new PounceClient({ apiKey: 'pounce_live_xxx' });
|
|
17
|
-
|
|
18
|
-
// Recent signals
|
|
19
|
-
const { json } = await client.recentSignals({ limit: 10, category: 'saas' });
|
|
20
|
-
for (const item of json.items) {
|
|
21
|
-
console.log(`${item.domain}: ${item.signal_score}`);
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Semantic search
|
|
25
|
-
const results = await client.search('AI startups in healthcare', { limit: 20 });
|
|
26
|
-
for (const item of results.json.items) {
|
|
27
|
-
console.log(`${item.domain}: similarity=${item.similarity.toFixed(2)}`);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
// Stream new signals (real-time)
|
|
31
|
-
for await (const signal of client.stream({ minScore: 70 })) {
|
|
32
|
-
console.log(`New: ${signal.domain} (score=${signal.signalScore})`);
|
|
33
|
-
}
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## API Key
|
|
37
|
-
|
|
38
|
-
Get your API key:
|
|
39
|
-
1. Sign up at [pounce.ch](https://pounce.ch)
|
|
40
|
-
2. Subscribe to Pro ($49/month) or Business ($149/month)
|
|
41
|
-
3. Generate API key in **Settings → API Access**
|
|
42
|
-
|
|
43
|
-
## Rate Limits
|
|
44
|
-
|
|
45
|
-
| Tier | Requests/month |
|
|
46
|
-
|------|----------------|
|
|
47
|
-
| Pro | 1,000 |
|
|
48
|
-
| Business | 10,000 |
|
|
49
|
-
|
|
50
|
-
## Documentation
|
|
51
|
-
|
|
52
|
-
- [API Documentation](https://pounce.ch/developers)
|
|
53
|
-
- [Skill File](https://pounce.ch/skill.md)
|
|
54
|
-
- [API Reference](https://api.pounce.ch/docs#/agent-data)
|
|
55
|
-
|
|
56
|
-
## Support
|
|
57
|
-
|
|
58
|
-
- Email: hello@pounce.ch
|
|
59
|
-
|
|
60
|
-
## License
|
|
61
|
-
|
|
62
|
-
MIT
|
package/dist/index.d.mts
DELETED
|
@@ -1,204 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Pounce Agent Data SDK - TypeScript Client
|
|
3
|
-
*
|
|
4
|
-
* Minimal client for the Pounce Agent Data API.
|
|
5
|
-
* Supports recent signals, semantic search, signal details, and SSE streaming.
|
|
6
|
-
*
|
|
7
|
-
* @example
|
|
8
|
-
* ```typescript
|
|
9
|
-
* import { PounceAgentDataClient } from '@pounce/agent-data';
|
|
10
|
-
*
|
|
11
|
-
* const client = new PounceAgentDataClient({ apiKey: 'pounce_live_xxx' });
|
|
12
|
-
*
|
|
13
|
-
* // Recent signals
|
|
14
|
-
* const { json, rateLimit } = await client.recentSignals({ limit: 10, category: 'saas' });
|
|
15
|
-
*
|
|
16
|
-
* // Semantic search
|
|
17
|
-
* const results = await client.search('AI companies in healthcare', { limit: 20 });
|
|
18
|
-
*
|
|
19
|
-
* // Stream new signals
|
|
20
|
-
* for await (const signal of client.stream({ minScore: 70 })) {
|
|
21
|
-
* console.log(signal);
|
|
22
|
-
* }
|
|
23
|
-
* ```
|
|
24
|
-
*/
|
|
25
|
-
type RateLimitInfo = {
|
|
26
|
-
limit?: number;
|
|
27
|
-
remaining?: number;
|
|
28
|
-
resetUnix?: number;
|
|
29
|
-
};
|
|
30
|
-
type Signal = {
|
|
31
|
-
signalId: string;
|
|
32
|
-
domain: string;
|
|
33
|
-
companyName?: string | null;
|
|
34
|
-
category?: string | null;
|
|
35
|
-
subcategory?: string | null;
|
|
36
|
-
signalScore: number;
|
|
37
|
-
trustScore?: number | null;
|
|
38
|
-
intentTags?: string[] | null;
|
|
39
|
-
techStack?: string[] | null;
|
|
40
|
-
country?: string | null;
|
|
41
|
-
description?: string | null;
|
|
42
|
-
detectedAt?: string | null;
|
|
43
|
-
uiUrl?: string | null;
|
|
44
|
-
};
|
|
45
|
-
type AgentDataRecentSignal = {
|
|
46
|
-
id: number;
|
|
47
|
-
signal_id?: string;
|
|
48
|
-
domain: string;
|
|
49
|
-
tld: string;
|
|
50
|
-
title?: string | null;
|
|
51
|
-
description?: string | null;
|
|
52
|
-
h1?: string | null;
|
|
53
|
-
category?: string | null;
|
|
54
|
-
subcategory?: string | null;
|
|
55
|
-
business_type?: string | null;
|
|
56
|
-
signal_score: number;
|
|
57
|
-
signal_grade?: string | null;
|
|
58
|
-
tech_stack?: string[] | null;
|
|
59
|
-
intent_tags?: string[] | null;
|
|
60
|
-
hosting_provider?: string | null;
|
|
61
|
-
country?: string | null;
|
|
62
|
-
has_real_content: boolean;
|
|
63
|
-
scanned_at?: string | null;
|
|
64
|
-
discovered_at: string;
|
|
65
|
-
ui_url?: string | null;
|
|
66
|
-
};
|
|
67
|
-
type RecentSignalsResponse = {
|
|
68
|
-
items: AgentDataRecentSignal[];
|
|
69
|
-
count: number;
|
|
70
|
-
has_more?: boolean;
|
|
71
|
-
};
|
|
72
|
-
type SemanticSearchItem = {
|
|
73
|
-
signal_id: string;
|
|
74
|
-
domain: string;
|
|
75
|
-
company_name?: string | null;
|
|
76
|
-
category?: string | null;
|
|
77
|
-
signal_score: number;
|
|
78
|
-
similarity: number;
|
|
79
|
-
snippet?: string | null;
|
|
80
|
-
intent_tags?: string[] | null;
|
|
81
|
-
country?: string | null;
|
|
82
|
-
ui_url?: string | null;
|
|
83
|
-
};
|
|
84
|
-
type SemanticSearchResponse = {
|
|
85
|
-
items: SemanticSearchItem[];
|
|
86
|
-
count: number;
|
|
87
|
-
query_tokens?: number;
|
|
88
|
-
};
|
|
89
|
-
type SignalDetailResponse = {
|
|
90
|
-
signal_id: string;
|
|
91
|
-
domain: string;
|
|
92
|
-
company_name?: string | null;
|
|
93
|
-
category?: string | null;
|
|
94
|
-
subcategory?: string | null;
|
|
95
|
-
signal_score: number;
|
|
96
|
-
trust_score?: number | null;
|
|
97
|
-
intent_tags?: string[] | null;
|
|
98
|
-
tech_stack?: string[] | null;
|
|
99
|
-
country?: string | null;
|
|
100
|
-
description?: string | null;
|
|
101
|
-
social_links?: Record<string, string> | null;
|
|
102
|
-
detected_at?: string | null;
|
|
103
|
-
ui_url?: string | null;
|
|
104
|
-
};
|
|
105
|
-
type AgentDataUsageResponse = {
|
|
106
|
-
api_key_prefix: string;
|
|
107
|
-
usage: {
|
|
108
|
-
period_start: string;
|
|
109
|
-
period_end: string;
|
|
110
|
-
used: number;
|
|
111
|
-
limit: number;
|
|
112
|
-
remaining: number;
|
|
113
|
-
reset_at: string;
|
|
114
|
-
};
|
|
115
|
-
};
|
|
116
|
-
type RecentSignalsOptions = {
|
|
117
|
-
hours?: number;
|
|
118
|
-
limit?: number;
|
|
119
|
-
minScore?: number;
|
|
120
|
-
category?: string;
|
|
121
|
-
country?: string;
|
|
122
|
-
tlds?: string[];
|
|
123
|
-
};
|
|
124
|
-
type SemanticSearchOptions = {
|
|
125
|
-
limit?: number;
|
|
126
|
-
minScore?: number;
|
|
127
|
-
category?: string;
|
|
128
|
-
country?: string;
|
|
129
|
-
tlds?: string[];
|
|
130
|
-
};
|
|
131
|
-
type StreamOptions = {
|
|
132
|
-
minScore?: number;
|
|
133
|
-
category?: string;
|
|
134
|
-
since?: string;
|
|
135
|
-
};
|
|
136
|
-
declare class PounceAgentDataClient {
|
|
137
|
-
private readonly apiKey;
|
|
138
|
-
private readonly baseUrl;
|
|
139
|
-
constructor(options: {
|
|
140
|
-
apiKey: string;
|
|
141
|
-
baseUrl?: string;
|
|
142
|
-
});
|
|
143
|
-
private extractRateLimit;
|
|
144
|
-
private getJson;
|
|
145
|
-
private postJson;
|
|
146
|
-
/**
|
|
147
|
-
* Get recent B2B signals.
|
|
148
|
-
*/
|
|
149
|
-
recentSignals(options?: RecentSignalsOptions): Promise<{
|
|
150
|
-
json: RecentSignalsResponse;
|
|
151
|
-
rateLimit: RateLimitInfo;
|
|
152
|
-
}>;
|
|
153
|
-
/**
|
|
154
|
-
* Semantic search for signals using natural language.
|
|
155
|
-
*
|
|
156
|
-
* @param query - Natural language search query
|
|
157
|
-
* @param options - Search options
|
|
158
|
-
*
|
|
159
|
-
* @example
|
|
160
|
-
* ```typescript
|
|
161
|
-
* const { json } = await client.search('AI startups in healthcare', { limit: 10 });
|
|
162
|
-
* for (const item of json.items) {
|
|
163
|
-
* console.log(`${item.domain}: similarity=${item.similarity.toFixed(2)}`);
|
|
164
|
-
* }
|
|
165
|
-
* ```
|
|
166
|
-
*/
|
|
167
|
-
search(query: string, options?: SemanticSearchOptions): Promise<{
|
|
168
|
-
json: SemanticSearchResponse;
|
|
169
|
-
rateLimit: RateLimitInfo;
|
|
170
|
-
}>;
|
|
171
|
-
/**
|
|
172
|
-
* Get full details for a specific signal.
|
|
173
|
-
*/
|
|
174
|
-
signalDetail(signalId: string): Promise<{
|
|
175
|
-
json: SignalDetailResponse;
|
|
176
|
-
rateLimit: RateLimitInfo;
|
|
177
|
-
}>;
|
|
178
|
-
/**
|
|
179
|
-
* Get API usage information for your account.
|
|
180
|
-
*/
|
|
181
|
-
usage(): Promise<{
|
|
182
|
-
json: AgentDataUsageResponse;
|
|
183
|
-
rateLimit: RateLimitInfo;
|
|
184
|
-
}>;
|
|
185
|
-
/**
|
|
186
|
-
* Stream new signals in real-time via SSE.
|
|
187
|
-
*
|
|
188
|
-
* @param options - Stream options
|
|
189
|
-
*
|
|
190
|
-
* @example
|
|
191
|
-
* ```typescript
|
|
192
|
-
* for await (const signal of client.stream({ minScore: 70 })) {
|
|
193
|
-
* console.log(`New signal: ${signal.domain} (score=${signal.signalScore})`);
|
|
194
|
-
* }
|
|
195
|
-
* ```
|
|
196
|
-
*
|
|
197
|
-
* @note This is an async generator. Make sure to handle connection errors and reconnect if needed.
|
|
198
|
-
*/
|
|
199
|
-
stream(options?: StreamOptions): AsyncGenerator<Signal, void, unknown>;
|
|
200
|
-
private parseSignal;
|
|
201
|
-
}
|
|
202
|
-
declare const PounceClient: typeof PounceAgentDataClient;
|
|
203
|
-
|
|
204
|
-
export { type AgentDataRecentSignal, type AgentDataUsageResponse, PounceAgentDataClient, PounceClient, type RateLimitInfo, type RecentSignalsOptions, type RecentSignalsResponse, type SemanticSearchItem, type SemanticSearchOptions, type SemanticSearchResponse, type Signal, type SignalDetailResponse, type StreamOptions };
|
package/dist/index.mjs
DELETED
|
@@ -1,218 +0,0 @@
|
|
|
1
|
-
// src/index.ts
|
|
2
|
-
var PounceAgentDataClient = class {
|
|
3
|
-
apiKey;
|
|
4
|
-
baseUrl;
|
|
5
|
-
constructor(options) {
|
|
6
|
-
this.apiKey = options.apiKey;
|
|
7
|
-
this.baseUrl = (options.baseUrl ?? "https://api.pounce.ch").replace(/\/$/, "");
|
|
8
|
-
if (!this.apiKey.startsWith("pounce_live_")) {
|
|
9
|
-
throw new Error("Invalid API key format (expected pounce_live_...)");
|
|
10
|
-
}
|
|
11
|
-
}
|
|
12
|
-
extractRateLimit(res) {
|
|
13
|
-
return {
|
|
14
|
-
limit: res.headers.get("X-RateLimit-Limit") ? Number(res.headers.get("X-RateLimit-Limit")) : void 0,
|
|
15
|
-
remaining: res.headers.get("X-RateLimit-Remaining") ? Number(res.headers.get("X-RateLimit-Remaining")) : void 0,
|
|
16
|
-
resetUnix: res.headers.get("X-RateLimit-Reset") ? Number(res.headers.get("X-RateLimit-Reset")) : void 0
|
|
17
|
-
};
|
|
18
|
-
}
|
|
19
|
-
async getJson(path, params) {
|
|
20
|
-
const url = new URL(this.baseUrl + path);
|
|
21
|
-
if (params) {
|
|
22
|
-
for (const [k, v] of Object.entries(params)) {
|
|
23
|
-
if (v !== void 0) url.searchParams.set(k, String(v));
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
const res = await fetch(url.toString(), {
|
|
27
|
-
method: "GET",
|
|
28
|
-
headers: {
|
|
29
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
30
|
-
Accept: "application/json"
|
|
31
|
-
}
|
|
32
|
-
});
|
|
33
|
-
const rateLimit = this.extractRateLimit(res);
|
|
34
|
-
if (!res.ok) {
|
|
35
|
-
const text = await res.text();
|
|
36
|
-
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
37
|
-
}
|
|
38
|
-
const json = await res.json();
|
|
39
|
-
return { json, rateLimit };
|
|
40
|
-
}
|
|
41
|
-
async postJson(path, body) {
|
|
42
|
-
const url = new URL(this.baseUrl + path);
|
|
43
|
-
const res = await fetch(url.toString(), {
|
|
44
|
-
method: "POST",
|
|
45
|
-
headers: {
|
|
46
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
47
|
-
Accept: "application/json",
|
|
48
|
-
"Content-Type": "application/json"
|
|
49
|
-
},
|
|
50
|
-
body: JSON.stringify(body)
|
|
51
|
-
});
|
|
52
|
-
const rateLimit = this.extractRateLimit(res);
|
|
53
|
-
if (!res.ok) {
|
|
54
|
-
const text = await res.text();
|
|
55
|
-
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
56
|
-
}
|
|
57
|
-
const json = await res.json();
|
|
58
|
-
return { json, rateLimit };
|
|
59
|
-
}
|
|
60
|
-
// ---------------------------------------------------------------------------
|
|
61
|
-
// Public API Methods
|
|
62
|
-
// ---------------------------------------------------------------------------
|
|
63
|
-
/**
|
|
64
|
-
* Get recent B2B signals.
|
|
65
|
-
*/
|
|
66
|
-
async recentSignals(options = {}) {
|
|
67
|
-
const { hours = 24, limit = 100, minScore = 50, category, country, tlds } = options;
|
|
68
|
-
return this.getJson("/api/v1/agent-data/signals/recent", {
|
|
69
|
-
hours,
|
|
70
|
-
limit,
|
|
71
|
-
min_score: minScore,
|
|
72
|
-
category,
|
|
73
|
-
country,
|
|
74
|
-
tlds: tlds?.join(",")
|
|
75
|
-
});
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Semantic search for signals using natural language.
|
|
79
|
-
*
|
|
80
|
-
* @param query - Natural language search query
|
|
81
|
-
* @param options - Search options
|
|
82
|
-
*
|
|
83
|
-
* @example
|
|
84
|
-
* ```typescript
|
|
85
|
-
* const { json } = await client.search('AI startups in healthcare', { limit: 10 });
|
|
86
|
-
* for (const item of json.items) {
|
|
87
|
-
* console.log(`${item.domain}: similarity=${item.similarity.toFixed(2)}`);
|
|
88
|
-
* }
|
|
89
|
-
* ```
|
|
90
|
-
*/
|
|
91
|
-
async search(query, options = {}) {
|
|
92
|
-
const { limit = 20, minScore = 50, category, country, tlds } = options;
|
|
93
|
-
const body = {
|
|
94
|
-
query,
|
|
95
|
-
limit,
|
|
96
|
-
min_score: minScore
|
|
97
|
-
};
|
|
98
|
-
const filters = {};
|
|
99
|
-
if (category) filters.category = category;
|
|
100
|
-
if (country) filters.country = country;
|
|
101
|
-
if (tlds) filters.tlds = tlds;
|
|
102
|
-
if (Object.keys(filters).length > 0) body.filters = filters;
|
|
103
|
-
return this.postJson(
|
|
104
|
-
"/api/v1/agent-data/search/semantic",
|
|
105
|
-
body
|
|
106
|
-
);
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Get full details for a specific signal.
|
|
110
|
-
*/
|
|
111
|
-
async signalDetail(signalId) {
|
|
112
|
-
return this.getJson(
|
|
113
|
-
`/api/v1/agent-data/signals/${encodeURIComponent(signalId)}`
|
|
114
|
-
);
|
|
115
|
-
}
|
|
116
|
-
/**
|
|
117
|
-
* Get API usage information for your account.
|
|
118
|
-
*/
|
|
119
|
-
async usage() {
|
|
120
|
-
return this.getJson("/api/v1/agent-data/usage");
|
|
121
|
-
}
|
|
122
|
-
/**
|
|
123
|
-
* Stream new signals in real-time via SSE.
|
|
124
|
-
*
|
|
125
|
-
* @param options - Stream options
|
|
126
|
-
*
|
|
127
|
-
* @example
|
|
128
|
-
* ```typescript
|
|
129
|
-
* for await (const signal of client.stream({ minScore: 70 })) {
|
|
130
|
-
* console.log(`New signal: ${signal.domain} (score=${signal.signalScore})`);
|
|
131
|
-
* }
|
|
132
|
-
* ```
|
|
133
|
-
*
|
|
134
|
-
* @note This is an async generator. Make sure to handle connection errors and reconnect if needed.
|
|
135
|
-
*/
|
|
136
|
-
async *stream(options = {}) {
|
|
137
|
-
const { minScore = 50, category, since } = options;
|
|
138
|
-
const url = new URL(`${this.baseUrl}/api/v1/agent-data/streams/signals`);
|
|
139
|
-
url.searchParams.set("min_score", String(minScore));
|
|
140
|
-
if (category) url.searchParams.set("category", category);
|
|
141
|
-
if (since) url.searchParams.set("since", since);
|
|
142
|
-
const res = await fetch(url.toString(), {
|
|
143
|
-
method: "GET",
|
|
144
|
-
headers: {
|
|
145
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
146
|
-
Accept: "text/event-stream"
|
|
147
|
-
}
|
|
148
|
-
});
|
|
149
|
-
if (!res.ok) {
|
|
150
|
-
const text = await res.text();
|
|
151
|
-
throw new Error(`HTTP ${res.status}: ${text}`);
|
|
152
|
-
}
|
|
153
|
-
if (!res.body) {
|
|
154
|
-
throw new Error("Response body is null");
|
|
155
|
-
}
|
|
156
|
-
const reader = res.body.getReader();
|
|
157
|
-
const decoder = new TextDecoder();
|
|
158
|
-
let buffer = "";
|
|
159
|
-
let eventType = null;
|
|
160
|
-
let dataBuffer = [];
|
|
161
|
-
try {
|
|
162
|
-
while (true) {
|
|
163
|
-
const { done, value } = await reader.read();
|
|
164
|
-
if (done) break;
|
|
165
|
-
buffer += decoder.decode(value, { stream: true });
|
|
166
|
-
const lines = buffer.split("\n");
|
|
167
|
-
buffer = lines.pop() ?? "";
|
|
168
|
-
for (const line of lines) {
|
|
169
|
-
const trimmed = line.replace(/\r$/, "");
|
|
170
|
-
if (!trimmed) {
|
|
171
|
-
if (eventType === "signal" && dataBuffer.length > 0) {
|
|
172
|
-
try {
|
|
173
|
-
const rawData = dataBuffer.join("\n");
|
|
174
|
-
const parsed = JSON.parse(rawData);
|
|
175
|
-
yield this.parseSignal(parsed);
|
|
176
|
-
} catch {
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
eventType = null;
|
|
180
|
-
dataBuffer = [];
|
|
181
|
-
continue;
|
|
182
|
-
}
|
|
183
|
-
if (trimmed.startsWith(":")) {
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
if (trimmed.startsWith("event:")) {
|
|
187
|
-
eventType = trimmed.slice(6).trim();
|
|
188
|
-
} else if (trimmed.startsWith("data:")) {
|
|
189
|
-
dataBuffer.push(trimmed.slice(5).trim());
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
} finally {
|
|
194
|
-
reader.releaseLock();
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
parseSignal(raw) {
|
|
198
|
-
return {
|
|
199
|
-
signalId: raw.signal_id ?? String(raw.id),
|
|
200
|
-
domain: raw.domain,
|
|
201
|
-
companyName: raw.title,
|
|
202
|
-
category: raw.category,
|
|
203
|
-
subcategory: raw.subcategory,
|
|
204
|
-
signalScore: raw.signal_score,
|
|
205
|
-
intentTags: raw.intent_tags,
|
|
206
|
-
techStack: raw.tech_stack,
|
|
207
|
-
country: raw.country,
|
|
208
|
-
description: raw.description,
|
|
209
|
-
detectedAt: raw.discovered_at ?? raw.scanned_at,
|
|
210
|
-
uiUrl: raw.ui_url
|
|
211
|
-
};
|
|
212
|
-
}
|
|
213
|
-
};
|
|
214
|
-
var PounceClient = PounceAgentDataClient;
|
|
215
|
-
export {
|
|
216
|
-
PounceAgentDataClient,
|
|
217
|
-
PounceClient
|
|
218
|
-
};
|