serpkite 0.5.0 → 0.7.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.cts CHANGED
@@ -166,6 +166,13 @@ interface paths {
166
166
  * (or `uule`) searches the named place. Without either, Google picks the area from the
167
167
  * query (an exact name or address) or from where the request comes from, so local queries
168
168
  * such as "coffee" need `location` or `ll`.
169
+ *
170
+ * **Yandex Maps:** with `engine=yandex` (where the deployment enables it) the results come
171
+ * from Yandex Maps, which covers Russia and the CIS in depth. They have the same fields,
172
+ * with the Yandex organisation id in `oid` (for `/v1/place`) and `yandex_maps_url` instead
173
+ * of Google's identifiers; categories, addresses and hours follow `language` (`ru` for
174
+ * Russian). Pass `ll` or a `location` (a city, appended to the query); `uule` and `tbs`
175
+ * are refused.
169
176
  */
170
177
  post: operations["maps"];
171
178
  delete?: never;
@@ -204,11 +211,16 @@ interface paths {
204
211
  get?: never;
205
212
  put?: never;
206
213
  /**
207
- * Details of one place (by `place_id`, `cid` or `fid`); 1 credit
214
+ * Details of one place (by `place_id`, `cid`, `fid` or Yandex `oid`); 1 credit
208
215
  * @description The full Google Maps listing of one place: address, country, coordinates, time zone,
209
216
  * categories, opening hours (as text and as structured `weekly_hours`), website, phone,
210
217
  * rating, description and photos, in `language`. `results` holds the place, or is empty
211
218
  * (not charged) when no place has that identifier.
219
+ *
220
+ * With `oid` (a Yandex Maps organisation id, e.g. from an `engine=yandex` maps result or
221
+ * `yandex.ru/maps/org/<name>/<oid>/`) the listing comes from Yandex Maps, where the
222
+ * deployment enables it: `oid` implies `engine=yandex` and can't be combined with Google's
223
+ * identifiers. Closed listings (temporarily or permanently) carry no hours.
212
224
  */
213
225
  post: operations["place"];
214
226
  delete?: never;
@@ -329,10 +341,19 @@ interface paths {
329
341
  get?: never;
330
342
  put?: never;
331
343
  /**
332
- * Up to 20 URLs (HTML or PDF) as Markdown, text or HTML, with query-ranked highlights, links and images (1 credit per URL read)
344
+ * Up to 20 URLs (HTML or PDF) as Markdown, text or HTML, with query-ranked highlights, links, images, an AI summary or JSON extracted with a schema (1 credit per URL read)
333
345
  * @description Every URL is billed only when it comes back: 1 credit, 0.5 from cache. URLs that
334
346
  * fail are listed in `failed` and cost nothing. The response is `200` even when every
335
347
  * URL failed. Highlights are ranked with BM25 (lexical, no model).
348
+ *
349
+ * **AI:** `summary: true` adds a 3–6 sentence summary of each page (+4 credits per
350
+ * page); `output_schema` (a JSON Schema, at most 16 KB, optionally guided by
351
+ * `prompt`) returns each page's data as JSON in `output` (+4 credits per page).
352
+ * Claude Haiku writes both; a schema whose fields are all booleans or enums is
353
+ * answered by a decision model instead (always valid against the schema). A
354
+ * summary or extraction that fails is reported in `summary_error` /
355
+ * `output_error` and not charged. With either, `timeout` defaults to 75 seconds
356
+ * and the last 25 are kept for the model.
336
357
  */
337
358
  post: operations["extract"];
338
359
  delete?: never;
@@ -425,6 +446,106 @@ interface paths {
425
446
  patch?: never;
426
447
  trace?: never;
427
448
  };
449
+ "/v1/answer": {
450
+ parameters: {
451
+ query?: never;
452
+ header?: never;
453
+ path?: never;
454
+ cookie?: never;
455
+ };
456
+ get?: never;
457
+ put?: never;
458
+ /**
459
+ * A cited answer grounded on live Google results, written by Claude (fast = 1 + 2 credits; standard = 1 + 1 per page read + 4)
460
+ * @description Runs the query on Google, then Claude (Haiku by default) writes a concise answer
461
+ * that cites the numbered `results` with `[n]` markers. `depth=fast` answers from
462
+ * the result page (snippets, answer box, knowledge panel); `depth=standard`
463
+ * (default) also reads the top `num_sources` pages and answers from their
464
+ * query-ranked passages. Sources are untrusted: instructions inside pages are
465
+ * ignored.
466
+ *
467
+ * **Billing:** the search part is priced like `/v1/search` with `include_content`
468
+ * (1 credit + 1 per page read, cache rules as usual); the model adds 2 credits at
469
+ * `fast` and 4 when it read pages (`standard`; 2 if no page could be read).
470
+ * `meta.credits` splits the two. When the model fails the answer part is refunded
471
+ * (`503 ai_unavailable`); a search that returned nothing to answer from is answered
472
+ * with `answer: null`, a warning, and no model charge.
473
+ *
474
+ * **Structured output:** with `output_schema` (a JSON Schema, at most 16 KB) the
475
+ * answer is a JSON value in `output` (and `answer` is null). Can't be combined
476
+ * with `stream`.
477
+ *
478
+ * **Streaming:** `stream: true` returns `text/event-stream` with these events, in
479
+ * order: `results` (`{request, results}`), `delta` (`{text}`, repeated), then
480
+ * `done` (`{answer, citations, meta}`) or `error` (`{error}`). Billing headers on a
481
+ * stream carry the search part only; the final `meta` has the total.
482
+ */
483
+ post: operations["answer"];
484
+ delete?: never;
485
+ options?: never;
486
+ head?: never;
487
+ patch?: never;
488
+ trace?: never;
489
+ };
490
+ "/v1/research": {
491
+ parameters: {
492
+ query?: never;
493
+ header?: never;
494
+ path?: never;
495
+ cookie?: never;
496
+ };
497
+ get?: never;
498
+ put?: never;
499
+ /**
500
+ * Start an async deep-research task — planned searches, page reading, a cited Markdown report written by Claude (lite 30, standard 75, deep 200 credits)
501
+ * @description Claude plans Google queries for `input`, the pages they find are read and
502
+ * ranked, a decision model checks whether the notes already cover the task (and
503
+ * drops off-topic sources), Claude reviews gaps and plans follow-up rounds, then
504
+ * writes a Markdown report citing numbered sources (and, with `output_schema`, a
505
+ * JSON value in `output`).
506
+ *
507
+ * | effort | credits | first-round queries | rounds | pages per query |
508
+ * |---|---:|---:|---:|---:|
509
+ * | lite | 30 | 3 | 1 | 2 |
510
+ * | standard | 75 | 5 | 2 | 3 |
511
+ * | deep | 200 | 8 | 3 | 4 |
512
+ *
513
+ * The flat price is reserved at enqueue and charged only when the report is
514
+ * written; failed research is refunded. A canceled task is charged 1 credit per
515
+ * search already run. Returns `202`; poll `GET /v1/research/{id}` or wait for the
516
+ * signed `research.completed` webhook. At most 20 crawl and research tasks per
517
+ * account may be queued or running at once (`429`).
518
+ */
519
+ post: operations["createResearch"];
520
+ delete?: never;
521
+ options?: never;
522
+ head?: never;
523
+ patch?: never;
524
+ trace?: never;
525
+ };
526
+ "/v1/research/{id}": {
527
+ parameters: {
528
+ query?: never;
529
+ header?: never;
530
+ path: {
531
+ id: string;
532
+ };
533
+ cookie?: never;
534
+ };
535
+ /** Poll a research task (kept for 24 hours) */
536
+ get: operations["getResearch"];
537
+ put?: never;
538
+ post?: never;
539
+ /**
540
+ * Cancel a research task. A queued task is refunded at once; a running one stops at its next round and is charged for the searches run
541
+ * @description `404` when there is no such task, `409` when it already finished.
542
+ */
543
+ delete: operations["cancelResearch"];
544
+ options?: never;
545
+ head?: never;
546
+ patch?: never;
547
+ trace?: never;
548
+ };
428
549
  "/v1/monitors": {
429
550
  parameters: {
430
551
  query?: never;
@@ -592,7 +713,8 @@ interface paths {
592
713
  * @description Credits for the whole batch are reserved together: if the balance, spend cap, key limit or
593
714
  * free daily cap can't cover every valid request, none is queued and each gets the error
594
715
  * (invalid requests get their own 400 entry either way). Each job is settled and refunded on
595
- * its own once it runs.
716
+ * its own once it runs. Half price applies to the search part; an AI surcharge
717
+ * (`include_answer`) is charged in full.
596
718
  *
597
719
  * **Retries.** Send an `Idempotency-Key` to make the call safe to retry: for 24 hours a
598
720
  * repeat with the same key and the same body returns the first response (with
@@ -836,9 +958,9 @@ interface components {
836
958
  /** @description Accept a cached result up to this many seconds old (50% of credits on a hit) */
837
959
  max_age?: number;
838
960
  engine?: components["schemas"]["EngineParam"];
839
- /** @description Only results from these domains (search, news, images, videos). Compiled into site: operators and enforced on the results. Not with engine=consensus */
961
+ /** @description Only results from these domains (search, news, images, videos). Compiled into site: operators and enforced on the results. With engine=consensus, every provider gets the operators and only providers with a remaining result are billed */
840
962
  include_domains?: components["schemas"]["DomainList"];
841
- /** @description Drop results from these domains (search, news, images, videos). Not with engine=consensus */
963
+ /** @description Drop results from these domains (search, news, images, videos) */
842
964
  exclude_domains?: components["schemas"]["DomainList"];
843
965
  /** @description Move results from these domains to the top, keeping the order within both groups (search, news) */
844
966
  boost_domains?: components["schemas"]["DomainList"];
@@ -857,6 +979,11 @@ interface components {
857
979
  * @default false
858
980
  */
859
981
  highlights?: boolean;
982
+ /**
983
+ * @description Add a cited AI `answer` written by Claude over this response's results (search and news; +2 credits, +4 when it read pages via `include_content`; refunded with a `meta.warnings` entry when the model fails)
984
+ * @default false
985
+ */
986
+ include_answer?: boolean;
860
987
  };
861
988
  /** @description Domains as an array or a comma-separated string, at most 20: a host (`example.com`, subdomains match), a host with a path prefix (`github.com/org`) or a TLD (`.gov`). */
862
989
  DomainList: string | string[];
@@ -893,7 +1020,7 @@ interface components {
893
1020
  fields?: string;
894
1021
  max_age?: number;
895
1022
  };
896
- /** @description One of place_id, cid or fid is required (place_id wins, then fid, then cid) */
1023
+ /** @description One of place_id, cid or fid (Google; place_id wins, then fid, then cid) or oid (Yandex Maps) is required */
897
1024
  PlaceRequest: {
898
1025
  /** @description Google place id ("ChIJ…"), e.g. `place_id` of a /v1/maps result */
899
1026
  place_id?: string;
@@ -901,6 +1028,11 @@ interface components {
901
1028
  cid?: string;
902
1029
  /** @description Feature id "0x…:0x…" (`fid` of a result) */
903
1030
  fid?: string;
1031
+ /**
1032
+ * @description Yandex Maps organisation id (`oid` of an `engine=yandex` maps result). Implies `engine=yandex`; not with place_id, cid or fid
1033
+ * @example 1045821788
1034
+ */
1035
+ oid?: string;
904
1036
  /**
905
1037
  * @description Country code (ISO 3166-1 alpha-2); Google's regional view of the listing
906
1038
  * @default us
@@ -974,10 +1106,21 @@ interface components {
974
1106
  /** @description Fetch through an exit in this country (ISO 3166-1 alpha-2) */
975
1107
  country?: string;
976
1108
  /**
977
- * @description Seconds to wait for the pages; a page still loading is listed in `failed` (`upstream_timeout`, not charged)
1109
+ * @description Seconds to wait for the pages; a page still loading is listed in `failed` (`upstream_timeout`, not charged). Default 75 with summary or output_schema
978
1110
  * @default 50
979
1111
  */
980
1112
  timeout?: number;
1113
+ /**
1114
+ * @description Add a 3-6 sentence AI summary of each page (+4 credits per page; focused on `query` when set)
1115
+ * @default false
1116
+ */
1117
+ summary?: boolean;
1118
+ /** @description A JSON Schema (at most 16 KB): each page's data is returned as JSON matching it in `output` (+4 credits per page) */
1119
+ output_schema?: {
1120
+ [key: string]: unknown;
1121
+ };
1122
+ /** @description Guides output_schema extraction (what to pick, how to normalise); needs output_schema */
1123
+ prompt?: string;
981
1124
  };
982
1125
  ExtractResult: {
983
1126
  /** @description Final URL after redirects */
@@ -1000,6 +1143,12 @@ interface components {
1000
1143
  images?: string[];
1001
1144
  /** @description highlights > 0 only */
1002
1145
  highlights?: components["schemas"]["Highlight"][];
1146
+ /** @description summary=true only (null when it failed) */
1147
+ summary?: string | null;
1148
+ summary_error?: string;
1149
+ /** @description output_schema only: the JSON value matching the schema (null when it failed) */
1150
+ output?: unknown;
1151
+ output_error?: string;
1003
1152
  };
1004
1153
  ExtractFailure: {
1005
1154
  url: string;
@@ -1032,8 +1181,189 @@ interface components {
1032
1181
  latency_ms?: number;
1033
1182
  succeeded: number;
1034
1183
  failed: number;
1184
+ llm?: components["schemas"]["LLMUsage"];
1035
1185
  };
1036
1186
  };
1187
+ AnswerRequest: {
1188
+ q: string;
1189
+ /**
1190
+ * @description `fast` answers from the result page (1 + 2 credits); `standard` also reads the top `num_sources` pages (1 + 1 per page + 4 credits)
1191
+ * @default standard
1192
+ * @enum {string}
1193
+ */
1194
+ depth?: "fast" | "standard";
1195
+ /**
1196
+ * @description Pages read (depth=standard only)
1197
+ * @default 3
1198
+ */
1199
+ num_sources?: number;
1200
+ /**
1201
+ * @description Send Server-Sent Events (`results`, `delta`…, `done` | `error`) instead of one JSON body
1202
+ * @default false
1203
+ */
1204
+ stream?: boolean;
1205
+ /** @description A JSON Schema (at most 16 KB). The answer becomes a JSON value in `output`. Not with stream */
1206
+ output_schema?: {
1207
+ [key: string]: unknown;
1208
+ };
1209
+ /** @default us */
1210
+ country?: string;
1211
+ /** @default en */
1212
+ language?: string;
1213
+ location?: string;
1214
+ uule?: string;
1215
+ /** @enum {string} */
1216
+ time?: "hour" | "day" | "week" | "month" | "year";
1217
+ tbs?: string;
1218
+ /**
1219
+ * @default desktop
1220
+ * @enum {string}
1221
+ */
1222
+ device?: "desktop" | "mobile";
1223
+ /**
1224
+ * @default off
1225
+ * @enum {string}
1226
+ */
1227
+ safe?: "active" | "off";
1228
+ /** @default true */
1229
+ autocorrect?: boolean;
1230
+ /** @description Accept a cached search up to this many seconds old */
1231
+ max_age?: number;
1232
+ engine?: components["schemas"]["EngineParam"];
1233
+ include_domains?: components["schemas"]["DomainList"];
1234
+ exclude_domains?: components["schemas"]["DomainList"];
1235
+ boost_domains?: components["schemas"]["DomainList"];
1236
+ /** Format: date */
1237
+ start_date?: string;
1238
+ /** Format: date */
1239
+ end_date?: string;
1240
+ };
1241
+ /** @description A result the answer may cite, numbered as in the prompt (`[index]`) */
1242
+ AnswerSource: {
1243
+ index: number;
1244
+ title: string;
1245
+ link: string;
1246
+ domain?: string;
1247
+ /** @description Publish date (ISO 8601 when known, else as shown) */
1248
+ date?: string;
1249
+ };
1250
+ AnswerMeta: components["schemas"]["Meta"] & {
1251
+ /** @description `credits_used` split into the search and the model part */
1252
+ credits?: {
1253
+ search?: number;
1254
+ answer?: number;
1255
+ };
1256
+ };
1257
+ AnswerResponse: {
1258
+ request: components["schemas"]["RequestEcho"];
1259
+ /** @description Markdown with `[n]` citation markers. Null with output_schema, or when there was nothing to answer from */
1260
+ answer: string | null;
1261
+ /** @description output_schema only: the JSON value matching the schema */
1262
+ output?: unknown;
1263
+ /** @description The sources the answer cites, in first-cited order */
1264
+ citations: components["schemas"]["Citation"][];
1265
+ results: components["schemas"]["AnswerSource"][];
1266
+ meta: components["schemas"]["AnswerMeta"];
1267
+ };
1268
+ /** @description `event: results`, sent first */
1269
+ AnswerStreamResults: {
1270
+ request: components["schemas"]["RequestEcho"];
1271
+ results: components["schemas"]["AnswerSource"][];
1272
+ };
1273
+ /** @description `event: delta`: the next piece of answer text */
1274
+ AnswerStreamDelta: {
1275
+ text: string;
1276
+ };
1277
+ /** @description `event: done`, sent last: the final answer (citation markers checked) and meta with the total credits */
1278
+ AnswerStreamDone: {
1279
+ answer: string;
1280
+ citations: components["schemas"]["Citation"][];
1281
+ meta: components["schemas"]["AnswerMeta"];
1282
+ };
1283
+ ResearchRequest: {
1284
+ /** @description The research task in plain words (`q` is accepted as an alias) */
1285
+ input: string;
1286
+ /**
1287
+ * @description lite = 30, standard = 75, deep = 200 credits
1288
+ * @default standard
1289
+ * @enum {string}
1290
+ */
1291
+ effort?: "lite" | "standard" | "deep";
1292
+ /** @description A JSON Schema (at most 16 KB); the report is also returned as a JSON value in `result.output` */
1293
+ output_schema?: {
1294
+ [key: string]: unknown;
1295
+ };
1296
+ country?: string;
1297
+ language?: string;
1298
+ include_domains?: string[];
1299
+ exclude_domains?: string[];
1300
+ /**
1301
+ * Format: uri
1302
+ * @description Receives the signed `research.completed` event. Defaults to the account webhook
1303
+ */
1304
+ webhook_url?: string;
1305
+ };
1306
+ ResearchSource: {
1307
+ index: number;
1308
+ title: string;
1309
+ link: string;
1310
+ domain?: string;
1311
+ published_at?: string;
1312
+ /** @description The query that found it */
1313
+ query?: string;
1314
+ };
1315
+ ResearchResult: {
1316
+ input: string;
1317
+ /** @enum {string} */
1318
+ effort: "lite" | "standard" | "deep";
1319
+ /** @description Markdown report with `[n]` citation markers */
1320
+ report: string;
1321
+ citations: components["schemas"]["Citation"][];
1322
+ sources: components["schemas"]["ResearchSource"][];
1323
+ /** @description Every search the research ran */
1324
+ queries: string[];
1325
+ stats?: {
1326
+ searches?: number;
1327
+ sources?: number;
1328
+ rounds?: number;
1329
+ };
1330
+ llm?: components["schemas"]["LLMUsage"];
1331
+ /** @description output_schema only: the JSON value (null when it could not be produced) */
1332
+ output?: unknown;
1333
+ output_error?: string;
1334
+ };
1335
+ ResearchTask: {
1336
+ /** Format: uuid */
1337
+ id: string;
1338
+ /** @constant */
1339
+ kind: "research";
1340
+ status: components["schemas"]["TaskStatus"];
1341
+ /** Format: date-time */
1342
+ created_at: string;
1343
+ /** Format: date-time */
1344
+ started_at?: string | null;
1345
+ /** Format: date-time */
1346
+ completed_at?: string | null;
1347
+ credits_reserved: number;
1348
+ credits_used: number;
1349
+ /** @enum {string|null} */
1350
+ webhook_status?: "pending" | "delivered" | "failed" | null;
1351
+ progress?: ({
1352
+ round?: number;
1353
+ rounds?: number;
1354
+ queries?: number;
1355
+ sources?: number;
1356
+ /** @enum {string} */
1357
+ step?: "searching" | "reviewing" | "writing";
1358
+ } & {
1359
+ [key: string]: unknown;
1360
+ }) | null;
1361
+ /** @description Set once the report is written (a failed or canceled task may carry only `queries`) */
1362
+ result?: components["schemas"]["ResearchResult"] | {
1363
+ [key: string]: unknown;
1364
+ } | null;
1365
+ error?: components["schemas"]["TaskError"];
1366
+ };
1037
1367
  CrawlRequest: {
1038
1368
  /**
1039
1369
  * Format: uri
@@ -1095,7 +1425,7 @@ interface components {
1095
1425
  /** Format: uuid */
1096
1426
  id: string;
1097
1427
  /** @enum {string} */
1098
- kind: "crawl";
1428
+ kind: "crawl" | "research";
1099
1429
  status: components["schemas"]["TaskStatus"];
1100
1430
  /** Format: date-time */
1101
1431
  created_at: string;
@@ -1200,7 +1530,7 @@ interface components {
1200
1530
  * @description The site (any page of it; sitemaps are read from its origin)
1201
1531
  */
1202
1532
  url: string;
1203
- /** @description Keep only URLs relevant to these words, most relevant first */
1533
+ /** @description Keep only URLs relevant to these words, most relevant first. When the sitemap lists fewer than 50 URLs, up to 8 of the start page's links are read too, one level deeper */
1204
1534
  search?: string;
1205
1535
  /** @default 100 */
1206
1536
  limit?: number;
@@ -1257,8 +1587,8 @@ interface components {
1257
1587
  * @description A search provider (docs/providers). Which verticals each serves depends on the deployment.
1258
1588
  * @enum {string}
1259
1589
  */
1260
- Provider: "google" | "brave" | "bing" | "yahoo" | "duckduckgo" | "mojeek" | "wikipedia";
1261
- /** @description Which search providers may answer. `google` (the default) is Google only; within Google, SerpKite always fails over across its own proxy pools. `auto` allows falling back to other enabled providers, in route order, when Google is blocked or times out. A single other provider (`brave`) or a list (`["google","brave"]`, or `google,brave` in a query string) restricts the request to those providers. `meta.engine` always names the provider that answered and credits follow that provider's price. A key with "Allow fallback to other search engines" on treats a request without `engine` as `auto`. `consensus` (`/v1/search` only; 400 elsewhere, and it can't be combined with other names) queries several independent search indexes in parallel (at most one Bing-backed provider, so Yahoo or DuckDuckGo never count as agreeing with Bing), merges the results by URL and ranks them by how many providers returned each one. Each result lists its `sources`; `meta.engine` is `consensus` and `meta.route` lists every provider attempt. It stops once `num` unique results are in hand or after a few seconds, and costs the sum of one page at each provider that returned results (providers that failed, came back empty or were never started are free). */
1590
+ Provider: "google" | "brave" | "bing" | "yahoo" | "duckduckgo" | "mojeek" | "wikipedia" | "yandex";
1591
+ /** @description Which search providers may answer. `google` (the default) is Google only; within Google, SerpKite always fails over across its own proxy pools. `auto` allows falling back to other enabled providers, in route order, when Google is blocked or times out. A single other provider (`brave`) or a list (`["google","brave"]`, or `google,brave` in a query string) restricts the request to those providers. `meta.engine` always names the provider that answered and credits follow that provider's price. A key with "Allow fallback to other search engines" on treats a request without `engine` as `auto`. `consensus` (`/v1/search` only; 400 elsewhere, and it can't be combined with other names) queries several independent search indexes in parallel (at most one Bing-backed provider, so Yahoo or DuckDuckGo never count as agreeing with Bing), merges the results by URL and ranks them by how many providers returned each one. Each result lists its `sources`; `meta.engine` is `consensus` and `meta.route` lists every provider attempt. Up to three providers answer: a provider that fails or comes back empty hands its turn to the next one in the route. It stops once `num` unique results are in hand or after a few seconds, and costs the sum of one page at each provider that returned results (providers that failed, came back empty or were never started are free). `yandex` serves `/v1/search` from Yandex web search (no `time` filter or `safe: active`: a request naming it gets a 400 with them) and `/v1/maps`, `/v1/places` and `/v1/place` from Yandex Maps, where the deployment enables it (otherwise a 503 `unavailable`, not charged); with `auto` it is the last fallback there. */
1262
1592
  EngineParam: string | components["schemas"]["Provider"][];
1263
1593
  /** @description One provider attempt behind this answer. Proxy pools are internal and never listed. */
1264
1594
  RouteStep: {
@@ -1292,6 +1622,37 @@ interface components {
1292
1622
  /** @enum {string} */
1293
1623
  parse_quality?: "ok" | "partial" | "empty";
1294
1624
  latency_ms?: number;
1625
+ llm?: components["schemas"]["LLMUsage"];
1626
+ /** @description Non-fatal problems, e.g. an include_answer that failed (and was refunded) */
1627
+ warnings?: string[];
1628
+ };
1629
+ /** @description The model that wrote this response's AI part and the tokens it used */
1630
+ LLMUsage: {
1631
+ /**
1632
+ * @example anthropic
1633
+ * @example openai
1634
+ */
1635
+ provider?: string;
1636
+ /**
1637
+ * @example claude-haiku-5-5
1638
+ * @example gpt-6-luna
1639
+ */
1640
+ model?: string;
1641
+ input_tokens?: number;
1642
+ output_tokens?: number;
1643
+ };
1644
+ Citation: {
1645
+ /** @description The `[n]` marker used in the text (1-based source number) */
1646
+ index: number;
1647
+ title: string;
1648
+ link: string;
1649
+ domain?: string;
1650
+ };
1651
+ /** @description include_answer: a cited answer over this response's results */
1652
+ SearchAnswer: {
1653
+ /** @description Markdown with `[n]` citation markers (n = the numbered sources: answer box, knowledge panel, then results) */
1654
+ text: string;
1655
+ citations: components["schemas"]["Citation"][];
1295
1656
  };
1296
1657
  /** @description The normalised request that produced this response (defaults filled in) */
1297
1658
  RequestEcho: {
@@ -1321,6 +1682,7 @@ interface components {
1321
1682
  place_id?: string;
1322
1683
  cid?: string;
1323
1684
  fid?: string;
1685
+ oid?: string;
1324
1686
  sort?: string;
1325
1687
  include_content?: number;
1326
1688
  format?: string;
@@ -1328,6 +1690,7 @@ interface components {
1328
1690
  exclude_domains?: string[];
1329
1691
  boost_domains?: string[];
1330
1692
  highlights?: boolean;
1693
+ include_answer?: boolean;
1331
1694
  } & {
1332
1695
  [key: string]: unknown;
1333
1696
  };
@@ -1410,6 +1773,7 @@ interface components {
1410
1773
  related_searches: components["schemas"]["RelatedSearch"][];
1411
1774
  top_stories?: components["schemas"]["NewsResult"][];
1412
1775
  places?: components["schemas"]["PlaceResult"][];
1776
+ answer?: components["schemas"]["SearchAnswer"];
1413
1777
  meta: components["schemas"]["Meta"];
1414
1778
  };
1415
1779
  ImageResult: {
@@ -1462,6 +1826,7 @@ interface components {
1462
1826
  NewsResponse: {
1463
1827
  request: components["schemas"]["RequestEcho"];
1464
1828
  results: components["schemas"]["NewsResult"][];
1829
+ answer?: components["schemas"]["SearchAnswer"];
1465
1830
  meta: components["schemas"]["Meta"];
1466
1831
  };
1467
1832
  PlaceResult: {
@@ -1479,7 +1844,7 @@ interface components {
1479
1844
  phone_number?: string;
1480
1845
  /** @example +44 20 7232 3010 */
1481
1846
  international_phone_number?: string;
1482
- /** @description Hours as Google displays them, keyed by English weekday (Monday … Sunday), in `language`, e.g. {"Monday": "7:30 am–6 pm", "Sunday": "Closed"} */
1847
+ /** @description Hours as the provider displays them, keyed by English weekday (Monday … Sunday), in `language`, e.g. {"Monday": "7:30 am–6 pm", "Sunday": "Closed"}; Yandex Maps: 24-hour times ("08:00–22:00"), "Closed"/"выходной", "Open 24 hours"/"круглосуточно" */
1483
1848
  opening_hours?: {
1484
1849
  [key: string]: string;
1485
1850
  };
@@ -1488,7 +1853,7 @@ interface components {
1488
1853
  country?: string;
1489
1854
  /** @description IANA time zone of the place (Europe/Moscow) */
1490
1855
  timezone?: string;
1491
- /** @description Google's short description of the place, or the owner's, when Google shows one */
1856
+ /** @description Google's short description of the place, or the owner's, when Google shows one; Yandex Maps' summary of the place when it has one */
1492
1857
  description?: string;
1493
1858
  /** @description Photos of the place (/v1/place; up to 10). The URLs are public and can be fetched server-side without cookies */
1494
1859
  photos?: components["schemas"]["PlacePhoto"][];
@@ -1498,12 +1863,17 @@ interface components {
1498
1863
  place_id?: string;
1499
1864
  cid?: string;
1500
1865
  fid?: string;
1866
+ /** @description Yandex Maps organisation id (engine=yandex), for /v1/place */
1867
+ oid?: string;
1868
+ /** @description The place on Yandex Maps (engine=yandex): https://yandex.ru/maps/org/<oid>/ */
1869
+ yandex_maps_url?: string;
1501
1870
  };
1502
1871
  /**
1503
- * @description Opening hours per weekday, from Google's listing, as local times (`timezone`) in 24-hour HH:MM.
1872
+ * @description Opening hours per weekday, from the provider's listing, as local times (`timezone`) in 24-hour HH:MM.
1504
1873
  * A day that is closed is an empty list; a day open 24 hours is `[{"open": "00:00", "close": "24:00"}]`;
1505
1874
  * a day with a break has several intervals. `close` is "24:00" at midnight, and an interval that
1506
- * ends after midnight has `next_day: true` (e.g. 17:30–03:00). Days Google doesn't list are absent.
1875
+ * ends after midnight has `next_day: true` (e.g. 17:30–03:00). Days Google doesn't list are absent;
1876
+ * Yandex Maps lists all seven or none.
1507
1877
  */
1508
1878
  WeeklyHours: {
1509
1879
  monday?: components["schemas"]["HoursIntervals"];
@@ -1807,14 +2177,14 @@ interface components {
1807
2177
  requests: number;
1808
2178
  };
1809
2179
  };
1810
- /** @description Body of `crawl.completed` */
2180
+ /** @description Body of `crawl.completed` and `research.completed` */
1811
2181
  TaskCompletedEvent: {
1812
- /** @constant */
1813
- event: "crawl.completed";
2182
+ /** @enum {string} */
2183
+ event: "crawl.completed" | "research.completed";
1814
2184
  /** Format: uuid */
1815
2185
  id: string;
1816
- /** @constant */
1817
- kind: "crawl";
2186
+ /** @enum {string} */
2187
+ kind: "crawl" | "research";
1818
2188
  status: components["schemas"]["TaskStatus"];
1819
2189
  /** Format: date-time */
1820
2190
  created_at: string;
@@ -1823,7 +2193,7 @@ interface components {
1823
2193
  credits_used: number;
1824
2194
  /** @description Where the task (and its full result) can be fetched for 24 hours */
1825
2195
  poll_url?: string;
1826
- /** @description The CrawlResult (null when the crawl failed without one, or when it is larger than 4 MB: see result_omitted) */
2196
+ /** @description The CrawlResult or ResearchResult (null when the task failed without one, or when it is larger than 4 MB: see result_omitted) */
1827
2197
  result?: unknown;
1828
2198
  /** @description Set when the result was too large for the webhook; GET poll_url for it */
1829
2199
  result_omitted?: boolean;
@@ -2445,6 +2815,8 @@ interface operations {
2445
2815
  end_date?: string;
2446
2816
  /** @description Needs include_content */
2447
2817
  highlights?: boolean;
2818
+ /** @description Add a cited AI answer (+2 credits; +4 with include_content) */
2819
+ include_answer?: boolean;
2448
2820
  api_key?: string;
2449
2821
  };
2450
2822
  header?: never;
@@ -2844,6 +3216,203 @@ interface operations {
2844
3216
  429: components["responses"]["Error"];
2845
3217
  };
2846
3218
  };
3219
+ answer: {
3220
+ parameters: {
3221
+ query?: never;
3222
+ header?: never;
3223
+ path?: never;
3224
+ cookie?: never;
3225
+ };
3226
+ requestBody: {
3227
+ content: {
3228
+ /**
3229
+ * @example {
3230
+ * "q": "what is retrieval-augmented generation",
3231
+ * "depth": "standard",
3232
+ * "num_sources": 3
3233
+ * }
3234
+ */
3235
+ "application/json": components["schemas"]["AnswerRequest"];
3236
+ };
3237
+ };
3238
+ responses: {
3239
+ /** @description OK (`text/event-stream` when `stream` is true) */
3240
+ 200: {
3241
+ headers: {
3242
+ "X-Credits-Used": components["headers"]["CreditsUsed"];
3243
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
3244
+ "X-Cost-USD": components["headers"]["CostUSD"];
3245
+ "X-Cache": components["headers"]["Cache"];
3246
+ "X-Latency-Ms": components["headers"]["LatencyMs"];
3247
+ "X-Tokens-Estimate": components["headers"]["TokensEstimate"];
3248
+ [name: string]: unknown;
3249
+ };
3250
+ content: {
3251
+ /**
3252
+ * @example {
3253
+ * "request": {
3254
+ * "endpoint": "answer",
3255
+ * "engine": "google",
3256
+ * "q": "what is retrieval-augmented generation",
3257
+ * "country": "us",
3258
+ * "language": "en",
3259
+ * "num": 10,
3260
+ * "page": 1,
3261
+ * "autocorrect": true,
3262
+ * "device": "desktop",
3263
+ * "include_content": 3,
3264
+ * "depth": "standard",
3265
+ * "num_sources": 3
3266
+ * },
3267
+ * "answer": "Retrieval-augmented generation (RAG) grounds a language model's answer in documents retrieved at query time [1], which reduces hallucinations and keeps answers current [2].",
3268
+ * "citations": [
3269
+ * {
3270
+ * "index": 1,
3271
+ * "title": "Retrieval-augmented generation",
3272
+ * "link": "https://en.wikipedia.org/wiki/Retrieval-augmented_generation",
3273
+ * "domain": "en.wikipedia.org"
3274
+ * },
3275
+ * {
3276
+ * "index": 2,
3277
+ * "title": "What is RAG?",
3278
+ * "link": "https://www.ibm.com/think/topics/retrieval-augmented-generation",
3279
+ * "domain": "ibm.com"
3280
+ * }
3281
+ * ],
3282
+ * "results": [
3283
+ * {
3284
+ * "index": 1,
3285
+ * "title": "Retrieval-augmented generation",
3286
+ * "link": "https://en.wikipedia.org/wiki/Retrieval-augmented_generation",
3287
+ * "domain": "en.wikipedia.org"
3288
+ * },
3289
+ * {
3290
+ * "index": 2,
3291
+ * "title": "What is RAG?",
3292
+ * "link": "https://www.ibm.com/think/topics/retrieval-augmented-generation",
3293
+ * "domain": "ibm.com"
3294
+ * }
3295
+ * ],
3296
+ * "meta": {
3297
+ * "request_id": "req_01J9",
3298
+ * "credits_used": 6,
3299
+ * "credits": {
3300
+ * "search": 4,
3301
+ * "answer": 2
3302
+ * },
3303
+ * "cached": false,
3304
+ * "engine": "google",
3305
+ * "latency_ms": 4410,
3306
+ * "llm": {
3307
+ * "provider": "anthropic",
3308
+ * "model": "claude-haiku-5-5",
3309
+ * "input_tokens": 3120,
3310
+ * "output_tokens": 88
3311
+ * }
3312
+ * }
3313
+ * }
3314
+ */
3315
+ "application/json": components["schemas"]["AnswerResponse"];
3316
+ /**
3317
+ * @example event: results
3318
+ * data: {"request":{"endpoint":"answer","q":"what is retrieval-augmented generation"},"results":[{"index":1,"title":"Retrieval-augmented generation","link":"https://en.wikipedia.org/wiki/Retrieval-augmented_generation","domain":"en.wikipedia.org"}]}
3319
+ *
3320
+ * event: delta
3321
+ * data: {"text":"Retrieval-augmented generation grounds "}
3322
+ *
3323
+ * event: done
3324
+ * data: {"answer":"Retrieval-augmented generation grounds a model's answer in documents retrieved at query time [1].","citations":[{"index":1,"title":"Retrieval-augmented generation","link":"https://en.wikipedia.org/wiki/Retrieval-augmented_generation","domain":"en.wikipedia.org"}],"meta":{"request_id":"req_01J9","credits_used":3,"cached":false}}
3325
+ */
3326
+ "text/event-stream": string;
3327
+ };
3328
+ };
3329
+ 400: components["responses"]["Error"];
3330
+ 401: components["responses"]["Error"];
3331
+ 402: components["responses"]["Error"];
3332
+ 403: components["responses"]["Error"];
3333
+ 429: components["responses"]["Error"];
3334
+ 503: components["responses"]["Unavailable"];
3335
+ };
3336
+ };
3337
+ createResearch: {
3338
+ parameters: {
3339
+ query?: never;
3340
+ header?: never;
3341
+ path?: never;
3342
+ cookie?: never;
3343
+ };
3344
+ requestBody: {
3345
+ content: {
3346
+ /**
3347
+ * @example {
3348
+ * "input": "compare espresso machines under $500 for a small office",
3349
+ * "effort": "standard",
3350
+ * "output_schema": {
3351
+ * "type": "object",
3352
+ * "properties": {
3353
+ * "winner": {
3354
+ * "type": "string"
3355
+ * }
3356
+ * }
3357
+ * }
3358
+ * }
3359
+ */
3360
+ "application/json": components["schemas"]["ResearchRequest"];
3361
+ };
3362
+ };
3363
+ responses: {
3364
+ 202: components["responses"]["TaskAccepted"];
3365
+ 400: components["responses"]["Error"];
3366
+ 401: components["responses"]["Error"];
3367
+ 402: components["responses"]["Error"];
3368
+ 403: components["responses"]["Error"];
3369
+ 429: components["responses"]["Error"];
3370
+ 503: components["responses"]["Unavailable"];
3371
+ };
3372
+ };
3373
+ getResearch: {
3374
+ parameters: {
3375
+ query?: never;
3376
+ header?: never;
3377
+ path: {
3378
+ id: string;
3379
+ };
3380
+ cookie?: never;
3381
+ };
3382
+ requestBody?: never;
3383
+ responses: {
3384
+ /** @description OK */
3385
+ 200: {
3386
+ headers: {
3387
+ [name: string]: unknown;
3388
+ };
3389
+ content: {
3390
+ "application/json": components["schemas"]["ResearchTask"];
3391
+ };
3392
+ };
3393
+ 401: components["responses"]["Error"];
3394
+ 404: components["responses"]["Error"];
3395
+ 429: components["responses"]["Error"];
3396
+ };
3397
+ };
3398
+ cancelResearch: {
3399
+ parameters: {
3400
+ query?: never;
3401
+ header?: never;
3402
+ path: {
3403
+ id: string;
3404
+ };
3405
+ cookie?: never;
3406
+ };
3407
+ requestBody?: never;
3408
+ responses: {
3409
+ 200: components["responses"]["TaskCanceled"];
3410
+ 401: components["responses"]["Error"];
3411
+ 404: components["responses"]["Error"];
3412
+ 409: components["responses"]["Error"];
3413
+ 429: components["responses"]["Error"];
3414
+ };
3415
+ };
2847
3416
  listMonitors: {
2848
3417
  parameters: {
2849
3418
  query?: never;
@@ -3370,6 +3939,28 @@ interface operations {
3370
3939
  };
3371
3940
  };
3372
3941
  };
3942
+ researchCompletedWebhook: {
3943
+ parameters: {
3944
+ query?: never;
3945
+ header?: never;
3946
+ path?: never;
3947
+ cookie?: never;
3948
+ };
3949
+ requestBody: {
3950
+ content: {
3951
+ "application/json": components["schemas"]["TaskCompletedEvent"];
3952
+ };
3953
+ };
3954
+ responses: {
3955
+ /** @description Any 2xx acknowledges the delivery */
3956
+ 200: {
3957
+ headers: {
3958
+ [name: string]: unknown;
3959
+ };
3960
+ content?: never;
3961
+ };
3962
+ };
3963
+ };
3373
3964
  monitorResultsWebhook: {
3374
3965
  parameters: {
3375
3966
  query?: never;
@@ -3420,7 +4011,10 @@ type SearchParams = Omit<Schemas["SearchRequest"], "engine"> & {
3420
4011
  engine?: Engine;
3421
4012
  };
3422
4013
  type ReviewsParams = Schemas["ReviewsRequest"];
3423
- /** Parameters of `place`: one of `place_id`, `cid` or `fid` (place_id wins, then fid, then cid). */
4014
+ /**
4015
+ * Parameters of `place`: one of `place_id`, `cid` or `fid` (Google; place_id wins, then fid,
4016
+ * then cid), or `oid` (a Yandex Maps organisation id, which implies `engine: "yandex"`).
4017
+ */
3424
4018
  type PlaceParams = Omit<Schemas["PlaceRequest"], "engine"> & {
3425
4019
  /** Search providers allowed to answer. Default `"google"`. See {@link Engine}. */
3426
4020
  engine?: Engine;
@@ -3470,6 +4064,15 @@ type MapURL = Schemas["MapURL"];
3470
4064
  type ExtractResult = Schemas["ExtractResult"];
3471
4065
  type ExtractFailure = Schemas["ExtractFailure"];
3472
4066
  type RankMatch = Schemas["RankResponse"]["matches"][number];
4067
+ /** A source an AI answer or report cites with an `[index]` marker. */
4068
+ type Citation = Schemas["Citation"];
4069
+ /**
4070
+ * `include_answer: true` on `search` / `news`: a cited answer over the response's results
4071
+ * (`text` with `[n]` markers). Absent when the model failed (refunded, see `meta.warnings`).
4072
+ */
4073
+ type SearchAnswer = Schemas["SearchAnswer"];
4074
+ /** `meta.llm`: the model behind an AI response and the tokens it used. */
4075
+ type LLMUsage = Schemas["LLMUsage"];
3473
4076
  type SearchResponse = Schemas["SearchResponse"];
3474
4077
  type ImagesResponse = Schemas["ImagesResponse"];
3475
4078
  type VideosResponse = Schemas["VideosResponse"];
@@ -3497,6 +4100,34 @@ interface CompactResponse {
3497
4100
  meta: Meta;
3498
4101
  [key: string]: unknown;
3499
4102
  }
4103
+ /** Body of `POST /v1/answer` (`stream` is set by `answerStream`). */
4104
+ type AnswerParams = Omit<Schemas["AnswerRequest"], "engine" | "stream"> & {
4105
+ /** Search providers allowed to answer. Default `"google"`. See {@link Engine}. */
4106
+ engine?: Engine;
4107
+ };
4108
+ type AnswerResponse = Schemas["AnswerResponse"];
4109
+ /** A result the answer may cite, numbered as in the prompt (`[index]`). */
4110
+ type AnswerSource = Schemas["AnswerSource"];
4111
+ /** `meta` of an answer: `credits` splits `credits_used` into search and model; `llm` names the model. */
4112
+ type AnswerMeta = Schemas["AnswerMeta"];
4113
+ type AnswerStreamResults = Schemas["AnswerStreamResults"];
4114
+ type AnswerStreamDelta = Schemas["AnswerStreamDelta"];
4115
+ type AnswerStreamDone = Schemas["AnswerStreamDone"];
4116
+ /**
4117
+ * One Server-Sent Event of `answerStream`: `results` first, then `delta` pieces of text,
4118
+ * then `done` with the final answer, citations and meta. A server `error` event is thrown
4119
+ * as a `SerpKiteError` instead of being yielded.
4120
+ */
4121
+ type AnswerStreamEvent = {
4122
+ event: "results";
4123
+ data: AnswerStreamResults;
4124
+ } | {
4125
+ event: "delta";
4126
+ data: AnswerStreamDelta;
4127
+ } | {
4128
+ event: "done";
4129
+ data: AnswerStreamDone;
4130
+ };
3500
4131
  type Batch = Schemas["Batch"];
3501
4132
  type BatchStatus = Batch["status"];
3502
4133
  type BatchEndpoint = Schemas["BatchCreateRequest"]["endpoint"];
@@ -3536,7 +4167,7 @@ type BatchCreateParams = {
3536
4167
  };
3537
4168
  }[BatchEndpoint];
3538
4169
  type TaskStatus = Schemas["TaskStatus"];
3539
- /** The `202` body of `crawl`. */
4170
+ /** The `202` body of `crawl` and `research`. */
3540
4171
  type TaskCreated = Schemas["TaskCreated"];
3541
4172
  type TaskCancelResponse = Schemas["TaskCancelResponse"];
3542
4173
  type TaskError = Schemas["TaskError"];
@@ -3555,6 +4186,24 @@ type CrawlStats = CrawlResult["stats"];
3555
4186
  /** Why a crawl ended (`result.stats.stopped`). */
3556
4187
  type CrawlStopReason = NonNullable<CrawlStats["stopped"]>;
3557
4188
  type CrawlPage = Schemas["CrawlPage"];
4189
+ /**
4190
+ * Body of `POST /v1/research`: `input` (the task in plain words), `effort` (`lite`, `standard`
4191
+ * (default) or `deep`; flat prices at https://serpkite.com/pricing), optional `output_schema`,
4192
+ * locale, domain filters and `webhook_url` (receives `research.completed`).
4193
+ */
4194
+ type ResearchParams = Schemas["ResearchRequest"];
4195
+ type ResearchEffort = NonNullable<ResearchParams["effort"]>;
4196
+ type ResearchResult = Schemas["ResearchResult"];
4197
+ type ResearchSource = Schemas["ResearchSource"];
4198
+ /**
4199
+ * A research task. `result` is set once the report is written (`status: "completed"`); a
4200
+ * failed or canceled task may carry a partial result with only `queries`.
4201
+ */
4202
+ type ResearchTask = Omit<Schemas["ResearchTask"], "result"> & {
4203
+ result?: ResearchResult | null;
4204
+ };
4205
+ /** `progress` of a running research task (round, queries, sources, current step). */
4206
+ type ResearchProgress = NonNullable<Schemas["ResearchTask"]["progress"]>;
3558
4207
  /**
3559
4208
  * Body of `POST /v1/monitors`. `search` and `news` monitors need `q`; `webpage` monitors need
3560
4209
  * `url` (and take only `country` besides) and report the page when its content changes.
@@ -3603,10 +4252,17 @@ type BatchCompletedEvent = Omit<Batch, "poll_url" | "webhook_url" | "webhook_sta
3603
4252
  event: "batch.completed";
3604
4253
  };
3605
4254
  /**
3606
- * Body of `crawl.completed`. When the result is over 4 MB, `result` is null and
4255
+ * Body of `crawl.completed` and `research.completed` (`kind` says which; `result` is a
4256
+ * `CrawlResult` or `ResearchResult`). When the result is over 4 MB, `result` is null and
3607
4257
  * `result_omitted` is true: fetch the task from `poll_url`.
3608
4258
  */
3609
4259
  type TaskCompletedEvent = Schemas["TaskCompletedEvent"];
4260
+ /** Body of `research.completed`: a {@link TaskCompletedEvent} whose `result` is a `ResearchResult`. */
4261
+ type ResearchCompletedEvent = Omit<TaskCompletedEvent, "event" | "kind" | "result"> & {
4262
+ event: "research.completed";
4263
+ kind: "research";
4264
+ result?: ResearchResult | null;
4265
+ };
3610
4266
  /**
3611
4267
  * Body of `monitor.results`. `run_id` is also the `X-SerpKite-Delivery` header (dedupe retries
3612
4268
  * on it). Carries the monitor's `metadata`, and `url` for webpage monitors (whose `new_results`
@@ -3614,7 +4270,7 @@ type TaskCompletedEvent = Schemas["TaskCompletedEvent"];
3614
4270
  */
3615
4271
  type MonitorResultsEvent = Schemas["MonitorResultsEvent"];
3616
4272
  /** `X-SerpKite-Event` values. Plain strings stay accepted for events added later. */
3617
- type WebhookEventType = "batch.completed" | "crawl.completed" | "monitor.results" | (string & {});
4273
+ type WebhookEventType = "batch.completed" | "crawl.completed" | "research.completed" | "monitor.results" | (string & {});
3618
4274
  /** A verified webhook delivery, from `parseWebhook`. */
3619
4275
  type WebhookEvent = {
3620
4276
  type: "batch.completed";
@@ -3624,13 +4280,17 @@ type WebhookEvent = {
3624
4280
  type: "crawl.completed";
3625
4281
  deliveryId: string | undefined;
3626
4282
  data: TaskCompletedEvent;
4283
+ } | {
4284
+ type: "research.completed";
4285
+ deliveryId: string | undefined;
4286
+ data: ResearchCompletedEvent;
3627
4287
  } | {
3628
4288
  type: "monitor.results";
3629
4289
  deliveryId: string | undefined;
3630
4290
  data: MonitorResultsEvent;
3631
4291
  };
3632
4292
 
3633
- declare const VERSION = "0.5.0";
4293
+ declare const VERSION = "0.7.0";
3634
4294
  declare const DEFAULT_BASE_URL = "https://api.serpkite.com";
3635
4295
  interface SerpKiteOptions {
3636
4296
  /** API key (`skt_live_…`). Defaults to the `SERPKITE_API_KEY` environment variable. */
@@ -3681,8 +4341,9 @@ interface BatchCreateOptions extends RequestOptions {
3681
4341
  }
3682
4342
  interface WaitOptions {
3683
4343
  /**
3684
- * Give up after this many milliseconds. Default 600000 (10 minutes) for batches and
3685
- * 2100000 (35 minutes) for `waitForCrawl`: a crawl runs for up to 30 minutes.
4344
+ * Give up after this many milliseconds. Default 600000 (10 minutes) for batches,
4345
+ * 2100000 (35 minutes) for `waitForCrawl` (a crawl runs for up to 30 minutes) and
4346
+ * 900000 (15 minutes) for `waitResearch`.
3686
4347
  */
3687
4348
  timeoutMs?: number;
3688
4349
  /** First delay between polls. Default 1000. Grows 1.5× per poll. */
@@ -3731,6 +4392,7 @@ declare class SerpKite {
3731
4392
  related_searches: components["schemas"]["RelatedSearch"][];
3732
4393
  top_stories?: components["schemas"]["NewsResult"][];
3733
4394
  places?: components["schemas"]["PlaceResult"][];
4395
+ answer?: components["schemas"]["SearchAnswer"];
3734
4396
  meta: components["schemas"]["Meta"];
3735
4397
  }>;
3736
4398
  /** Google Images. */
@@ -3749,9 +4411,13 @@ declare class SerpKite {
3749
4411
  readonly news: VerticalMethod<SearchParams, {
3750
4412
  request: components["schemas"]["RequestEcho"];
3751
4413
  results: components["schemas"]["NewsResult"][];
4414
+ answer?: components["schemas"]["SearchAnswer"];
3752
4415
  meta: components["schemas"]["Meta"];
3753
4416
  }>;
3754
- /** Google Maps search (places with coordinates). Accepts `ll` ("@lat,lng,14z"). */
4417
+ /**
4418
+ * Google Maps search (places with coordinates). Accepts `ll` ("@lat,lng,14z"). With
4419
+ * `engine: "yandex"` (where enabled) the places come from Yandex Maps and carry an `oid`.
4420
+ */
3755
4421
  readonly maps: VerticalMethod<SearchParams, {
3756
4422
  request: components["schemas"]["RequestEcho"];
3757
4423
  results: components["schemas"]["PlaceResult"][];
@@ -3764,7 +4430,8 @@ declare class SerpKite {
3764
4430
  meta: components["schemas"]["Meta"];
3765
4431
  }>;
3766
4432
  /**
3767
- * Details of one place by `place_id`, `cid` or `fid`: address, country, time zone, hours
4433
+ * Details of one place by `place_id`, `cid` or `fid`, or by a Yandex Maps `oid` (implies
4434
+ * `engine: "yandex"`): address, country, time zone, hours
3768
4435
  * (`opening_hours` text and structured `weekly_hours`), phones, description and photos.
3769
4436
  * `results` holds the place, or is empty (not charged) when no place has that id. 1 credit.
3770
4437
  */
@@ -3843,6 +4510,10 @@ declare class SerpKite {
3843
4510
  * Read up to 20 URLs (HTML or PDF) as Markdown, text or HTML in one call, with optional
3844
4511
  * query-ranked `highlights` (BM25), `include_links` and `include_images`. 1 credit per URL
3845
4512
  * that comes back (0.5 from cache); URLs that fail are listed in `failed` and cost nothing.
4513
+ * `summary: true` adds an AI summary of each page and `output_schema` (a JSON Schema, guided
4514
+ * by an optional `prompt`) returns each page's data as JSON in `output`, each at an extra
4515
+ * per-page price (https://serpkite.com/pricing); a page whose model step failed has
4516
+ * `summary_error` / `output_error` instead and isn't charged for it.
3846
4517
  */
3847
4518
  extract(params: ExtractParams, options?: RequestOptions): Promise<ExtractResponse>;
3848
4519
  /**
@@ -3854,6 +4525,29 @@ declare class SerpKite {
3854
4525
  map(params: MapParams, options?: RequestOptions): Promise<MapResponse>;
3855
4526
  /** Balance, limits and this month's usage for the key's account. */
3856
4527
  account(options?: RequestOptions): Promise<Account>;
4528
+ /**
4529
+ * A cited answer grounded on live Google results: Markdown with `[n]` markers in `answer`,
4530
+ * the cited sources in `citations`. `depth: "fast"` answers from the result page;
4531
+ * `"standard"` (default) also reads the top `num_sources` pages and costs more
4532
+ * (https://serpkite.com/pricing; `meta.credits` splits search and model). With
4533
+ * `output_schema` the answer is a JSON value in `output`.
4534
+ * When the model fails the call throws `ai_unavailable` (503) and the model part is refunded;
4535
+ * a search with nothing to answer from returns `answer: null` and a `meta.warnings` entry.
4536
+ */
4537
+ answer(params: AnswerParams, options?: RequestOptions): Promise<AnswerResponse>;
4538
+ /**
4539
+ * Streams an answer as Server-Sent Events: `results` first, then `delta` text pieces,
4540
+ * then `done` (final answer, citations, meta). A server `error` event is thrown as a
4541
+ * `SerpKiteError` (`ai_unavailable`). Breaking out of the loop closes the connection
4542
+ * (the model part is then not charged). Can't be combined with `output_schema`.
4543
+ *
4544
+ * ```ts
4545
+ * for await (const ev of sk.answerStream({ q: "what is retrieval-augmented generation" })) {
4546
+ * if (ev.event === "delta") process.stdout.write(ev.data.text);
4547
+ * }
4548
+ * ```
4549
+ */
4550
+ answerStream(params: AnswerParams, options?: RequestOptions): AsyncIterable<AnswerStreamEvent>;
3857
4551
  /**
3858
4552
  * Starts an async crawl of one site and returns the queued task (`202`). 1 credit per page
3859
4553
  * read (0.5 from cache); `limit` credits (up to 1000 pages, `max_depth` up to 10) are
@@ -3876,6 +4570,33 @@ declare class SerpKite {
3876
4570
  waitForCrawl(idOrTask: string | {
3877
4571
  id: string;
3878
4572
  }, options?: WaitOptions): Promise<CrawlTask>;
4573
+ /**
4574
+ * Starts an async research task: the model plans searches, reads the sources and writes a
4575
+ * cited Markdown report (`result.report`). `effort` (`lite`, `standard` (default), `deep`)
4576
+ * sets how much is searched and read; its flat price (https://serpkite.com/pricing) is
4577
+ * reserved up front and charged only when the report is written (a canceled task is charged
4578
+ * for the searches already run). With
4579
+ * `output_schema` the report is also returned as JSON in `result.output`. Poll with
4580
+ * `getResearch` / `waitResearch` or receive the signed `research.completed` webhook.
4581
+ * Only retried on 429, so a lost response never starts (and reserves) a second task.
4582
+ */
4583
+ research(params: ResearchParams, options?: RequestOptions): Promise<TaskCreated>;
4584
+ /** Polls a research task (`progress` while it runs; results are kept for 24 hours). */
4585
+ getResearch(id: string, options?: RequestOptions): Promise<ResearchTask>;
4586
+ /**
4587
+ * Cancels a research task: refunded if still queued, else stops at its next round and is
4588
+ * charged for the searches run.
4589
+ */
4590
+ cancelResearch(id: string, options?: RequestOptions): Promise<TaskCancelResponse>;
4591
+ /**
4592
+ * Polls until the research task is `completed`, `failed` or `canceled` and returns it (a
4593
+ * failed task is returned, not thrown; check `status` and `error`). The report is in
4594
+ * `result.report`. Accepts an id or the task returned by `research`. Default timeout
4595
+ * 15 minutes.
4596
+ */
4597
+ waitResearch(idOrTask: string | {
4598
+ id: string;
4599
+ }, options?: WaitOptions): Promise<ResearchTask>;
3879
4600
  readonly monitors: {
3880
4601
  /**
3881
4602
  * Saves a `search` or `news` request (`q`) that runs on a schedule (hourly to monthly) and
@@ -3992,7 +4713,7 @@ interface VerifyWebhookOptions {
3992
4713
  }
3993
4714
  type HeaderSource = Headers | Record<string, string | string[] | undefined>;
3994
4715
  /**
3995
- * Checks a webhook delivery (any event: `batch.completed`, `crawl.completed`,
4716
+ * Checks a webhook delivery (any event: `batch.completed`, `crawl.completed`, `research.completed`,
3996
4717
  * `monitor.results`): `X-SerpKite-Signature` must be
3997
4718
  * `v1=<hex HMAC-SHA256(secret, "<X-SerpKite-Timestamp>.<raw body>")>` and the
3998
4719
  * timestamp recent. Pass the raw request body exactly as received (not
@@ -4007,7 +4728,7 @@ declare function verifyWebhook(secret: string, payload: string | Uint8Array, hea
4007
4728
  * Verifies a delivery (see {@link verifyWebhook}) and returns it typed by its
4008
4729
  * `X-SerpKite-Event` header. `deliveryId` is `X-SerpKite-Delivery` (for
4009
4730
  * `monitor.results` it equals `data.run_id`): use it to deduplicate retries. A
4010
- * `crawl.completed` result over 4 MB arrives as `result: null` with
4731
+ * `crawl.completed` or `research.completed` result over 4 MB arrives as `result: null` with
4011
4732
  * `result_omitted: true`; fetch it from `data.poll_url`. Throws a
4012
4733
  * `SerpKiteError` with code `invalid_signature` when the signature or timestamp
4013
4734
  * doesn't check out.
@@ -4019,4 +4740,4 @@ declare function verifyWebhook(secret: string, payload: string | Uint8Array, hea
4019
4740
  */
4020
4741
  declare function parseWebhook(secret: string, payload: string | Uint8Array, headers: HeaderSource, options?: VerifyWebhookOptions): Promise<WebhookEvent>;
4021
4742
 
4022
- export { type Account, type AnswerBox, type AutocompleteResponse, type Batch, type BatchCompletedEvent, type BatchCreateEntry, type BatchCreateError, type BatchCreateOptions, type BatchCreateParams, type BatchCreateResponse, type BatchEndpoint, type BatchStatus, type CompactResponse, type CrawlPage, type CrawlParams, type CrawlResult, type CrawlSitemapMode, type CrawlStats, type CrawlStopReason, type CrawlTask, DEFAULT_BASE_URL, type DomainList, type Engine, type ErrorBody, type ExtractFailure, type ExtractParams, type ExtractResponse, type ExtractResult, type Format, type Highlight, type HoursInterval, type ImageResult, type ImagesResponse, type KnowledgeGraph, type MapParams, type MapResponse, type MapURL, type MapsResponse, type Meta, type Monitor, type MonitorCreateParams, type MonitorEndpoint, type MonitorList, type MonitorMetadata, type MonitorPageChange, type MonitorResultsEvent, type MonitorRun, type MonitorRunList, type MonitorRunsParams, type MonitorSearch, type MonitorStatus, type MonitorUpdateParams, type NewsResponse, type NewsResult, type OrganicResult, type PageLink, type PageMetadata, type PatentResult, type PatentsResponse, type PeopleAlsoAsk, type PlaceParams, type PlacePhoto, type PlaceResult, type PlacesResponse, type Provider, type RankMatch, type RankParams, type RankResponse, type RelatedSearch, type RequestEcho, type RequestOptions, type ResponseInfo, type ReviewResult, type ReviewsParams, type ReviewsResponse, type RouteOutcome, type RouteStep, type ScholarResponse, type ScholarResult, type SearchParams, type SearchResponse, SerpKite, SerpKiteError, type SerpKiteOptions, type ShoppingResponse, type ShoppingResult, type Sitelink, type Status, type Suggestion, type TaskCancelResponse, type TaskCompletedEvent, type TaskCreated, type TaskError, type TaskStatus, VERSION, type VerifyWebhookOptions, type VerticalMethod, type VideoResult, type VideosResponse, type WaitOptions, type WebhookEvent, type WebhookEventType, type WebpageParams, type WebpageResponse, type WeeklyHours, type components, isBatchError, type operations, parseRetryAfter, parseWebhook, type paths, verifyWebhook };
4743
+ export { type Account, type AnswerBox, type AnswerMeta, type AnswerParams, type AnswerResponse, type AnswerSource, type AnswerStreamDelta, type AnswerStreamDone, type AnswerStreamEvent, type AnswerStreamResults, type AutocompleteResponse, type Batch, type BatchCompletedEvent, type BatchCreateEntry, type BatchCreateError, type BatchCreateOptions, type BatchCreateParams, type BatchCreateResponse, type BatchEndpoint, type BatchStatus, type Citation, type CompactResponse, type CrawlPage, type CrawlParams, type CrawlResult, type CrawlSitemapMode, type CrawlStats, type CrawlStopReason, type CrawlTask, DEFAULT_BASE_URL, type DomainList, type Engine, type ErrorBody, type ExtractFailure, type ExtractParams, type ExtractResponse, type ExtractResult, type Format, type Highlight, type HoursInterval, type ImageResult, type ImagesResponse, type KnowledgeGraph, type LLMUsage, type MapParams, type MapResponse, type MapURL, type MapsResponse, type Meta, type Monitor, type MonitorCreateParams, type MonitorEndpoint, type MonitorList, type MonitorMetadata, type MonitorPageChange, type MonitorResultsEvent, type MonitorRun, type MonitorRunList, type MonitorRunsParams, type MonitorSearch, type MonitorStatus, type MonitorUpdateParams, type NewsResponse, type NewsResult, type OrganicResult, type PageLink, type PageMetadata, type PatentResult, type PatentsResponse, type PeopleAlsoAsk, type PlaceParams, type PlacePhoto, type PlaceResult, type PlacesResponse, type Provider, type RankMatch, type RankParams, type RankResponse, type RelatedSearch, type RequestEcho, type RequestOptions, type ResearchCompletedEvent, type ResearchEffort, type ResearchParams, type ResearchProgress, type ResearchResult, type ResearchSource, type ResearchTask, type ResponseInfo, type ReviewResult, type ReviewsParams, type ReviewsResponse, type RouteOutcome, type RouteStep, type ScholarResponse, type ScholarResult, type SearchAnswer, type SearchParams, type SearchResponse, SerpKite, SerpKiteError, type SerpKiteOptions, type ShoppingResponse, type ShoppingResult, type Sitelink, type Status, type Suggestion, type TaskCancelResponse, type TaskCompletedEvent, type TaskCreated, type TaskError, type TaskStatus, VERSION, type VerifyWebhookOptions, type VerticalMethod, type VideoResult, type VideosResponse, type WaitOptions, type WebhookEvent, type WebhookEventType, type WebpageParams, type WebpageResponse, type WeeklyHours, type components, isBatchError, type operations, parseRetryAfter, parseWebhook, type paths, verifyWebhook };