serpkite 0.6.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
@@ -341,10 +341,19 @@ interface paths {
341
341
  get?: never;
342
342
  put?: never;
343
343
  /**
344
- * 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)
345
345
  * @description Every URL is billed only when it comes back: 1 credit, 0.5 from cache. URLs that
346
346
  * fail are listed in `failed` and cost nothing. The response is `200` even when every
347
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.
348
357
  */
349
358
  post: operations["extract"];
350
359
  delete?: never;
@@ -437,6 +446,106 @@ interface paths {
437
446
  patch?: never;
438
447
  trace?: never;
439
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
+ };
440
549
  "/v1/monitors": {
441
550
  parameters: {
442
551
  query?: never;
@@ -604,7 +713,8 @@ interface paths {
604
713
  * @description Credits for the whole batch are reserved together: if the balance, spend cap, key limit or
605
714
  * free daily cap can't cover every valid request, none is queued and each gets the error
606
715
  * (invalid requests get their own 400 entry either way). Each job is settled and refunded on
607
- * 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.
608
718
  *
609
719
  * **Retries.** Send an `Idempotency-Key` to make the call safe to retry: for 24 hours a
610
720
  * repeat with the same key and the same body returns the first response (with
@@ -848,9 +958,9 @@ interface components {
848
958
  /** @description Accept a cached result up to this many seconds old (50% of credits on a hit) */
849
959
  max_age?: number;
850
960
  engine?: components["schemas"]["EngineParam"];
851
- /** @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 */
852
962
  include_domains?: components["schemas"]["DomainList"];
853
- /** @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) */
854
964
  exclude_domains?: components["schemas"]["DomainList"];
855
965
  /** @description Move results from these domains to the top, keeping the order within both groups (search, news) */
856
966
  boost_domains?: components["schemas"]["DomainList"];
@@ -869,6 +979,11 @@ interface components {
869
979
  * @default false
870
980
  */
871
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;
872
987
  };
873
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`). */
874
989
  DomainList: string | string[];
@@ -991,10 +1106,21 @@ interface components {
991
1106
  /** @description Fetch through an exit in this country (ISO 3166-1 alpha-2) */
992
1107
  country?: string;
993
1108
  /**
994
- * @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
995
1110
  * @default 50
996
1111
  */
997
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;
998
1124
  };
999
1125
  ExtractResult: {
1000
1126
  /** @description Final URL after redirects */
@@ -1017,6 +1143,12 @@ interface components {
1017
1143
  images?: string[];
1018
1144
  /** @description highlights > 0 only */
1019
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;
1020
1152
  };
1021
1153
  ExtractFailure: {
1022
1154
  url: string;
@@ -1049,8 +1181,189 @@ interface components {
1049
1181
  latency_ms?: number;
1050
1182
  succeeded: number;
1051
1183
  failed: number;
1184
+ llm?: components["schemas"]["LLMUsage"];
1052
1185
  };
1053
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
+ };
1054
1367
  CrawlRequest: {
1055
1368
  /**
1056
1369
  * Format: uri
@@ -1112,7 +1425,7 @@ interface components {
1112
1425
  /** Format: uuid */
1113
1426
  id: string;
1114
1427
  /** @enum {string} */
1115
- kind: "crawl";
1428
+ kind: "crawl" | "research";
1116
1429
  status: components["schemas"]["TaskStatus"];
1117
1430
  /** Format: date-time */
1118
1431
  created_at: string;
@@ -1217,7 +1530,7 @@ interface components {
1217
1530
  * @description The site (any page of it; sitemaps are read from its origin)
1218
1531
  */
1219
1532
  url: string;
1220
- /** @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 */
1221
1534
  search?: string;
1222
1535
  /** @default 100 */
1223
1536
  limit?: number;
@@ -1275,7 +1588,7 @@ interface components {
1275
1588
  * @enum {string}
1276
1589
  */
1277
1590
  Provider: "google" | "brave" | "bing" | "yahoo" | "duckduckgo" | "mojeek" | "wikipedia" | "yandex";
1278
- /** @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). `yandex` serves `/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. */
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. */
1279
1592
  EngineParam: string | components["schemas"]["Provider"][];
1280
1593
  /** @description One provider attempt behind this answer. Proxy pools are internal and never listed. */
1281
1594
  RouteStep: {
@@ -1309,6 +1622,37 @@ interface components {
1309
1622
  /** @enum {string} */
1310
1623
  parse_quality?: "ok" | "partial" | "empty";
1311
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"][];
1312
1656
  };
1313
1657
  /** @description The normalised request that produced this response (defaults filled in) */
1314
1658
  RequestEcho: {
@@ -1346,6 +1690,7 @@ interface components {
1346
1690
  exclude_domains?: string[];
1347
1691
  boost_domains?: string[];
1348
1692
  highlights?: boolean;
1693
+ include_answer?: boolean;
1349
1694
  } & {
1350
1695
  [key: string]: unknown;
1351
1696
  };
@@ -1428,6 +1773,7 @@ interface components {
1428
1773
  related_searches: components["schemas"]["RelatedSearch"][];
1429
1774
  top_stories?: components["schemas"]["NewsResult"][];
1430
1775
  places?: components["schemas"]["PlaceResult"][];
1776
+ answer?: components["schemas"]["SearchAnswer"];
1431
1777
  meta: components["schemas"]["Meta"];
1432
1778
  };
1433
1779
  ImageResult: {
@@ -1480,6 +1826,7 @@ interface components {
1480
1826
  NewsResponse: {
1481
1827
  request: components["schemas"]["RequestEcho"];
1482
1828
  results: components["schemas"]["NewsResult"][];
1829
+ answer?: components["schemas"]["SearchAnswer"];
1483
1830
  meta: components["schemas"]["Meta"];
1484
1831
  };
1485
1832
  PlaceResult: {
@@ -1830,14 +2177,14 @@ interface components {
1830
2177
  requests: number;
1831
2178
  };
1832
2179
  };
1833
- /** @description Body of `crawl.completed` */
2180
+ /** @description Body of `crawl.completed` and `research.completed` */
1834
2181
  TaskCompletedEvent: {
1835
- /** @constant */
1836
- event: "crawl.completed";
2182
+ /** @enum {string} */
2183
+ event: "crawl.completed" | "research.completed";
1837
2184
  /** Format: uuid */
1838
2185
  id: string;
1839
- /** @constant */
1840
- kind: "crawl";
2186
+ /** @enum {string} */
2187
+ kind: "crawl" | "research";
1841
2188
  status: components["schemas"]["TaskStatus"];
1842
2189
  /** Format: date-time */
1843
2190
  created_at: string;
@@ -1846,7 +2193,7 @@ interface components {
1846
2193
  credits_used: number;
1847
2194
  /** @description Where the task (and its full result) can be fetched for 24 hours */
1848
2195
  poll_url?: string;
1849
- /** @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) */
1850
2197
  result?: unknown;
1851
2198
  /** @description Set when the result was too large for the webhook; GET poll_url for it */
1852
2199
  result_omitted?: boolean;
@@ -2468,6 +2815,8 @@ interface operations {
2468
2815
  end_date?: string;
2469
2816
  /** @description Needs include_content */
2470
2817
  highlights?: boolean;
2818
+ /** @description Add a cited AI answer (+2 credits; +4 with include_content) */
2819
+ include_answer?: boolean;
2471
2820
  api_key?: string;
2472
2821
  };
2473
2822
  header?: never;
@@ -2867,6 +3216,203 @@ interface operations {
2867
3216
  429: components["responses"]["Error"];
2868
3217
  };
2869
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
+ };
2870
3416
  listMonitors: {
2871
3417
  parameters: {
2872
3418
  query?: never;
@@ -3393,6 +3939,28 @@ interface operations {
3393
3939
  };
3394
3940
  };
3395
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
+ };
3396
3964
  monitorResultsWebhook: {
3397
3965
  parameters: {
3398
3966
  query?: never;
@@ -3496,6 +4064,15 @@ type MapURL = Schemas["MapURL"];
3496
4064
  type ExtractResult = Schemas["ExtractResult"];
3497
4065
  type ExtractFailure = Schemas["ExtractFailure"];
3498
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"];
3499
4076
  type SearchResponse = Schemas["SearchResponse"];
3500
4077
  type ImagesResponse = Schemas["ImagesResponse"];
3501
4078
  type VideosResponse = Schemas["VideosResponse"];
@@ -3523,6 +4100,34 @@ interface CompactResponse {
3523
4100
  meta: Meta;
3524
4101
  [key: string]: unknown;
3525
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
+ };
3526
4131
  type Batch = Schemas["Batch"];
3527
4132
  type BatchStatus = Batch["status"];
3528
4133
  type BatchEndpoint = Schemas["BatchCreateRequest"]["endpoint"];
@@ -3562,7 +4167,7 @@ type BatchCreateParams = {
3562
4167
  };
3563
4168
  }[BatchEndpoint];
3564
4169
  type TaskStatus = Schemas["TaskStatus"];
3565
- /** The `202` body of `crawl`. */
4170
+ /** The `202` body of `crawl` and `research`. */
3566
4171
  type TaskCreated = Schemas["TaskCreated"];
3567
4172
  type TaskCancelResponse = Schemas["TaskCancelResponse"];
3568
4173
  type TaskError = Schemas["TaskError"];
@@ -3581,6 +4186,24 @@ type CrawlStats = CrawlResult["stats"];
3581
4186
  /** Why a crawl ended (`result.stats.stopped`). */
3582
4187
  type CrawlStopReason = NonNullable<CrawlStats["stopped"]>;
3583
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"]>;
3584
4207
  /**
3585
4208
  * Body of `POST /v1/monitors`. `search` and `news` monitors need `q`; `webpage` monitors need
3586
4209
  * `url` (and take only `country` besides) and report the page when its content changes.
@@ -3629,10 +4252,17 @@ type BatchCompletedEvent = Omit<Batch, "poll_url" | "webhook_url" | "webhook_sta
3629
4252
  event: "batch.completed";
3630
4253
  };
3631
4254
  /**
3632
- * 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
3633
4257
  * `result_omitted` is true: fetch the task from `poll_url`.
3634
4258
  */
3635
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
+ };
3636
4266
  /**
3637
4267
  * Body of `monitor.results`. `run_id` is also the `X-SerpKite-Delivery` header (dedupe retries
3638
4268
  * on it). Carries the monitor's `metadata`, and `url` for webpage monitors (whose `new_results`
@@ -3640,7 +4270,7 @@ type TaskCompletedEvent = Schemas["TaskCompletedEvent"];
3640
4270
  */
3641
4271
  type MonitorResultsEvent = Schemas["MonitorResultsEvent"];
3642
4272
  /** `X-SerpKite-Event` values. Plain strings stay accepted for events added later. */
3643
- type WebhookEventType = "batch.completed" | "crawl.completed" | "monitor.results" | (string & {});
4273
+ type WebhookEventType = "batch.completed" | "crawl.completed" | "research.completed" | "monitor.results" | (string & {});
3644
4274
  /** A verified webhook delivery, from `parseWebhook`. */
3645
4275
  type WebhookEvent = {
3646
4276
  type: "batch.completed";
@@ -3650,13 +4280,17 @@ type WebhookEvent = {
3650
4280
  type: "crawl.completed";
3651
4281
  deliveryId: string | undefined;
3652
4282
  data: TaskCompletedEvent;
4283
+ } | {
4284
+ type: "research.completed";
4285
+ deliveryId: string | undefined;
4286
+ data: ResearchCompletedEvent;
3653
4287
  } | {
3654
4288
  type: "monitor.results";
3655
4289
  deliveryId: string | undefined;
3656
4290
  data: MonitorResultsEvent;
3657
4291
  };
3658
4292
 
3659
- declare const VERSION = "0.6.0";
4293
+ declare const VERSION = "0.7.0";
3660
4294
  declare const DEFAULT_BASE_URL = "https://api.serpkite.com";
3661
4295
  interface SerpKiteOptions {
3662
4296
  /** API key (`skt_live_…`). Defaults to the `SERPKITE_API_KEY` environment variable. */
@@ -3707,8 +4341,9 @@ interface BatchCreateOptions extends RequestOptions {
3707
4341
  }
3708
4342
  interface WaitOptions {
3709
4343
  /**
3710
- * Give up after this many milliseconds. Default 600000 (10 minutes) for batches and
3711
- * 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`.
3712
4347
  */
3713
4348
  timeoutMs?: number;
3714
4349
  /** First delay between polls. Default 1000. Grows 1.5× per poll. */
@@ -3757,6 +4392,7 @@ declare class SerpKite {
3757
4392
  related_searches: components["schemas"]["RelatedSearch"][];
3758
4393
  top_stories?: components["schemas"]["NewsResult"][];
3759
4394
  places?: components["schemas"]["PlaceResult"][];
4395
+ answer?: components["schemas"]["SearchAnswer"];
3760
4396
  meta: components["schemas"]["Meta"];
3761
4397
  }>;
3762
4398
  /** Google Images. */
@@ -3775,6 +4411,7 @@ declare class SerpKite {
3775
4411
  readonly news: VerticalMethod<SearchParams, {
3776
4412
  request: components["schemas"]["RequestEcho"];
3777
4413
  results: components["schemas"]["NewsResult"][];
4414
+ answer?: components["schemas"]["SearchAnswer"];
3778
4415
  meta: components["schemas"]["Meta"];
3779
4416
  }>;
3780
4417
  /**
@@ -3873,6 +4510,10 @@ declare class SerpKite {
3873
4510
  * Read up to 20 URLs (HTML or PDF) as Markdown, text or HTML in one call, with optional
3874
4511
  * query-ranked `highlights` (BM25), `include_links` and `include_images`. 1 credit per URL
3875
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.
3876
4517
  */
3877
4518
  extract(params: ExtractParams, options?: RequestOptions): Promise<ExtractResponse>;
3878
4519
  /**
@@ -3884,6 +4525,29 @@ declare class SerpKite {
3884
4525
  map(params: MapParams, options?: RequestOptions): Promise<MapResponse>;
3885
4526
  /** Balance, limits and this month's usage for the key's account. */
3886
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>;
3887
4551
  /**
3888
4552
  * Starts an async crawl of one site and returns the queued task (`202`). 1 credit per page
3889
4553
  * read (0.5 from cache); `limit` credits (up to 1000 pages, `max_depth` up to 10) are
@@ -3906,6 +4570,33 @@ declare class SerpKite {
3906
4570
  waitForCrawl(idOrTask: string | {
3907
4571
  id: string;
3908
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>;
3909
4600
  readonly monitors: {
3910
4601
  /**
3911
4602
  * Saves a `search` or `news` request (`q`) that runs on a schedule (hourly to monthly) and
@@ -4022,7 +4713,7 @@ interface VerifyWebhookOptions {
4022
4713
  }
4023
4714
  type HeaderSource = Headers | Record<string, string | string[] | undefined>;
4024
4715
  /**
4025
- * Checks a webhook delivery (any event: `batch.completed`, `crawl.completed`,
4716
+ * Checks a webhook delivery (any event: `batch.completed`, `crawl.completed`, `research.completed`,
4026
4717
  * `monitor.results`): `X-SerpKite-Signature` must be
4027
4718
  * `v1=<hex HMAC-SHA256(secret, "<X-SerpKite-Timestamp>.<raw body>")>` and the
4028
4719
  * timestamp recent. Pass the raw request body exactly as received (not
@@ -4037,7 +4728,7 @@ declare function verifyWebhook(secret: string, payload: string | Uint8Array, hea
4037
4728
  * Verifies a delivery (see {@link verifyWebhook}) and returns it typed by its
4038
4729
  * `X-SerpKite-Event` header. `deliveryId` is `X-SerpKite-Delivery` (for
4039
4730
  * `monitor.results` it equals `data.run_id`): use it to deduplicate retries. A
4040
- * `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
4041
4732
  * `result_omitted: true`; fetch it from `data.poll_url`. Throws a
4042
4733
  * `SerpKiteError` with code `invalid_signature` when the signature or timestamp
4043
4734
  * doesn't check out.
@@ -4049,4 +4740,4 @@ declare function verifyWebhook(secret: string, payload: string | Uint8Array, hea
4049
4740
  */
4050
4741
  declare function parseWebhook(secret: string, payload: string | Uint8Array, headers: HeaderSource, options?: VerifyWebhookOptions): Promise<WebhookEvent>;
4051
4742
 
4052
- 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 };