serpkite 0.3.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -156,7 +156,17 @@ interface paths {
156
156
  };
157
157
  get?: never;
158
158
  put?: never;
159
- /** Google Maps search (places with coordinates). Accepts `ll` ("@lat,lng,zoomz") to search around a point */
159
+ /**
160
+ * Google Maps search (places with coordinates). Accepts `ll` ("@lat,lng,zoomz") to search around a point
161
+ * @description Google Maps search results: name, full address, coordinates, categories, rating, website,
162
+ * phone, opening hours and the place's identifiers (`place_id`, `cid`, `fid`) for
163
+ * `/v1/place` and `/v1/reviews`. Categories, addresses and hours are in `language`.
164
+ *
165
+ * **Where:** `ll` ("@lat,lng,zoomz") searches the map at that point and zoom; `location`
166
+ * (or `uule`) searches the named place. Without either, Google picks the area from the
167
+ * query (an exact name or address) or from where the request comes from, so local queries
168
+ * such as "coffee" need `location` or `ll`.
169
+ */
160
170
  post: operations["maps"];
161
171
  delete?: never;
162
172
  options?: never;
@@ -173,7 +183,10 @@ interface paths {
173
183
  };
174
184
  get?: never;
175
185
  put?: never;
176
- /** Google local results (places) */
186
+ /**
187
+ * Google local results (places)
188
+ * @description Same results as `/v1/maps` (Google Maps search), with the same fields and location rules.
189
+ */
177
190
  post: operations["places"];
178
191
  delete?: never;
179
192
  options?: never;
@@ -181,6 +194,29 @@ interface paths {
181
194
  patch?: never;
182
195
  trace?: never;
183
196
  };
197
+ "/v1/place": {
198
+ parameters: {
199
+ query?: never;
200
+ header?: never;
201
+ path?: never;
202
+ cookie?: never;
203
+ };
204
+ get?: never;
205
+ put?: never;
206
+ /**
207
+ * Details of one place (by `place_id`, `cid` or `fid`); 1 credit
208
+ * @description The full Google Maps listing of one place: address, country, coordinates, time zone,
209
+ * categories, opening hours (as text and as structured `weekly_hours`), website, phone,
210
+ * rating, description and photos, in `language`. `results` holds the place, or is empty
211
+ * (not charged) when no place has that identifier.
212
+ */
213
+ post: operations["place"];
214
+ delete?: never;
215
+ options?: never;
216
+ head?: never;
217
+ patch?: never;
218
+ trace?: never;
219
+ };
184
220
  "/v1/reviews": {
185
221
  parameters: {
186
222
  query?: never;
@@ -275,7 +311,7 @@ interface paths {
275
311
  };
276
312
  get?: never;
277
313
  put?: never;
278
- /** Fetch any public URL and return clean Markdown + metadata (1 credit) */
314
+ /** Fetch any public URL (HTML or PDF) and return clean Markdown + metadata (1 credit) */
279
315
  post: operations["webpage"];
280
316
  delete?: never;
281
317
  options?: never;
@@ -283,6 +319,214 @@ interface paths {
283
319
  patch?: never;
284
320
  trace?: never;
285
321
  };
322
+ "/v1/extract": {
323
+ parameters: {
324
+ query?: never;
325
+ header?: never;
326
+ path?: never;
327
+ cookie?: never;
328
+ };
329
+ get?: never;
330
+ put?: never;
331
+ /**
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)
333
+ * @description Every URL is billed only when it comes back: 1 credit, 0.5 from cache. URLs that
334
+ * fail are listed in `failed` and cost nothing. The response is `200` even when every
335
+ * URL failed. Highlights are ranked with BM25 (lexical, no model).
336
+ */
337
+ post: operations["extract"];
338
+ delete?: never;
339
+ options?: never;
340
+ head?: never;
341
+ patch?: never;
342
+ trace?: never;
343
+ };
344
+ "/v1/map": {
345
+ parameters: {
346
+ query?: never;
347
+ header?: never;
348
+ path?: never;
349
+ cookie?: never;
350
+ };
351
+ get?: never;
352
+ put?: never;
353
+ /**
354
+ * The URLs of a site, from robots.txt sitemaps and the start page's links, optionally ranked by a search (1 credit; free when nothing is found)
355
+ * @description Reads the sitemaps listed in robots.txt (or `/sitemap.xml`), following sitemap
356
+ * indexes; XML, gzip, RSS/Atom and plain-text sitemaps are understood. URLs are
357
+ * cleaned (fragment and tracking parameters such as `utm_*`, `gclid` and `fbclid`
358
+ * dropped), kept on the site, filtered by `include_paths` / `exclude_paths` and
359
+ * de-duplicated (`www.`, scheme and trailing slash folded). `search` ranks the URLs
360
+ * by their path words and titles (BM25) and drops the ones that don't match. Takes
361
+ * at most about 30 seconds.
362
+ */
363
+ post: operations["map"];
364
+ delete?: never;
365
+ options?: never;
366
+ head?: never;
367
+ patch?: never;
368
+ trace?: never;
369
+ };
370
+ "/v1/crawl": {
371
+ parameters: {
372
+ query?: never;
373
+ header?: never;
374
+ path?: never;
375
+ cookie?: never;
376
+ };
377
+ get?: never;
378
+ put?: never;
379
+ /**
380
+ * Start an async crawl of one site (1 credit per page read; `limit` credits reserved up front, the rest refunded)
381
+ * @description From `url` and (unless `sitemap: skip`) the site's sitemaps, same host (optionally
382
+ * subdomains), up to `limit` pages and `max_depth` link hops, filtered by
383
+ * `include_paths` / `exclude_paths` (regular expressions matched against the URL
384
+ * path). Breadth first, or best first with `query` (pages whose URL and link text
385
+ * match it are read first). Each host's robots.txt is honoured (RFC 9309: rules,
386
+ * `Crawl-delay`; a robots.txt that answers 5xx stops the crawl at the start page).
387
+ * URLs are canonicalised (fragments and tracking parameters dropped, `www.`,
388
+ * trailing slashes and redirects folded) so each page is read once. Each page comes
389
+ * back as Markdown (or text) with its metadata. A crawl runs for at most 30 minutes
390
+ * and returns up to 16 MB of pages; `result.stats.stopped` says why it ended.
391
+ *
392
+ * Returns `202` with a task; poll `GET /v1/crawl/{id}` or wait for the signed
393
+ * `crawl.completed` webhook. Pages read cost 1 credit each (0.5 from cache); a crawl
394
+ * that read nothing fails (`no_pages`) and is refunded. At most 20 crawls per account
395
+ * may be queued or running at once (`429`); a crawl interrupted by a deploy restarts
396
+ * from the beginning.
397
+ */
398
+ post: operations["createCrawl"];
399
+ delete?: never;
400
+ options?: never;
401
+ head?: never;
402
+ patch?: never;
403
+ trace?: never;
404
+ };
405
+ "/v1/crawl/{id}": {
406
+ parameters: {
407
+ query?: never;
408
+ header?: never;
409
+ path: {
410
+ id: string;
411
+ };
412
+ cookie?: never;
413
+ };
414
+ /** Poll a crawl (kept for 24 hours) */
415
+ get: operations["getCrawl"];
416
+ put?: never;
417
+ post?: never;
418
+ /**
419
+ * Cancel a crawl. A queued crawl is canceled and refunded at once; a running one stops at its next checkpoint and is charged for the pages read
420
+ * @description `404` when there is no such crawl, `409` when it already finished.
421
+ */
422
+ delete: operations["cancelCrawl"];
423
+ options?: never;
424
+ head?: never;
425
+ patch?: never;
426
+ trace?: never;
427
+ };
428
+ "/v1/monitors": {
429
+ parameters: {
430
+ query?: never;
431
+ header?: never;
432
+ path?: never;
433
+ cookie?: never;
434
+ };
435
+ /** List the account's monitors */
436
+ get: operations["listMonitors"];
437
+ put?: never;
438
+ /**
439
+ * Create a monitor — a saved /v1/search or /v1/news request (new results) or a /v1/webpage URL (content changes) that runs on a schedule and reports what is new (signed webhook and run history)
440
+ * @description Runs hourly to monthly (`interval` or `interval_seconds`, default daily); the
441
+ * first run is due right away (unless `active: false`). With `endpoint: webpage`
442
+ * the monitor watches `url` and reports the page (Markdown, `change: new|changed`)
443
+ * whenever its content changes (1 credit per check). Each run is billed like the
444
+ * search it makes (1 credit per 10 results, `num: 100` is 7; empty and failed runs
445
+ * are free) on the monitor's key: the key that created it, or last changed or ran
446
+ * it, under that key's limits and the account's spend cap. Only the fields below
447
+ * are kept; any other search field is a `400`. Results among the
448
+ * top `num` not seen in earlier runs are POSTed as a `monitor.results` webhook when
449
+ * the monitor has a `webhook_url`, and are always listed in its run history
450
+ * (`GET /v1/monitors/{id}/runs`, results kept 24 hours). At most 100 monitors per
451
+ * account (403 `forbidden`). A monitor pauses itself after 10 failed runs in a row
452
+ * (search errors, insufficient credits or webhook failures) or when its key is
453
+ * revoked; set `active: true` to resume.
454
+ */
455
+ post: operations["createMonitor"];
456
+ delete?: never;
457
+ options?: never;
458
+ head?: never;
459
+ patch?: never;
460
+ trace?: never;
461
+ };
462
+ "/v1/monitors/{id}": {
463
+ parameters: {
464
+ query?: never;
465
+ header?: never;
466
+ path: {
467
+ id: string;
468
+ };
469
+ cookie?: never;
470
+ };
471
+ /** Get a monitor */
472
+ get: operations["getMonitor"];
473
+ put?: never;
474
+ post?: never;
475
+ /** Delete a monitor */
476
+ delete: operations["deleteMonitor"];
477
+ options?: never;
478
+ head?: never;
479
+ /** Update a monitor: name, interval, webhook_url (empty string removes it), active, and the saved search (endpoint, q and search options; a changed search starts a new baseline) */
480
+ patch: operations["updateMonitor"];
481
+ trace?: never;
482
+ };
483
+ "/v1/monitors/{id}/runs": {
484
+ parameters: {
485
+ query?: {
486
+ limit?: number;
487
+ /** @description `next_before` of the previous page */
488
+ before?: string;
489
+ };
490
+ header?: never;
491
+ path: {
492
+ id: string;
493
+ };
494
+ cookie?: never;
495
+ };
496
+ /** A monitor's run history, newest first (runs are kept 30 days, their results 24 hours) */
497
+ get: operations["listMonitorRuns"];
498
+ put?: never;
499
+ post?: never;
500
+ delete?: never;
501
+ options?: never;
502
+ head?: never;
503
+ patch?: never;
504
+ trace?: never;
505
+ };
506
+ "/v1/monitors/{id}/run": {
507
+ parameters: {
508
+ query?: never;
509
+ header?: never;
510
+ path: {
511
+ id: string;
512
+ };
513
+ cookie?: never;
514
+ };
515
+ get?: never;
516
+ put?: never;
517
+ /**
518
+ * Run a monitor now (it becomes due at the next scheduler poll, within about 30 seconds)
519
+ * @description The monitor must be active. A paused monitor returns 409; resume it with
520
+ * PATCH {"active": true} first (resuming also makes it due immediately).
521
+ * The monitor is bound to the calling key, which this and later runs are billed to.
522
+ */
523
+ post: operations["runMonitor"];
524
+ delete?: never;
525
+ options?: never;
526
+ head?: never;
527
+ patch?: never;
528
+ trace?: never;
529
+ };
286
530
  "/customsearch/v1": {
287
531
  parameters: {
288
532
  query?: never;
@@ -431,7 +675,15 @@ interface paths {
431
675
  };
432
676
  get?: never;
433
677
  put?: never;
434
- /** Remote MCP server (streamable HTTP, JSON-RPC 2.0). Tools search, news, maps, scholar, webpage */
678
+ /**
679
+ * Remote MCP server (streamable HTTP, JSON-RPC 2.0). Tools search, news, maps, place, scholar, webpage
680
+ * @description Authenticates with an API key (`Authorization: Bearer skt_live_…`) or an
681
+ * OAuth 2.1 access token (`skt_oat_…`) issued by app-api.serpkite.com for
682
+ * this resource (MCP authorization spec). Without a valid credential the
683
+ * 401 carries `WWW-Authenticate: Bearer resource_metadata="…/.well-known/oauth-protected-resource/v1/mcp", scope="mcp"`
684
+ * (plus `error="invalid_token"` when a credential was rejected). OAuth
685
+ * access tokens are only accepted here, not on the REST endpoints.
686
+ */
435
687
  post: operations["mcp"];
436
688
  delete?: never;
437
689
  options?: never;
@@ -439,6 +691,40 @@ interface paths {
439
691
  patch?: never;
440
692
  trace?: never;
441
693
  };
694
+ "/.well-known/oauth-protected-resource/v1/mcp": {
695
+ parameters: {
696
+ query?: never;
697
+ header?: never;
698
+ path?: never;
699
+ cookie?: never;
700
+ };
701
+ /** OAuth protected resource metadata for the MCP server (RFC 9728) */
702
+ get: operations["mcpProtectedResourceMetadata"];
703
+ put?: never;
704
+ post?: never;
705
+ delete?: never;
706
+ options?: never;
707
+ head?: never;
708
+ patch?: never;
709
+ trace?: never;
710
+ };
711
+ "/.well-known/oauth-protected-resource": {
712
+ parameters: {
713
+ query?: never;
714
+ header?: never;
715
+ path?: never;
716
+ cookie?: never;
717
+ };
718
+ /** OAuth protected resource metadata (root form; same document) */
719
+ get: operations["protectedResourceMetadata"];
720
+ put?: never;
721
+ post?: never;
722
+ delete?: never;
723
+ options?: never;
724
+ head?: never;
725
+ patch?: never;
726
+ trace?: never;
727
+ };
442
728
  }
443
729
  interface components {
444
730
  schemas: {
@@ -467,15 +753,34 @@ interface components {
467
753
  request_id?: string;
468
754
  };
469
755
  };
756
+ /** @description RFC 9728 protected resource metadata */
757
+ ProtectedResourceMetadata: {
758
+ /**
759
+ * Format: uri
760
+ * @example https://api.serpkite.com/v1/mcp
761
+ */
762
+ resource: string;
763
+ /**
764
+ * @example [
765
+ * "https://app-api.serpkite.com"
766
+ * ]
767
+ */
768
+ authorization_servers: string[];
769
+ scopes_supported?: string[];
770
+ bearer_methods_supported?: string[];
771
+ resource_name?: string;
772
+ /** Format: uri */
773
+ resource_documentation?: string;
774
+ };
470
775
  SearchRequest: {
471
776
  q: string;
472
777
  /**
473
- * @description Country code (ISO 3166-1 alpha-2, case-insensitive; uk is accepted as gb). When omitted and location ends in a country name, that country is used
778
+ * @description Country code (ISO 3166-1 alpha-2, case-insensitive; uk is accepted as gb). When omitted and location ends in a country name, that country is used. Russia (ru) is supported across all search verticals, including patents, using the shared proxy routes
474
779
  * @default us
475
780
  */
476
781
  country?: string;
477
782
  /**
478
- * @description Interface language: a language code with an optional region (e.g. en, de, pt-br, zh-tw, es-419)
783
+ * @description Interface language: a language code with an optional region (e.g. en, ru, de, pt-br, zh-tw, es-419). Russian (ru) is supported across all search verticals; language does not change the selected country. On patents, a non-English code restricts publication language (ar, zh, da, nl, fi, fr, de, it, ja, ko, no, pt, ru, es, sv)
479
784
  * @default en
480
785
  */
481
786
  language?: string;
@@ -483,7 +788,7 @@ interface components {
483
788
  location?: string;
484
789
  /** @description Pre-encoded Google location (overrides ll and location; percent-encoded values are decoded) */
485
790
  uule?: string;
486
- /** @description Map point "@lat,lng,14z" (maps and places only; zoom optional): the search runs as a searcher at that point. Overrides location */
791
+ /** @description Map point "@lat,lng,14z" (maps and places only; zoom optional, default 14z): the map is searched around that point at that zoom, wherever the request comes from. Overrides location */
487
792
  ll?: string;
488
793
  /**
489
794
  * @description 10, or up to 100 for the depth bundle on search and news (7 credits for 100; values between round up to whole pages). Other verticals return one page of 10
@@ -531,6 +836,37 @@ interface components {
531
836
  /** @description Accept a cached result up to this many seconds old (50% of credits on a hit) */
532
837
  max_age?: number;
533
838
  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 */
840
+ include_domains?: components["schemas"]["DomainList"];
841
+ /** @description Drop results from these domains (search, news, images, videos). Not with engine=consensus */
842
+ exclude_domains?: components["schemas"]["DomainList"];
843
+ /** @description Move results from these domains to the top, keeping the order within both groups (search, news) */
844
+ boost_domains?: components["schemas"]["DomainList"];
845
+ /**
846
+ * Format: date
847
+ * @description Only results published on or after this date, YYYY-MM-DD (search, news, images, videos). Can't be combined with time or tbs. A fallback engine without date ranges is skipped
848
+ */
849
+ start_date?: string;
850
+ /**
851
+ * Format: date
852
+ * @description Only results published on or before this date, YYYY-MM-DD. Can't be combined with time or tbs
853
+ */
854
+ end_date?: string;
855
+ /**
856
+ * @description Return up to 3 query-ranked passages (`highlights`) of each page read by include_content instead of the whole page (search only; needs include_content; no extra credits)
857
+ * @default false
858
+ */
859
+ highlights?: boolean;
860
+ };
861
+ /** @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
+ DomainList: string | string[];
863
+ /** @description A query-relevant passage of a page, verbatim */
864
+ Highlight: {
865
+ text: string;
866
+ /** @description Relevance to the query (BM25; higher is better */
867
+ score: number;
868
+ /** @description The section heading path the passage sits under */
869
+ heading?: string;
534
870
  };
535
871
  /** @description One of place_id, cid or fid is required */
536
872
  ReviewsRequest: {
@@ -540,14 +876,15 @@ interface components {
540
876
  country?: string;
541
877
  language?: string;
542
878
  /**
879
+ * @description Only `most_relevant` is served: Google Maps shows other review orders only to signed-in visitors, so `newest`, `highest_rating` and `lowest_rating` return 400 (not charged).
543
880
  * @default most_relevant
544
881
  * @enum {string}
545
882
  */
546
883
  sort?: "most_relevant" | "newest" | "highest_rating" | "lowest_rating";
547
- /** @description `next_page_token` from the previous page, unchanged. Opaque and bound to the place and `sort` it was issued for (anything else is a 400). Paging reaches the first 100 reviews of a place per sort order. */
884
+ /** @description `next_page_token` from the previous page, unchanged. Opaque and bound to the place and `sort` it was issued for (anything else is a 400). Paging reaches the first 10 reviews of a place, all Google Maps shows a logged-out visitor. */
548
885
  page_token?: string;
549
886
  /**
550
- * @description Reviews per page (a page can be shorter when Google stops loading early; `next_page_token` then resumes after it)
887
+ * @description Reviews per page; a page holds at most 10 (the first 10 reviews of a place). A page can be shorter when Google stops loading early; `next_page_token` then resumes after it
551
888
  * @default 10
552
889
  */
553
890
  num?: number;
@@ -556,8 +893,39 @@ interface components {
556
893
  fields?: string;
557
894
  max_age?: number;
558
895
  };
896
+ /** @description One of place_id, cid or fid is required (place_id wins, then fid, then cid) */
897
+ PlaceRequest: {
898
+ /** @description Google place id ("ChIJ…"), e.g. `place_id` of a /v1/maps result */
899
+ place_id?: string;
900
+ /** @description Decimal customer id (`cid` of a result) */
901
+ cid?: string;
902
+ /** @description Feature id "0x…:0x…" (`fid` of a result) */
903
+ fid?: string;
904
+ /**
905
+ * @description Country code (ISO 3166-1 alpha-2); Google's regional view of the listing
906
+ * @default us
907
+ */
908
+ country?: string;
909
+ /**
910
+ * @description Language of the address, categories, hours and description (e.g. en, ru, de)
911
+ * @default en
912
+ */
913
+ language?: string;
914
+ /**
915
+ * @default json
916
+ * @enum {string}
917
+ */
918
+ format?: "json" | "markdown" | "compact";
919
+ fields?: string;
920
+ /** @description Accept a cached result up to this many seconds old (50% of credits on a hit) */
921
+ max_age?: number;
922
+ engine?: components["schemas"]["EngineParam"];
923
+ };
559
924
  WebpageRequest: {
560
- /** Format: uri */
925
+ /**
926
+ * Format: uri
927
+ * @description An HTML page or a PDF
928
+ */
561
929
  url: string;
562
930
  /**
563
931
  * @default json
@@ -566,38 +934,355 @@ interface components {
566
934
  format?: "json" | "markdown" | "compact";
567
935
  /** @default false */
568
936
  include_html?: boolean;
937
+ /**
938
+ * @description Also return the page's outbound links (`links`)
939
+ * @default false
940
+ */
941
+ include_links?: boolean;
942
+ /**
943
+ * @description Also return the page's image URLs (`image_links`)
944
+ * @default false
945
+ */
946
+ include_images?: boolean;
947
+ /** @description Fetch through an exit in this country (ISO 3166-1 alpha-2) for geo-dependent pages */
948
+ country?: string;
569
949
  max_age?: number;
570
950
  };
571
- /**
572
- * @description A search provider (docs/providers). Which verticals each serves depends on the deployment.
573
- * @enum {string}
574
- */
575
- Provider: "google" | "brave" | "bing" | "yahoo" | "duckduckgo" | "mojeek" | "wikipedia";
576
- /** @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). */
577
- EngineParam: string | components["schemas"]["Provider"][];
578
- /** @description One provider attempt behind this answer. Proxy pools are internal and never listed. */
579
- RouteStep: {
951
+ ExtractRequest: {
952
+ /** @description HTML pages or PDFs (duplicates are dropped) */
953
+ urls: string[];
580
954
  /**
581
- * @example google
582
- * @example brave
955
+ * @default markdown
956
+ * @enum {string}
583
957
  */
584
- provider: string;
585
- /** @enum {string} */
586
- outcome: "ok" | "partial" | "empty" | "soft_empty" | "blocked" | "timeout" | "error" | "unsupported" | "bad_param" | "bad_target" | "canceled";
587
- /** @description Duration of the attempt in milliseconds */
588
- ms: number;
589
- };
590
- Meta: {
591
- request_id: string;
592
- credits_used: number;
958
+ format?: "markdown" | "text" | "html";
959
+ /** @description What highlights are ranked against */
960
+ query?: string;
593
961
  /**
594
- * @description The provider that produced the result (`consensus` for a merged engine=consensus answer)
595
- * @example google
596
- * @example brave
597
- * @example consensus
598
- * @example stub
962
+ * @description Query-ranked passages per page (BM25; needs query)
963
+ * @default 0
599
964
  */
600
- engine?: string;
965
+ highlights?: number;
966
+ /** @description Trim each page's markdown or text to about this many tokens */
967
+ max_tokens?: number;
968
+ /** @default false */
969
+ include_links?: boolean;
970
+ /** @default false */
971
+ include_images?: boolean;
972
+ /** @description Accept a cached page up to this many seconds old (0.5 credit) */
973
+ max_age?: number;
974
+ /** @description Fetch through an exit in this country (ISO 3166-1 alpha-2) */
975
+ country?: string;
976
+ /**
977
+ * @description Seconds to wait for the pages; a page still loading is listed in `failed` (`upstream_timeout`, not charged)
978
+ * @default 50
979
+ */
980
+ timeout?: number;
981
+ };
982
+ ExtractResult: {
983
+ /** @description Final URL after redirects */
984
+ url: string;
985
+ status_code?: number;
986
+ title?: string;
987
+ /** @description The page's published time as ISO 8601, when it has one */
988
+ published_at?: string;
989
+ metadata?: components["schemas"]["PageMetadata"];
990
+ cached: boolean;
991
+ /** @description format=markdown */
992
+ markdown?: string;
993
+ /** @description format=text */
994
+ text?: string;
995
+ /** @description format=html (null for a PDF); at most 2 MiB per page */
996
+ html?: string | null;
997
+ /** @description include_links=true only */
998
+ links?: components["schemas"]["PageLink"][];
999
+ /** @description include_images=true only */
1000
+ images?: string[];
1001
+ /** @description highlights > 0 only */
1002
+ highlights?: components["schemas"]["Highlight"][];
1003
+ };
1004
+ ExtractFailure: {
1005
+ url: string;
1006
+ error: {
1007
+ /**
1008
+ * @example invalid_request
1009
+ * @example upstream_error
1010
+ * @example upstream_timeout
1011
+ * @example empty_page
1012
+ */
1013
+ code: string;
1014
+ message: string;
1015
+ };
1016
+ };
1017
+ ExtractResponse: {
1018
+ request: {
1019
+ /** @constant */
1020
+ endpoint?: "extract";
1021
+ urls?: string[];
1022
+ format?: string;
1023
+ query?: string;
1024
+ } & {
1025
+ [key: string]: unknown;
1026
+ };
1027
+ results: components["schemas"]["ExtractResult"][];
1028
+ failed: components["schemas"]["ExtractFailure"][];
1029
+ meta: {
1030
+ request_id: string;
1031
+ credits_used: number;
1032
+ latency_ms?: number;
1033
+ succeeded: number;
1034
+ failed: number;
1035
+ };
1036
+ };
1037
+ CrawlRequest: {
1038
+ /**
1039
+ * Format: uri
1040
+ * @description Start page (always read: path filters and robots.txt apply to the pages found from it)
1041
+ */
1042
+ url: string;
1043
+ /**
1044
+ * @description Maximum pages read (and credits reserved)
1045
+ * @default 25
1046
+ */
1047
+ limit?: number;
1048
+ /**
1049
+ * @description Link hops from url (sitemap pages count as 1 hop; 0 reads only url)
1050
+ * @default 2
1051
+ */
1052
+ max_depth?: number;
1053
+ /** @description Regular expressions matched against the URL path; follow only paths matching one */
1054
+ include_paths?: string[];
1055
+ /** @description Regular expressions matched against the URL path; never follow paths matching one */
1056
+ exclude_paths?: string[];
1057
+ /** @default false */
1058
+ include_subdomains?: boolean;
1059
+ /**
1060
+ * @description `include` also seeds the crawl with the site's sitemap URLs (after the start page's links), `only` reads the start page and sitemap URLs without following links, `skip` follows links only
1061
+ * @default include
1062
+ * @enum {string}
1063
+ */
1064
+ sitemap?: "include" | "only" | "skip";
1065
+ /** @description Read the pages most relevant to these words first (best-first crawl) */
1066
+ query?: string;
1067
+ /**
1068
+ * @description Treat URLs that differ only in their query string as one page
1069
+ * @default false
1070
+ */
1071
+ ignore_query_parameters?: boolean;
1072
+ /**
1073
+ * @default markdown
1074
+ * @enum {string}
1075
+ */
1076
+ format?: "markdown" | "text";
1077
+ /**
1078
+ * @description Return each page's outbound links
1079
+ * @default false
1080
+ */
1081
+ include_links?: boolean;
1082
+ /** @description Trim each page to this many tokens */
1083
+ max_tokens?: number;
1084
+ /** @description Accept cached pages up to this many seconds old (0.5 credit each) */
1085
+ max_age?: number;
1086
+ /**
1087
+ * Format: uri
1088
+ * @description Receives the signed `crawl.completed` event. Defaults to the account webhook
1089
+ */
1090
+ webhook_url?: string;
1091
+ };
1092
+ /** @enum {string} */
1093
+ TaskStatus: "queued" | "running" | "completed" | "failed" | "canceled";
1094
+ TaskCreated: {
1095
+ /** Format: uuid */
1096
+ id: string;
1097
+ /** @enum {string} */
1098
+ kind: "crawl";
1099
+ status: components["schemas"]["TaskStatus"];
1100
+ /** Format: date-time */
1101
+ created_at: string;
1102
+ poll_url: string;
1103
+ credits_reserved: number;
1104
+ webhook_url?: string | null;
1105
+ };
1106
+ TaskCancelResponse: {
1107
+ /** Format: uuid */
1108
+ id: string;
1109
+ /** @enum {string} */
1110
+ status: "canceled" | "canceling";
1111
+ };
1112
+ /** @description Set when the task failed or was canceled */
1113
+ TaskError: {
1114
+ /**
1115
+ * @example no_pages
1116
+ * @example canceled
1117
+ * @example timeout
1118
+ * @example internal
1119
+ */
1120
+ code?: string;
1121
+ message?: string;
1122
+ } | null;
1123
+ CrawlPage: {
1124
+ url: string;
1125
+ /** @description Link hops from the start page */
1126
+ depth: number;
1127
+ title?: string;
1128
+ markdown?: string;
1129
+ text?: string;
1130
+ published_at?: string;
1131
+ metadata?: components["schemas"]["PageMetadata"];
1132
+ links?: components["schemas"]["PageLink"][];
1133
+ };
1134
+ CrawlResult: {
1135
+ url: string;
1136
+ pages: components["schemas"]["CrawlPage"][];
1137
+ failed: components["schemas"]["ExtractFailure"][];
1138
+ stats: {
1139
+ pages?: number;
1140
+ failed?: number;
1141
+ seconds?: number;
1142
+ /** @description Unique URLs found that passed the filters */
1143
+ discovered?: number;
1144
+ /** @description Found but not read when the crawl ended */
1145
+ queued?: number;
1146
+ /** @description Pages that redirected to a page already read (not charged) */
1147
+ duplicates?: number;
1148
+ /** @description URLs taken from sitemaps */
1149
+ sitemap_urls?: number;
1150
+ /**
1151
+ * @description The start host's robots.txt
1152
+ * @enum {string}
1153
+ */
1154
+ robots?: "found" | "missing" | "unreachable" | "none";
1155
+ /** @description Disallow rules in force on the start host */
1156
+ robots_disallowed?: number;
1157
+ /** @description URLs skipped because robots.txt disallows them */
1158
+ robots_blocked?: number;
1159
+ /** @description The start host's Crawl-delay, honoured */
1160
+ crawl_delay_ms?: number;
1161
+ /**
1162
+ * @description Why the crawl ended
1163
+ * @enum {string}
1164
+ */
1165
+ stopped?: "done" | "limit" | "time_limit" | "size_limit" | "too_many_failures" | "canceled";
1166
+ };
1167
+ };
1168
+ CrawlTask: {
1169
+ /** Format: uuid */
1170
+ id: string;
1171
+ /** @constant */
1172
+ kind: "crawl";
1173
+ status: components["schemas"]["TaskStatus"];
1174
+ /** Format: date-time */
1175
+ created_at: string;
1176
+ /** Format: date-time */
1177
+ started_at?: string | null;
1178
+ /** Format: date-time */
1179
+ completed_at?: string | null;
1180
+ credits_reserved: number;
1181
+ credits_used: number;
1182
+ /** @enum {string|null} */
1183
+ webhook_status?: "pending" | "delivered" | "failed" | null;
1184
+ progress?: ({
1185
+ pages_done?: number;
1186
+ pages_failed?: number;
1187
+ pages_queued?: number;
1188
+ pages_discovered?: number;
1189
+ limit?: number;
1190
+ } & {
1191
+ [key: string]: unknown;
1192
+ }) | null;
1193
+ /** @description Set once the crawl ends (also on cancel, with the pages read so far) */
1194
+ result?: components["schemas"]["CrawlResult"] | null;
1195
+ error?: components["schemas"]["TaskError"];
1196
+ };
1197
+ MapRequest: {
1198
+ /**
1199
+ * Format: uri
1200
+ * @description The site (any page of it; sitemaps are read from its origin)
1201
+ */
1202
+ url: string;
1203
+ /** @description Keep only URLs relevant to these words, most relevant first */
1204
+ search?: string;
1205
+ /** @default 100 */
1206
+ limit?: number;
1207
+ /** @default false */
1208
+ include_subdomains?: boolean;
1209
+ /** @description Regular expressions matched against the URL path; keep only URLs matching one */
1210
+ include_paths?: string[];
1211
+ /** @description Regular expressions matched against the URL path; drop URLs matching one */
1212
+ exclude_paths?: string[];
1213
+ /**
1214
+ * @description Treat URLs that differ only in their query string as one (the first one found is kept)
1215
+ * @default false
1216
+ */
1217
+ ignore_query_parameters?: boolean;
1218
+ /**
1219
+ * @description `include` sitemaps and the start page's links, `only` sitemaps, `skip` sitemaps (links only)
1220
+ * @default include
1221
+ * @enum {string}
1222
+ */
1223
+ sitemap?: "include" | "only" | "skip";
1224
+ };
1225
+ MapURL: {
1226
+ url: string;
1227
+ title?: string;
1228
+ /** @description The sitemap's lastmod, as written */
1229
+ lastmod?: string;
1230
+ /** @enum {string} */
1231
+ source: "sitemap" | "page";
1232
+ };
1233
+ MapResponse: {
1234
+ request: {
1235
+ /** @constant */
1236
+ endpoint?: "map";
1237
+ url?: string;
1238
+ search?: string;
1239
+ limit?: number;
1240
+ sitemap?: string;
1241
+ include_subdomains?: boolean;
1242
+ include_paths?: string[];
1243
+ exclude_paths?: string[];
1244
+ ignore_query_parameters?: boolean;
1245
+ } & {
1246
+ [key: string]: unknown;
1247
+ };
1248
+ results: components["schemas"]["MapURL"][];
1249
+ meta: {
1250
+ request_id: string;
1251
+ credits_used: number;
1252
+ latency_ms?: number;
1253
+ count: number;
1254
+ };
1255
+ };
1256
+ /**
1257
+ * @description A search provider (docs/providers). Which verticals each serves depends on the deployment.
1258
+ * @enum {string}
1259
+ */
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). */
1262
+ EngineParam: string | components["schemas"]["Provider"][];
1263
+ /** @description One provider attempt behind this answer. Proxy pools are internal and never listed. */
1264
+ RouteStep: {
1265
+ /**
1266
+ * @example google
1267
+ * @example brave
1268
+ */
1269
+ provider: string;
1270
+ /** @enum {string} */
1271
+ outcome: "ok" | "partial" | "empty" | "soft_empty" | "blocked" | "timeout" | "error" | "unsupported" | "bad_param" | "bad_target" | "canceled";
1272
+ /** @description Duration of the attempt in milliseconds */
1273
+ ms: number;
1274
+ };
1275
+ Meta: {
1276
+ request_id: string;
1277
+ credits_used: number;
1278
+ /**
1279
+ * @description The provider that produced the result (`consensus` for a merged engine=consensus answer)
1280
+ * @example google
1281
+ * @example brave
1282
+ * @example consensus
1283
+ * @example stub
1284
+ */
1285
+ engine?: string;
601
1286
  /** @description Provider attempts in order (fresh results only; absent on cache hits). With engine=consensus, every provider started; ones stopped early are `canceled`, ones cut off by the deadline `timeout` */
602
1287
  route?: components["schemas"]["RouteStep"][];
603
1288
  cached: boolean;
@@ -628,6 +1313,10 @@ interface components {
628
1313
  device?: string;
629
1314
  autocorrect?: boolean;
630
1315
  tbs?: string;
1316
+ /** Format: date */
1317
+ start_date?: string;
1318
+ /** Format: date */
1319
+ end_date?: string;
631
1320
  safe?: string;
632
1321
  place_id?: string;
633
1322
  cid?: string;
@@ -635,6 +1324,10 @@ interface components {
635
1324
  sort?: string;
636
1325
  include_content?: number;
637
1326
  format?: string;
1327
+ include_domains?: string[];
1328
+ exclude_domains?: string[];
1329
+ boost_domains?: string[];
1330
+ highlights?: boolean;
638
1331
  } & {
639
1332
  [key: string]: unknown;
640
1333
  };
@@ -659,8 +1352,16 @@ interface components {
659
1352
  };
660
1353
  rating?: number;
661
1354
  rating_count?: number;
1355
+ /**
1356
+ * @description `date` as an ISO 8601 date or date-time when it parses (relative dates resolved against the fetch time)
1357
+ * @example 2026-09-30
1358
+ * @example 2026-10-03T09:00:00Z
1359
+ */
1360
+ published_at?: string;
662
1361
  /** @description Page Markdown when include_content covered this result */
663
1362
  content?: string;
1363
+ /** @description highlights=true only. Query-ranked passages of the fetched page, best first (instead of content) */
1364
+ highlights?: components["schemas"]["Highlight"][];
664
1365
  /**
665
1366
  * @description engine=consensus only. The providers that returned this result, in route order; results are ranked by how many there are
666
1367
  * @example [
@@ -738,6 +1439,8 @@ interface components {
738
1439
  source?: string;
739
1440
  channel?: string;
740
1441
  date?: string;
1442
+ /** @description `date` as ISO 8601 when it parses */
1443
+ published_at?: string;
741
1444
  };
742
1445
  VideosResponse: {
743
1446
  request: components["schemas"]["RequestEcho"];
@@ -751,6 +1454,8 @@ interface components {
751
1454
  domain?: string;
752
1455
  snippet?: string;
753
1456
  date?: string;
1457
+ /** @description `date` as ISO 8601 when it parses */
1458
+ published_at?: string;
754
1459
  source?: string;
755
1460
  image_url?: string;
756
1461
  };
@@ -772,14 +1477,63 @@ interface components {
772
1477
  types?: string[];
773
1478
  website?: string;
774
1479
  phone_number?: string;
1480
+ /** @example +44 20 7232 3010 */
1481
+ 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"} */
775
1483
  opening_hours?: {
776
1484
  [key: string]: string;
777
1485
  };
1486
+ weekly_hours?: components["schemas"]["WeeklyHours"];
1487
+ /** @description ISO 3166-1 alpha-2 country code of the place, upper case (RU, GB) */
1488
+ country?: string;
1489
+ /** @description IANA time zone of the place (Europe/Moscow) */
1490
+ timezone?: string;
1491
+ /** @description Google's short description of the place, or the owner's, when Google shows one */
1492
+ description?: string;
1493
+ /** @description Photos of the place (/v1/place; up to 10). The URLs are public and can be fetched server-side without cookies */
1494
+ photos?: components["schemas"]["PlacePhoto"][];
1495
+ /** @description The place on Google Maps */
1496
+ google_maps_url?: string;
778
1497
  thumbnail_url?: string;
779
1498
  place_id?: string;
780
1499
  cid?: string;
781
1500
  fid?: string;
782
1501
  };
1502
+ /**
1503
+ * @description Opening hours per weekday, from Google's listing, as local times (`timezone`) in 24-hour HH:MM.
1504
+ * A day that is closed is an empty list; a day open 24 hours is `[{"open": "00:00", "close": "24:00"}]`;
1505
+ * 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.
1507
+ */
1508
+ WeeklyHours: {
1509
+ monday?: components["schemas"]["HoursIntervals"];
1510
+ tuesday?: components["schemas"]["HoursIntervals"];
1511
+ wednesday?: components["schemas"]["HoursIntervals"];
1512
+ thursday?: components["schemas"]["HoursIntervals"];
1513
+ friday?: components["schemas"]["HoursIntervals"];
1514
+ saturday?: components["schemas"]["HoursIntervals"];
1515
+ sunday?: components["schemas"]["HoursIntervals"];
1516
+ };
1517
+ HoursIntervals: components["schemas"]["HoursInterval"][];
1518
+ HoursInterval: {
1519
+ /** @example 08:00 */
1520
+ open: string;
1521
+ /** @example 22:00 */
1522
+ close: string;
1523
+ /** @description The interval closes after midnight, on the next day */
1524
+ next_day?: boolean;
1525
+ };
1526
+ PlacePhoto: {
1527
+ /** @description Image URL (at most 1600 px on the long side) */
1528
+ url: string;
1529
+ width?: number;
1530
+ height?: number;
1531
+ /**
1532
+ * @description Who uploaded it, when Google says (Google shows no contributor names to logged-out visitors)
1533
+ * @enum {string}
1534
+ */
1535
+ source?: "business" | "visitor";
1536
+ };
783
1537
  PlacesResponse: {
784
1538
  request: components["schemas"]["RequestEcho"];
785
1539
  results: components["schemas"]["PlaceResult"][];
@@ -883,6 +1637,20 @@ interface components {
883
1637
  image?: string;
884
1638
  published_time?: string;
885
1639
  author?: string;
1640
+ /**
1641
+ * @description The page's media type
1642
+ * @example text/html
1643
+ * @example application/pdf
1644
+ */
1645
+ content_type?: string;
1646
+ /** @description Page count of a PDF */
1647
+ pages?: number;
1648
+ };
1649
+ PageLink: {
1650
+ /** @description Absolute URL */
1651
+ url: string;
1652
+ /** @description Anchor text */
1653
+ text?: string;
886
1654
  };
887
1655
  WebpageResponse: {
888
1656
  request: components["schemas"]["RequestEcho"];
@@ -894,6 +1662,10 @@ interface components {
894
1662
  /** @description Only with include_html=true */
895
1663
  html?: string;
896
1664
  metadata: components["schemas"]["PageMetadata"];
1665
+ /** @description include_links=true only. Outbound links in document order, deduplicated */
1666
+ links?: components["schemas"]["PageLink"][];
1667
+ /** @description include_images=true only. Image URLs in document order */
1668
+ image_links?: string[];
897
1669
  meta: components["schemas"]["Meta"];
898
1670
  };
899
1671
  CSEResponse: {
@@ -970,13 +1742,15 @@ interface components {
970
1742
  requests: number;
971
1743
  /** @description Share of requests without a 5xx (0-1) */
972
1744
  success_rate: number;
1745
+ /** @description Median latency of successful (non-error) responses; 0 when none succeeded */
973
1746
  p50_ms: number;
1747
+ /** @description 95th-percentile latency of successful (non-error) responses; 0 when none succeeded */
974
1748
  p95_ms: number;
975
1749
  }[];
976
1750
  };
977
1751
  BatchCreateRequest: {
978
1752
  /** @enum {string} */
979
- endpoint: "search" | "images" | "videos" | "news" | "maps" | "places" | "reviews" | "shopping" | "scholar" | "patents" | "autocomplete" | "webpage";
1753
+ endpoint: "search" | "images" | "videos" | "news" | "maps" | "places" | "place" | "reviews" | "shopping" | "scholar" | "patents" | "autocomplete" | "webpage";
980
1754
  /** @description Request bodies for `endpoint` (same fields as the realtime endpoint) */
981
1755
  requests: {
982
1756
  [key: string]: unknown;
@@ -1033,54 +1807,325 @@ interface components {
1033
1807
  requests: number;
1034
1808
  };
1035
1809
  };
1036
- };
1037
- responses: {
1038
- /** @description Error */
1039
- Error: {
1040
- headers: {
1041
- [name: string]: unknown;
1042
- };
1043
- content: {
1044
- "application/json": components["schemas"]["Error"];
1810
+ /** @description Body of `crawl.completed` */
1811
+ TaskCompletedEvent: {
1812
+ /** @constant */
1813
+ event: "crawl.completed";
1814
+ /** Format: uuid */
1815
+ id: string;
1816
+ /** @constant */
1817
+ kind: "crawl";
1818
+ status: components["schemas"]["TaskStatus"];
1819
+ /** Format: date-time */
1820
+ created_at: string;
1821
+ /** Format: date-time */
1822
+ completed_at?: string | null;
1823
+ credits_used: number;
1824
+ /** @description Where the task (and its full result) can be fetched for 24 hours */
1825
+ 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) */
1827
+ result?: unknown;
1828
+ /** @description Set when the result was too large for the webhook; GET poll_url for it */
1829
+ result_omitted?: boolean;
1830
+ error?: {
1831
+ code?: string;
1832
+ message?: string;
1045
1833
  };
1046
1834
  };
1047
- /**
1048
- * @description Temporarily unavailable, not billed, safe to retry after `Retry-After`.
1049
- * Codes: `upstream_error` (the upstream page couldn't be fetched or parsed),
1050
- * `upstream_blocked` (the upstream is rate limiting us), `upstream_timeout`
1051
- * (the search took too long), `unavailable` (endpoint or dependency down).
1052
- * The API never sends 502 or 504.
1053
- */
1054
- Unavailable: {
1055
- headers: {
1056
- "Retry-After": components["headers"]["RetryAfter"];
1057
- [name: string]: unknown;
1058
- };
1059
- content: {
1060
- "application/json": components["schemas"]["Error"];
1061
- };
1835
+ /** @description The saved request a monitor reruns: a search (q and options) or, for webpage monitors, url (and country) */
1836
+ MonitorSearch: {
1837
+ q?: string;
1838
+ url?: string;
1839
+ country?: string;
1840
+ language?: string;
1841
+ location?: string;
1842
+ /** @enum {string} */
1843
+ time?: "hour" | "day" | "week" | "month" | "year";
1844
+ num?: number;
1845
+ device?: string;
1846
+ safe?: string;
1847
+ include_domains?: string[];
1848
+ exclude_domains?: string[];
1849
+ engine?: string[];
1062
1850
  };
1063
- /** @description OK (text/markdown when format=markdown) */
1064
- SearchOK: {
1065
- headers: {
1066
- "X-Credits-Used": components["headers"]["CreditsUsed"];
1067
- "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
1068
- "X-Cost-USD": components["headers"]["CostUSD"];
1069
- "X-Cache": components["headers"]["Cache"];
1070
- "X-Latency-Ms": components["headers"]["LatencyMs"];
1071
- "X-Tokens-Estimate": components["headers"]["TokensEstimate"];
1072
- [name: string]: unknown;
1073
- };
1074
- content: {
1075
- "application/json": components["schemas"]["SearchResponse"];
1076
- "text/markdown": string;
1851
+ /** @description Search and news monitors need `q`; webpage monitors need `url` and take only `country` besides */
1852
+ MonitorCreateRequest: {
1853
+ q?: string;
1854
+ /**
1855
+ * Format: uri
1856
+ * @description endpoint=webpage: the page to watch for content changes
1857
+ */
1858
+ url?: string;
1859
+ /**
1860
+ * @default search
1861
+ * @enum {string}
1862
+ */
1863
+ endpoint?: "search" | "news" | "webpage";
1864
+ /** @description Your own JSON object (at most 2 KB), echoed on the monitor and in its webhooks */
1865
+ metadata?: {
1866
+ [key: string]: unknown;
1077
1867
  };
1868
+ name?: string;
1869
+ /**
1870
+ * @default daily
1871
+ * @enum {string}
1872
+ */
1873
+ interval?: "hourly" | "daily" | "weekly";
1874
+ /** @description Overrides interval */
1875
+ interval_seconds?: number;
1876
+ /**
1877
+ * Format: uri
1878
+ * @description Receives signed `monitor.results` events. Without one, read new results from the run history
1879
+ */
1880
+ webhook_url?: string;
1881
+ /**
1882
+ * @description false creates the monitor paused
1883
+ * @default true
1884
+ */
1885
+ active?: boolean;
1886
+ country?: string;
1887
+ language?: string;
1888
+ location?: string;
1889
+ /** @enum {string} */
1890
+ time?: "hour" | "day" | "week" | "month" | "year";
1891
+ num?: number;
1892
+ /** @enum {string} */
1893
+ device?: "desktop" | "mobile";
1894
+ /** @enum {string} */
1895
+ safe?: "active" | "off";
1896
+ include_domains?: components["schemas"]["DomainList"];
1897
+ exclude_domains?: components["schemas"]["DomainList"];
1898
+ engine?: components["schemas"]["EngineParam"];
1078
1899
  };
1079
- /** @description OK (text/markdown when format=markdown) */
1080
- ImagesOK: {
1081
- headers: {
1082
- "X-Credits-Used": components["headers"]["CreditsUsed"];
1083
- "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
1900
+ /** @description Only the fields sent change. Search fields are merged into the saved search; a changed search (or endpoint) makes the next run report every result as new. */
1901
+ MonitorUpdateRequest: {
1902
+ name?: string;
1903
+ /** @enum {string} */
1904
+ interval?: "hourly" | "daily" | "weekly";
1905
+ interval_seconds?: number;
1906
+ /** @description A webhook URL, or an empty string to remove it */
1907
+ webhook_url?: string;
1908
+ /** @description true resumes a paused monitor (due now, failure streak cleared) */
1909
+ active?: boolean;
1910
+ /** @description Replaces the metadata (null clears it) */
1911
+ metadata?: {
1912
+ [key: string]: unknown;
1913
+ } | null;
1914
+ /**
1915
+ * @description Switching between a search and a page drops the other kind's fields
1916
+ * @enum {string}
1917
+ */
1918
+ endpoint?: "search" | "news" | "webpage";
1919
+ q?: string;
1920
+ /**
1921
+ * Format: uri
1922
+ * @description endpoint=webpage only
1923
+ */
1924
+ url?: string;
1925
+ country?: string;
1926
+ language?: string;
1927
+ location?: string;
1928
+ /** @enum {string} */
1929
+ time?: "hour" | "day" | "week" | "month" | "year";
1930
+ num?: number;
1931
+ /** @enum {string} */
1932
+ device?: "desktop" | "mobile";
1933
+ /** @enum {string} */
1934
+ safe?: "active" | "off";
1935
+ include_domains?: components["schemas"]["DomainList"];
1936
+ exclude_domains?: components["schemas"]["DomainList"];
1937
+ engine?: components["schemas"]["EngineParam"];
1938
+ };
1939
+ Monitor: {
1940
+ /** Format: uuid */
1941
+ id: string;
1942
+ name: string;
1943
+ /** @enum {string} */
1944
+ endpoint: "search" | "news" | "webpage";
1945
+ request: components["schemas"]["MonitorSearch"];
1946
+ metadata?: {
1947
+ [key: string]: unknown;
1948
+ } | null;
1949
+ interval_seconds: number;
1950
+ /** @description Null when new results are only kept in the run history */
1951
+ webhook_url: string | null;
1952
+ active: boolean;
1953
+ /** Format: date-time */
1954
+ next_run_at: string;
1955
+ /** Format: date-time */
1956
+ last_run_at?: string | null;
1957
+ /** @enum {string|null} */
1958
+ last_status?: "ok" | "error" | "webhook_failed" | "paused" | null;
1959
+ last_error?: string | null;
1960
+ /** @description New results found by the last run */
1961
+ last_new_results?: number;
1962
+ runs: number;
1963
+ /** @description Failed runs in a row; the monitor pauses itself at 10 */
1964
+ consecutive_failures: number;
1965
+ /** @description Total over all runs */
1966
+ credits_used: number;
1967
+ /** Format: date-time */
1968
+ created_at: string;
1969
+ };
1970
+ MonitorRun: {
1971
+ /** Format: uuid */
1972
+ id: string;
1973
+ /** @enum {string} */
1974
+ status: "ok" | "error" | "webhook_failed" | "paused";
1975
+ error?: string | null;
1976
+ new_results: number;
1977
+ /** @description The new results (OrganicResult-shaped for search, NewsResult for news, MonitorPageChange for webpage); null when there were none or after 24 hours */
1978
+ results?: {
1979
+ [key: string]: unknown;
1980
+ }[] | null;
1981
+ credits_used: number;
1982
+ /**
1983
+ * @description none = the monitor has no webhook; null = nothing to send
1984
+ * @enum {string|null}
1985
+ */
1986
+ webhook_status?: "delivered" | "failed" | "none" | null;
1987
+ /** Format: date-time */
1988
+ created_at: string;
1989
+ };
1990
+ /** @description What a webpage monitor reports when the page is new to it or its content changed */
1991
+ MonitorPageChange: {
1992
+ /** @description Final URL after redirects */
1993
+ url: string;
1994
+ title?: string;
1995
+ /** @enum {string} */
1996
+ change: "new" | "changed";
1997
+ /** @description Fingerprint of the content (whitespace-insensitive) */
1998
+ content_hash: string;
1999
+ /** @description The page's Markdown (up to about 8 */
2000
+ markdown: string;
2001
+ published_at?: string;
2002
+ };
2003
+ MonitorRunList: {
2004
+ results: components["schemas"]["MonitorRun"][];
2005
+ /**
2006
+ * Format: uuid
2007
+ * @description Pass as `before` for the next page; null on the last page
2008
+ */
2009
+ next_before: string | null;
2010
+ };
2011
+ MonitorList: {
2012
+ results: components["schemas"]["Monitor"][];
2013
+ };
2014
+ /** @description Body of `monitor.results` */
2015
+ MonitorResultsEvent: {
2016
+ /** @constant */
2017
+ event: "monitor.results";
2018
+ /** Format: uuid */
2019
+ monitor_id: string;
2020
+ /**
2021
+ * Format: uuid
2022
+ * @description Also the X-SerpKite-Delivery header; use it to deduplicate retries
2023
+ */
2024
+ run_id: string;
2025
+ name: string;
2026
+ /** @enum {string} */
2027
+ endpoint: "search" | "news" | "webpage";
2028
+ /** @description The saved query (empty for webpage monitors) */
2029
+ q: string;
2030
+ /** @description webpage monitors only */
2031
+ url?: string;
2032
+ /** @description The monitor's metadata */
2033
+ metadata?: {
2034
+ [key: string]: unknown;
2035
+ } | null;
2036
+ /** @description The first run since the monitor was created or its search changed */
2037
+ first_run: boolean;
2038
+ /** Format: date-time */
2039
+ run_at: string;
2040
+ /** @description Results not seen in earlier runs (OrganicResult-shaped for search, NewsResult for news, MonitorPageChange for webpage) */
2041
+ new_results: {
2042
+ [key: string]: unknown;
2043
+ }[];
2044
+ /** @description This run's price */
2045
+ credits_used: number;
2046
+ };
2047
+ };
2048
+ responses: {
2049
+ /** @description Error */
2050
+ Error: {
2051
+ headers: {
2052
+ [name: string]: unknown;
2053
+ };
2054
+ content: {
2055
+ "application/json": components["schemas"]["Error"];
2056
+ };
2057
+ };
2058
+ /**
2059
+ * @description Temporarily unavailable, not billed, safe to retry after `Retry-After`.
2060
+ * Codes: `upstream_error` (the upstream page couldn't be fetched or parsed),
2061
+ * `upstream_blocked` (the upstream is rate limiting us), `upstream_timeout`
2062
+ * (the search took too long), `unavailable` (endpoint or dependency down).
2063
+ * The API never sends 502 or 504.
2064
+ */
2065
+ Unavailable: {
2066
+ headers: {
2067
+ "Retry-After": components["headers"]["RetryAfter"];
2068
+ [name: string]: unknown;
2069
+ };
2070
+ content: {
2071
+ "application/json": components["schemas"]["Error"];
2072
+ };
2073
+ };
2074
+ /** @description Queued. Poll `poll_url` or wait for the webhook */
2075
+ TaskAccepted: {
2076
+ headers: {
2077
+ /** @description The maximum price, reserved until the task ends */
2078
+ "X-Credits-Reserved"?: number;
2079
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
2080
+ /** @description Path of the task (`/v1/{kind}/{id}`) */
2081
+ Location?: string;
2082
+ [name: string]: unknown;
2083
+ };
2084
+ content: {
2085
+ /**
2086
+ * @example {
2087
+ * "id": "01926a3e-7b2c-7c4e-9f1a-2b3c4d5e6f70",
2088
+ * "kind": "crawl",
2089
+ * "status": "queued",
2090
+ * "created_at": "2026-10-03T12:00:00Z",
2091
+ * "poll_url": "https://api.serpkite.com/v1/crawl/01926a3e-7b2c-7c4e-9f1a-2b3c4d5e6f70",
2092
+ * "credits_reserved": 50,
2093
+ * "webhook_url": null
2094
+ * }
2095
+ */
2096
+ "application/json": components["schemas"]["TaskCreated"];
2097
+ };
2098
+ };
2099
+ /** @description `canceled` (it was queued: refunded at once) or `canceling` (it is running and stops at its next checkpoint) */
2100
+ TaskCanceled: {
2101
+ headers: {
2102
+ [name: string]: unknown;
2103
+ };
2104
+ content: {
2105
+ "application/json": components["schemas"]["TaskCancelResponse"];
2106
+ };
2107
+ };
2108
+ /** @description OK (text/markdown when format=markdown) */
2109
+ SearchOK: {
2110
+ headers: {
2111
+ "X-Credits-Used": components["headers"]["CreditsUsed"];
2112
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
2113
+ "X-Cost-USD": components["headers"]["CostUSD"];
2114
+ "X-Cache": components["headers"]["Cache"];
2115
+ "X-Latency-Ms": components["headers"]["LatencyMs"];
2116
+ "X-Tokens-Estimate": components["headers"]["TokensEstimate"];
2117
+ [name: string]: unknown;
2118
+ };
2119
+ content: {
2120
+ "application/json": components["schemas"]["SearchResponse"];
2121
+ "text/markdown": string;
2122
+ };
2123
+ };
2124
+ /** @description OK (text/markdown when format=markdown) */
2125
+ ImagesOK: {
2126
+ headers: {
2127
+ "X-Credits-Used": components["headers"]["CreditsUsed"];
2128
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
1084
2129
  "X-Cost-USD": components["headers"]["CostUSD"];
1085
2130
  "X-Cache": components["headers"]["Cache"];
1086
2131
  "X-Latency-Ms": components["headers"]["LatencyMs"];
@@ -1220,6 +2265,115 @@ interface components {
1220
2265
  "text/markdown": string;
1221
2266
  };
1222
2267
  };
2268
+ /** @description OK */
2269
+ ExtractOK: {
2270
+ headers: {
2271
+ "X-Credits-Used": components["headers"]["CreditsUsed"];
2272
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
2273
+ "X-Cost-USD": components["headers"]["CostUSD"];
2274
+ "X-Cache": components["headers"]["Cache"];
2275
+ "X-Latency-Ms": components["headers"]["LatencyMs"];
2276
+ "X-Tokens-Estimate": components["headers"]["TokensEstimate"];
2277
+ [name: string]: unknown;
2278
+ };
2279
+ content: {
2280
+ /**
2281
+ * @example {
2282
+ * "request": {
2283
+ * "endpoint": "extract",
2284
+ * "urls": [
2285
+ * "https://example.com/pricing",
2286
+ * "https://example.com/missing"
2287
+ * ],
2288
+ * "format": "markdown",
2289
+ * "query": "enterprise price"
2290
+ * },
2291
+ * "results": [
2292
+ * {
2293
+ * "url": "https://example.com/pricing",
2294
+ * "status_code": 200,
2295
+ * "title": "Pricing",
2296
+ * "metadata": {
2297
+ * "title": "Pricing",
2298
+ * "content_type": "text/html"
2299
+ * },
2300
+ * "cached": false,
2301
+ * "markdown": "# Pricing\n\n…",
2302
+ * "highlights": [
2303
+ * {
2304
+ * "text": "Enterprise: $499 per month …",
2305
+ * "score": 4.83,
2306
+ * "heading": "Plans"
2307
+ * }
2308
+ * ]
2309
+ * }
2310
+ * ],
2311
+ * "failed": [
2312
+ * {
2313
+ * "url": "https://example.com/missing",
2314
+ * "error": {
2315
+ * "code": "upstream_error",
2316
+ * "message": "could not fetch the page: the site answered 404; you were not charged"
2317
+ * }
2318
+ * }
2319
+ * ],
2320
+ * "meta": {
2321
+ * "request_id": "req_01J9",
2322
+ * "credits_used": 1,
2323
+ * "latency_ms": 2210,
2324
+ * "succeeded": 1,
2325
+ * "failed": 1
2326
+ * }
2327
+ * }
2328
+ */
2329
+ "application/json": components["schemas"]["ExtractResponse"];
2330
+ };
2331
+ };
2332
+ /** @description OK */
2333
+ MapOK: {
2334
+ headers: {
2335
+ "X-Credits-Used": components["headers"]["CreditsUsed"];
2336
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
2337
+ "X-Cost-USD": components["headers"]["CostUSD"];
2338
+ "X-Cache": components["headers"]["Cache"];
2339
+ "X-Latency-Ms": components["headers"]["LatencyMs"];
2340
+ "X-Tokens-Estimate": components["headers"]["TokensEstimate"];
2341
+ [name: string]: unknown;
2342
+ };
2343
+ content: {
2344
+ /**
2345
+ * @example {
2346
+ * "request": {
2347
+ * "endpoint": "map",
2348
+ * "url": "https://docs.example.com/",
2349
+ * "limit": 50,
2350
+ * "sitemap": "include",
2351
+ * "include_subdomains": false,
2352
+ * "search": "install guide"
2353
+ * },
2354
+ * "results": [
2355
+ * {
2356
+ * "url": "https://docs.example.com/install",
2357
+ * "lastmod": "2026-09-01",
2358
+ * "source": "sitemap"
2359
+ * },
2360
+ * {
2361
+ * "url": "https://docs.example.com/guide",
2362
+ * "title": "Guide",
2363
+ * "source": "page"
2364
+ * }
2365
+ * ],
2366
+ * "meta": {
2367
+ * "request_id": "req_01J9",
2368
+ * "credits_used": 1,
2369
+ * "latency_ms": 840,
2370
+ * "count": 2
2371
+ * }
2372
+ * }
2373
+ */
2374
+ "application/json": components["schemas"]["MapResponse"];
2375
+ };
2376
+ };
1223
2377
  /** @description OK (text/markdown when format=markdown) */
1224
2378
  WebpageOK: {
1225
2379
  headers: {
@@ -1281,6 +2435,16 @@ interface operations {
1281
2435
  max_age?: number;
1282
2436
  /** @description google (default), auto, consensus, one provider, or a comma-separated list (e.g. google,brave) */
1283
2437
  engine?: string;
2438
+ /** @description Comma-separated domains, or the key repeated (see SearchRequest.include_domains) */
2439
+ include_domains?: string;
2440
+ /** @description Comma-separated domains, or the key repeated */
2441
+ exclude_domains?: string;
2442
+ /** @description Comma-separated domains, or the key repeated */
2443
+ boost_domains?: string;
2444
+ start_date?: string;
2445
+ end_date?: string;
2446
+ /** @description Needs include_content */
2447
+ highlights?: boolean;
1284
2448
  api_key?: string;
1285
2449
  };
1286
2450
  header?: never;
@@ -1406,6 +2570,28 @@ interface operations {
1406
2570
  503: components["responses"]["Unavailable"];
1407
2571
  };
1408
2572
  };
2573
+ place: {
2574
+ parameters: {
2575
+ query?: never;
2576
+ header?: never;
2577
+ path?: never;
2578
+ cookie?: never;
2579
+ };
2580
+ requestBody: {
2581
+ content: {
2582
+ "application/json": components["schemas"]["PlaceRequest"];
2583
+ };
2584
+ };
2585
+ responses: {
2586
+ 200: components["responses"]["PlacesOK"];
2587
+ 400: components["responses"]["Error"];
2588
+ 401: components["responses"]["Error"];
2589
+ 402: components["responses"]["Error"];
2590
+ 403: components["responses"]["Error"];
2591
+ 429: components["responses"]["Error"];
2592
+ 503: components["responses"]["Unavailable"];
2593
+ };
2594
+ };
1409
2595
  reviews: {
1410
2596
  parameters: {
1411
2597
  query?: never;
@@ -1417,109 +2603,444 @@ interface operations {
1417
2603
  content: {
1418
2604
  "application/json": components["schemas"]["ReviewsRequest"];
1419
2605
  };
1420
- };
1421
- responses: {
1422
- 200: components["responses"]["ReviewsOK"];
2606
+ };
2607
+ responses: {
2608
+ 200: components["responses"]["ReviewsOK"];
2609
+ 400: components["responses"]["Error"];
2610
+ 401: components["responses"]["Error"];
2611
+ 402: components["responses"]["Error"];
2612
+ 403: components["responses"]["Error"];
2613
+ 429: components["responses"]["Error"];
2614
+ 503: components["responses"]["Unavailable"];
2615
+ };
2616
+ };
2617
+ shopping: {
2618
+ parameters: {
2619
+ query?: never;
2620
+ header?: never;
2621
+ path?: never;
2622
+ cookie?: never;
2623
+ };
2624
+ requestBody: components["requestBodies"]["Search"];
2625
+ responses: {
2626
+ 200: components["responses"]["ShoppingOK"];
2627
+ 400: components["responses"]["Error"];
2628
+ 401: components["responses"]["Error"];
2629
+ 402: components["responses"]["Error"];
2630
+ 403: components["responses"]["Error"];
2631
+ 429: components["responses"]["Error"];
2632
+ 503: components["responses"]["Unavailable"];
2633
+ };
2634
+ };
2635
+ scholar: {
2636
+ parameters: {
2637
+ query?: never;
2638
+ header?: never;
2639
+ path?: never;
2640
+ cookie?: never;
2641
+ };
2642
+ requestBody: components["requestBodies"]["Search"];
2643
+ responses: {
2644
+ 200: components["responses"]["ScholarOK"];
2645
+ 400: components["responses"]["Error"];
2646
+ 401: components["responses"]["Error"];
2647
+ 402: components["responses"]["Error"];
2648
+ 403: components["responses"]["Error"];
2649
+ 429: components["responses"]["Error"];
2650
+ 503: components["responses"]["Unavailable"];
2651
+ };
2652
+ };
2653
+ patents: {
2654
+ parameters: {
2655
+ query?: never;
2656
+ header?: never;
2657
+ path?: never;
2658
+ cookie?: never;
2659
+ };
2660
+ requestBody: components["requestBodies"]["Search"];
2661
+ responses: {
2662
+ 200: components["responses"]["PatentsOK"];
2663
+ 400: components["responses"]["Error"];
2664
+ 401: components["responses"]["Error"];
2665
+ 402: components["responses"]["Error"];
2666
+ 403: components["responses"]["Error"];
2667
+ 429: components["responses"]["Error"];
2668
+ 503: components["responses"]["Unavailable"];
2669
+ };
2670
+ };
2671
+ autocomplete: {
2672
+ parameters: {
2673
+ query?: never;
2674
+ header?: never;
2675
+ path?: never;
2676
+ cookie?: never;
2677
+ };
2678
+ requestBody: components["requestBodies"]["Search"];
2679
+ responses: {
2680
+ 200: components["responses"]["AutocompleteOK"];
2681
+ 400: components["responses"]["Error"];
2682
+ 401: components["responses"]["Error"];
2683
+ 402: components["responses"]["Error"];
2684
+ 403: components["responses"]["Error"];
2685
+ 429: components["responses"]["Error"];
2686
+ 503: components["responses"]["Unavailable"];
2687
+ };
2688
+ };
2689
+ webpage: {
2690
+ parameters: {
2691
+ query?: never;
2692
+ header?: never;
2693
+ path?: never;
2694
+ cookie?: never;
2695
+ };
2696
+ requestBody: {
2697
+ content: {
2698
+ "application/json": components["schemas"]["WebpageRequest"];
2699
+ };
2700
+ };
2701
+ responses: {
2702
+ 200: components["responses"]["WebpageOK"];
2703
+ 400: components["responses"]["Error"];
2704
+ 401: components["responses"]["Error"];
2705
+ 402: components["responses"]["Error"];
2706
+ 403: components["responses"]["Error"];
2707
+ 429: components["responses"]["Error"];
2708
+ 503: components["responses"]["Unavailable"];
2709
+ };
2710
+ };
2711
+ extract: {
2712
+ parameters: {
2713
+ query?: never;
2714
+ header?: never;
2715
+ path?: never;
2716
+ cookie?: never;
2717
+ };
2718
+ requestBody: {
2719
+ content: {
2720
+ /**
2721
+ * @example {
2722
+ * "urls": [
2723
+ * "https://example.com/pricing",
2724
+ * "https://example.com/docs/limits.pdf"
2725
+ * ],
2726
+ * "query": "enterprise price",
2727
+ * "highlights": 2
2728
+ * }
2729
+ */
2730
+ "application/json": components["schemas"]["ExtractRequest"];
2731
+ };
2732
+ };
2733
+ responses: {
2734
+ 200: components["responses"]["ExtractOK"];
2735
+ 400: components["responses"]["Error"];
2736
+ 401: components["responses"]["Error"];
2737
+ 402: components["responses"]["Error"];
2738
+ 403: components["responses"]["Error"];
2739
+ 429: components["responses"]["Error"];
2740
+ 503: components["responses"]["Unavailable"];
2741
+ };
2742
+ };
2743
+ map: {
2744
+ parameters: {
2745
+ query?: never;
2746
+ header?: never;
2747
+ path?: never;
2748
+ cookie?: never;
2749
+ };
2750
+ requestBody: {
2751
+ content: {
2752
+ /**
2753
+ * @example {
2754
+ * "url": "https://docs.example.com/",
2755
+ * "search": "install guide",
2756
+ * "limit": 50
2757
+ * }
2758
+ */
2759
+ "application/json": components["schemas"]["MapRequest"];
2760
+ };
2761
+ };
2762
+ responses: {
2763
+ 200: components["responses"]["MapOK"];
2764
+ 400: components["responses"]["Error"];
2765
+ 401: components["responses"]["Error"];
2766
+ 402: components["responses"]["Error"];
2767
+ 403: components["responses"]["Error"];
2768
+ 429: components["responses"]["Error"];
2769
+ 503: components["responses"]["Unavailable"];
2770
+ };
2771
+ };
2772
+ createCrawl: {
2773
+ parameters: {
2774
+ query?: never;
2775
+ header?: never;
2776
+ path?: never;
2777
+ cookie?: never;
2778
+ };
2779
+ requestBody: {
2780
+ content: {
2781
+ /**
2782
+ * @example {
2783
+ * "url": "https://docs.example.com/",
2784
+ * "limit": 50,
2785
+ * "max_depth": 2,
2786
+ * "include_paths": [
2787
+ * "^/guides/"
2788
+ * ]
2789
+ * }
2790
+ */
2791
+ "application/json": components["schemas"]["CrawlRequest"];
2792
+ };
2793
+ };
2794
+ responses: {
2795
+ 202: components["responses"]["TaskAccepted"];
2796
+ 400: components["responses"]["Error"];
2797
+ 401: components["responses"]["Error"];
2798
+ 402: components["responses"]["Error"];
2799
+ 403: components["responses"]["Error"];
2800
+ 429: components["responses"]["Error"];
2801
+ 503: components["responses"]["Unavailable"];
2802
+ };
2803
+ };
2804
+ getCrawl: {
2805
+ parameters: {
2806
+ query?: never;
2807
+ header?: never;
2808
+ path: {
2809
+ id: string;
2810
+ };
2811
+ cookie?: never;
2812
+ };
2813
+ requestBody?: never;
2814
+ responses: {
2815
+ /** @description OK */
2816
+ 200: {
2817
+ headers: {
2818
+ [name: string]: unknown;
2819
+ };
2820
+ content: {
2821
+ "application/json": components["schemas"]["CrawlTask"];
2822
+ };
2823
+ };
2824
+ 401: components["responses"]["Error"];
2825
+ 404: components["responses"]["Error"];
2826
+ 429: components["responses"]["Error"];
2827
+ };
2828
+ };
2829
+ cancelCrawl: {
2830
+ parameters: {
2831
+ query?: never;
2832
+ header?: never;
2833
+ path: {
2834
+ id: string;
2835
+ };
2836
+ cookie?: never;
2837
+ };
2838
+ requestBody?: never;
2839
+ responses: {
2840
+ 200: components["responses"]["TaskCanceled"];
2841
+ 401: components["responses"]["Error"];
2842
+ 404: components["responses"]["Error"];
2843
+ 409: components["responses"]["Error"];
2844
+ 429: components["responses"]["Error"];
2845
+ };
2846
+ };
2847
+ listMonitors: {
2848
+ parameters: {
2849
+ query?: never;
2850
+ header?: never;
2851
+ path?: never;
2852
+ cookie?: never;
2853
+ };
2854
+ requestBody?: never;
2855
+ responses: {
2856
+ /** @description OK */
2857
+ 200: {
2858
+ headers: {
2859
+ [name: string]: unknown;
2860
+ };
2861
+ content: {
2862
+ "application/json": components["schemas"]["MonitorList"];
2863
+ };
2864
+ };
2865
+ 401: components["responses"]["Error"];
2866
+ 429: components["responses"]["Error"];
2867
+ };
2868
+ };
2869
+ createMonitor: {
2870
+ parameters: {
2871
+ query?: never;
2872
+ header?: never;
2873
+ path?: never;
2874
+ cookie?: never;
2875
+ };
2876
+ requestBody: {
2877
+ content: {
2878
+ /**
2879
+ * @example {
2880
+ * "q": "ai agents",
2881
+ * "endpoint": "news",
2882
+ * "interval": "hourly",
2883
+ * "name": "agents news",
2884
+ * "webhook_url": "https://example.com/hooks/serpkite"
2885
+ * }
2886
+ */
2887
+ "application/json": components["schemas"]["MonitorCreateRequest"];
2888
+ };
2889
+ };
2890
+ responses: {
2891
+ /** @description Created */
2892
+ 201: {
2893
+ headers: {
2894
+ [name: string]: unknown;
2895
+ };
2896
+ content: {
2897
+ "application/json": components["schemas"]["Monitor"];
2898
+ };
2899
+ };
1423
2900
  400: components["responses"]["Error"];
1424
2901
  401: components["responses"]["Error"];
1425
- 402: components["responses"]["Error"];
1426
2902
  403: components["responses"]["Error"];
1427
2903
  429: components["responses"]["Error"];
1428
- 503: components["responses"]["Unavailable"];
1429
2904
  };
1430
2905
  };
1431
- shopping: {
2906
+ getMonitor: {
1432
2907
  parameters: {
1433
2908
  query?: never;
1434
2909
  header?: never;
1435
- path?: never;
2910
+ path: {
2911
+ id: string;
2912
+ };
1436
2913
  cookie?: never;
1437
2914
  };
1438
- requestBody: components["requestBodies"]["Search"];
2915
+ requestBody?: never;
1439
2916
  responses: {
1440
- 200: components["responses"]["ShoppingOK"];
1441
- 400: components["responses"]["Error"];
2917
+ /** @description OK */
2918
+ 200: {
2919
+ headers: {
2920
+ [name: string]: unknown;
2921
+ };
2922
+ content: {
2923
+ "application/json": components["schemas"]["Monitor"];
2924
+ };
2925
+ };
1442
2926
  401: components["responses"]["Error"];
1443
- 402: components["responses"]["Error"];
1444
- 403: components["responses"]["Error"];
2927
+ 404: components["responses"]["Error"];
1445
2928
  429: components["responses"]["Error"];
1446
- 503: components["responses"]["Unavailable"];
1447
2929
  };
1448
2930
  };
1449
- scholar: {
2931
+ deleteMonitor: {
1450
2932
  parameters: {
1451
2933
  query?: never;
1452
2934
  header?: never;
1453
- path?: never;
2935
+ path: {
2936
+ id: string;
2937
+ };
1454
2938
  cookie?: never;
1455
2939
  };
1456
- requestBody: components["requestBodies"]["Search"];
2940
+ requestBody?: never;
1457
2941
  responses: {
1458
- 200: components["responses"]["ScholarOK"];
1459
- 400: components["responses"]["Error"];
2942
+ /** @description Deleted */
2943
+ 204: {
2944
+ headers: {
2945
+ [name: string]: unknown;
2946
+ };
2947
+ content?: never;
2948
+ };
1460
2949
  401: components["responses"]["Error"];
1461
- 402: components["responses"]["Error"];
1462
- 403: components["responses"]["Error"];
2950
+ 404: components["responses"]["Error"];
1463
2951
  429: components["responses"]["Error"];
1464
- 503: components["responses"]["Unavailable"];
1465
2952
  };
1466
2953
  };
1467
- patents: {
2954
+ updateMonitor: {
1468
2955
  parameters: {
1469
2956
  query?: never;
1470
2957
  header?: never;
1471
- path?: never;
2958
+ path: {
2959
+ id: string;
2960
+ };
1472
2961
  cookie?: never;
1473
2962
  };
1474
- requestBody: components["requestBodies"]["Search"];
2963
+ requestBody: {
2964
+ content: {
2965
+ /**
2966
+ * @example {
2967
+ * "active": false,
2968
+ * "interval": "daily"
2969
+ * }
2970
+ */
2971
+ "application/json": components["schemas"]["MonitorUpdateRequest"];
2972
+ };
2973
+ };
1475
2974
  responses: {
1476
- 200: components["responses"]["PatentsOK"];
2975
+ /** @description OK */
2976
+ 200: {
2977
+ headers: {
2978
+ [name: string]: unknown;
2979
+ };
2980
+ content: {
2981
+ "application/json": components["schemas"]["Monitor"];
2982
+ };
2983
+ };
1477
2984
  400: components["responses"]["Error"];
1478
2985
  401: components["responses"]["Error"];
1479
- 402: components["responses"]["Error"];
1480
- 403: components["responses"]["Error"];
2986
+ 404: components["responses"]["Error"];
1481
2987
  429: components["responses"]["Error"];
1482
- 503: components["responses"]["Unavailable"];
1483
2988
  };
1484
2989
  };
1485
- autocomplete: {
2990
+ listMonitorRuns: {
1486
2991
  parameters: {
1487
- query?: never;
2992
+ query?: {
2993
+ limit?: number;
2994
+ /** @description `next_before` of the previous page */
2995
+ before?: string;
2996
+ };
1488
2997
  header?: never;
1489
- path?: never;
2998
+ path: {
2999
+ id: string;
3000
+ };
1490
3001
  cookie?: never;
1491
3002
  };
1492
- requestBody: components["requestBodies"]["Search"];
3003
+ requestBody?: never;
1493
3004
  responses: {
1494
- 200: components["responses"]["AutocompleteOK"];
3005
+ /** @description OK */
3006
+ 200: {
3007
+ headers: {
3008
+ [name: string]: unknown;
3009
+ };
3010
+ content: {
3011
+ "application/json": components["schemas"]["MonitorRunList"];
3012
+ };
3013
+ };
1495
3014
  400: components["responses"]["Error"];
1496
3015
  401: components["responses"]["Error"];
1497
- 402: components["responses"]["Error"];
1498
- 403: components["responses"]["Error"];
3016
+ 404: components["responses"]["Error"];
1499
3017
  429: components["responses"]["Error"];
1500
- 503: components["responses"]["Unavailable"];
1501
3018
  };
1502
3019
  };
1503
- webpage: {
3020
+ runMonitor: {
1504
3021
  parameters: {
1505
3022
  query?: never;
1506
3023
  header?: never;
1507
- path?: never;
1508
- cookie?: never;
1509
- };
1510
- requestBody: {
1511
- content: {
1512
- "application/json": components["schemas"]["WebpageRequest"];
3024
+ path: {
3025
+ id: string;
1513
3026
  };
3027
+ cookie?: never;
1514
3028
  };
3029
+ requestBody?: never;
1515
3030
  responses: {
1516
- 200: components["responses"]["WebpageOK"];
1517
- 400: components["responses"]["Error"];
3031
+ /** @description Scheduled */
3032
+ 202: {
3033
+ headers: {
3034
+ [name: string]: unknown;
3035
+ };
3036
+ content: {
3037
+ "application/json": components["schemas"]["Monitor"];
3038
+ };
3039
+ };
1518
3040
  401: components["responses"]["Error"];
1519
- 402: components["responses"]["Error"];
1520
- 403: components["responses"]["Error"];
3041
+ 404: components["responses"]["Error"];
3042
+ 409: components["responses"]["Error"];
1521
3043
  429: components["responses"]["Error"];
1522
- 503: components["responses"]["Unavailable"];
1523
3044
  };
1524
3045
  };
1525
3046
  customSearch: {
@@ -1774,7 +3295,101 @@ interface operations {
1774
3295
  };
1775
3296
  content?: never;
1776
3297
  };
1777
- 401: components["responses"]["Error"];
3298
+ /** @description Missing, invalid, expired or revoked credential */
3299
+ 401: {
3300
+ headers: {
3301
+ /** @description RFC 9728 challenge pointing at the protected resource metadata */
3302
+ "WWW-Authenticate"?: string;
3303
+ [name: string]: unknown;
3304
+ };
3305
+ content: {
3306
+ "application/json": components["schemas"]["Error"];
3307
+ };
3308
+ };
3309
+ };
3310
+ };
3311
+ mcpProtectedResourceMetadata: {
3312
+ parameters: {
3313
+ query?: never;
3314
+ header?: never;
3315
+ path?: never;
3316
+ cookie?: never;
3317
+ };
3318
+ requestBody?: never;
3319
+ responses: {
3320
+ /** @description Metadata */
3321
+ 200: {
3322
+ headers: {
3323
+ [name: string]: unknown;
3324
+ };
3325
+ content: {
3326
+ "application/json": components["schemas"]["ProtectedResourceMetadata"];
3327
+ };
3328
+ };
3329
+ };
3330
+ };
3331
+ protectedResourceMetadata: {
3332
+ parameters: {
3333
+ query?: never;
3334
+ header?: never;
3335
+ path?: never;
3336
+ cookie?: never;
3337
+ };
3338
+ requestBody?: never;
3339
+ responses: {
3340
+ /** @description Metadata */
3341
+ 200: {
3342
+ headers: {
3343
+ [name: string]: unknown;
3344
+ };
3345
+ content: {
3346
+ "application/json": components["schemas"]["ProtectedResourceMetadata"];
3347
+ };
3348
+ };
3349
+ };
3350
+ };
3351
+ crawlCompletedWebhook: {
3352
+ parameters: {
3353
+ query?: never;
3354
+ header?: never;
3355
+ path?: never;
3356
+ cookie?: never;
3357
+ };
3358
+ requestBody: {
3359
+ content: {
3360
+ "application/json": components["schemas"]["TaskCompletedEvent"];
3361
+ };
3362
+ };
3363
+ responses: {
3364
+ /** @description Any 2xx acknowledges the delivery */
3365
+ 200: {
3366
+ headers: {
3367
+ [name: string]: unknown;
3368
+ };
3369
+ content?: never;
3370
+ };
3371
+ };
3372
+ };
3373
+ monitorResultsWebhook: {
3374
+ parameters: {
3375
+ query?: never;
3376
+ header?: never;
3377
+ path?: never;
3378
+ cookie?: never;
3379
+ };
3380
+ requestBody: {
3381
+ content: {
3382
+ "application/json": components["schemas"]["MonitorResultsEvent"];
3383
+ };
3384
+ };
3385
+ responses: {
3386
+ /** @description Any 2xx acknowledges the delivery */
3387
+ 200: {
3388
+ headers: {
3389
+ [name: string]: unknown;
3390
+ };
3391
+ content?: never;
3392
+ };
1778
3393
  };
1779
3394
  };
1780
3395
  }
@@ -1805,8 +3420,15 @@ type SearchParams = Omit<Schemas["SearchRequest"], "engine"> & {
1805
3420
  engine?: Engine;
1806
3421
  };
1807
3422
  type ReviewsParams = Schemas["ReviewsRequest"];
3423
+ /** Parameters of `place`: one of `place_id`, `cid` or `fid` (place_id wins, then fid, then cid). */
3424
+ type PlaceParams = Omit<Schemas["PlaceRequest"], "engine"> & {
3425
+ /** Search providers allowed to answer. Default `"google"`. See {@link Engine}. */
3426
+ engine?: Engine;
3427
+ };
1808
3428
  type WebpageParams = Schemas["WebpageRequest"];
1809
3429
  type RankParams = Schemas["RankRequest"];
3430
+ type MapParams = Schemas["MapRequest"];
3431
+ type ExtractParams = Schemas["ExtractRequest"];
1810
3432
  /** `format` values accepted by the verticals. */
1811
3433
  type Format = NonNullable<SearchParams["format"]>;
1812
3434
  type Meta = Schemas["Meta"];
@@ -1822,18 +3444,37 @@ type ImageResult = Schemas["ImageResult"];
1822
3444
  type VideoResult = Schemas["VideoResult"];
1823
3445
  type NewsResult = Schemas["NewsResult"];
1824
3446
  type PlaceResult = Schemas["PlaceResult"];
3447
+ /**
3448
+ * Opening hours per weekday (`monday` … `sunday`) as local 24-hour `HH:MM` intervals: a closed
3449
+ * day is `[]`, a day open 24 hours `[{ open: "00:00", close: "24:00" }]`. Days Google doesn't
3450
+ * list are absent.
3451
+ */
3452
+ type WeeklyHours = Schemas["WeeklyHours"];
3453
+ /** One opening interval; `next_day` when it closes after midnight. */
3454
+ type HoursInterval = Schemas["HoursInterval"];
3455
+ /** A photo of a place (`place`; up to 10). */
3456
+ type PlacePhoto = Schemas["PlacePhoto"];
1825
3457
  type ReviewResult = Schemas["ReviewResult"];
1826
3458
  type ShoppingResult = Schemas["ShoppingResult"];
1827
3459
  type ScholarResult = Schemas["ScholarResult"];
1828
3460
  type PatentResult = Schemas["PatentResult"];
1829
3461
  type Suggestion = Schemas["Suggestion"];
1830
3462
  type PageMetadata = Schemas["PageMetadata"];
3463
+ /** An outbound link of a page (`webpage` with `include_links`). */
3464
+ type PageLink = Schemas["PageLink"];
3465
+ /** A query-ranked passage of a page (`search` with `highlights`). */
3466
+ type Highlight = Schemas["Highlight"];
3467
+ /** A domain filter: a list or a comma-separated string (`include_domains`…). */
3468
+ type DomainList = Schemas["DomainList"];
3469
+ type MapURL = Schemas["MapURL"];
3470
+ type ExtractResult = Schemas["ExtractResult"];
3471
+ type ExtractFailure = Schemas["ExtractFailure"];
1831
3472
  type RankMatch = Schemas["RankResponse"]["matches"][number];
1832
3473
  type SearchResponse = Schemas["SearchResponse"];
1833
3474
  type ImagesResponse = Schemas["ImagesResponse"];
1834
3475
  type VideosResponse = Schemas["VideosResponse"];
1835
3476
  type NewsResponse = Schemas["NewsResponse"];
1836
- /** Returned by both `maps` and `places`. */
3477
+ /** Returned by `maps`, `places` and `place`. */
1837
3478
  type PlacesResponse = Schemas["PlacesResponse"];
1838
3479
  type MapsResponse = PlacesResponse;
1839
3480
  type ReviewsResponse = Schemas["ReviewsResponse"];
@@ -1843,6 +3484,8 @@ type PatentsResponse = Schemas["PatentsResponse"];
1843
3484
  type AutocompleteResponse = Schemas["AutocompleteResponse"];
1844
3485
  type WebpageResponse = Schemas["WebpageResponse"];
1845
3486
  type RankResponse = Schemas["RankResponse"];
3487
+ type MapResponse = Schemas["MapResponse"];
3488
+ type ExtractResponse = Schemas["ExtractResponse"];
1846
3489
  type Account = Schemas["Account"];
1847
3490
  type Status = Schemas["Status"];
1848
3491
  /**
@@ -1874,6 +3517,7 @@ type BatchRequestMap = {
1874
3517
  news: SearchParams;
1875
3518
  maps: SearchParams;
1876
3519
  places: SearchParams;
3520
+ place: PlaceParams;
1877
3521
  reviews: ReviewsParams;
1878
3522
  shopping: SearchParams;
1879
3523
  scholar: SearchParams;
@@ -1891,8 +3535,102 @@ type BatchCreateParams = {
1891
3535
  webhook_url?: string;
1892
3536
  };
1893
3537
  }[BatchEndpoint];
3538
+ type TaskStatus = Schemas["TaskStatus"];
3539
+ /** The `202` body of `crawl`. */
3540
+ type TaskCreated = Schemas["TaskCreated"];
3541
+ type TaskCancelResponse = Schemas["TaskCancelResponse"];
3542
+ type TaskError = Schemas["TaskError"];
3543
+ /**
3544
+ * Body of `POST /v1/crawl`: `limit` up to 1000 pages, `max_depth` up to 10, `sitemap`
3545
+ * (`include` | `only` | `skip`), `query` for a best-first crawl, path filters and
3546
+ * `ignore_query_parameters`.
3547
+ */
3548
+ type CrawlParams = Schemas["CrawlRequest"];
3549
+ /** `sitemap` values of `crawl`. */
3550
+ type CrawlSitemapMode = NonNullable<CrawlParams["sitemap"]>;
3551
+ type CrawlTask = Schemas["CrawlTask"];
3552
+ type CrawlResult = Schemas["CrawlResult"];
3553
+ /** `result.stats` of a crawl: counts, robots.txt outcome and why it `stopped`. */
3554
+ type CrawlStats = CrawlResult["stats"];
3555
+ /** Why a crawl ended (`result.stats.stopped`). */
3556
+ type CrawlStopReason = NonNullable<CrawlStats["stopped"]>;
3557
+ type CrawlPage = Schemas["CrawlPage"];
3558
+ /**
3559
+ * Body of `POST /v1/monitors`. `search` and `news` monitors need `q`; `webpage` monitors need
3560
+ * `url` (and take only `country` besides) and report the page when its content changes.
3561
+ * `metadata` is your own JSON object (at most 2 KB), echoed on the monitor and its webhooks.
3562
+ * `webhook_url` is optional: without one, new results are read from the run history
3563
+ * (`monitors.runs`). `active: false` creates the monitor paused.
3564
+ */
3565
+ type MonitorCreateParams = Omit<Schemas["MonitorCreateRequest"], "engine"> & {
3566
+ engine?: Engine;
3567
+ };
3568
+ /**
3569
+ * Body of `PATCH /v1/monitors/{id}`: only the fields sent change. Search fields (or `url`) are
3570
+ * merged into the saved request (a changed one reports every result as new on the next run);
3571
+ * switching `endpoint` between a search and `webpage` drops the other kind's fields.
3572
+ * `metadata` replaces the stored object (`null` clears it); `webhook_url: ""` removes the
3573
+ * webhook; `active: true` resumes a paused monitor.
3574
+ */
3575
+ type MonitorUpdateParams = Omit<Schemas["MonitorUpdateRequest"], "engine"> & {
3576
+ engine?: Engine;
3577
+ };
3578
+ type Monitor = Schemas["Monitor"];
3579
+ /** What a monitor watches: a `search`, `news` search, or a `webpage` for content changes. */
3580
+ type MonitorEndpoint = Monitor["endpoint"];
3581
+ /** Your own JSON object on a monitor (at most 2 KB), echoed in `monitor.results`. */
3582
+ type MonitorMetadata = NonNullable<Monitor["metadata"]>;
3583
+ /**
3584
+ * A result item of a `webpage` monitor (in run `results` and `monitor.results` `new_results`):
3585
+ * the page when first seen (`change: "new"`) or when its content changed (`"changed"`).
3586
+ */
3587
+ type MonitorPageChange = Schemas["MonitorPageChange"];
3588
+ /** `last_status` of a monitor; `"paused"` after 10 failed runs in a row. */
3589
+ type MonitorStatus = NonNullable<Monitor["last_status"]>;
3590
+ type MonitorList = Schemas["MonitorList"];
3591
+ type MonitorSearch = Schemas["MonitorSearch"];
3592
+ /**
3593
+ * One run of a monitor. `results` holds the new results (null when none, or after 24 hours):
3594
+ * `OrganicResult`-shaped for search, `NewsResult` for news, {@link MonitorPageChange} for webpage.
3595
+ */
3596
+ type MonitorRun = Schemas["MonitorRun"];
3597
+ /** A page of runs, newest first. Pass `next_before` as `before` for the next page. */
3598
+ type MonitorRunList = Schemas["MonitorRunList"];
3599
+ /** Query of `GET /v1/monitors/{id}/runs`. */
3600
+ type MonitorRunsParams = NonNullable<operations["listMonitorRuns"]["parameters"]["query"]>;
3601
+ /** Body of `batch.completed`: the finished job, without `poll_url`, `webhook_url` and `webhook_status`. */
3602
+ type BatchCompletedEvent = Omit<Batch, "poll_url" | "webhook_url" | "webhook_status"> & {
3603
+ event: "batch.completed";
3604
+ };
3605
+ /**
3606
+ * Body of `crawl.completed`. When the result is over 4 MB, `result` is null and
3607
+ * `result_omitted` is true: fetch the task from `poll_url`.
3608
+ */
3609
+ type TaskCompletedEvent = Schemas["TaskCompletedEvent"];
3610
+ /**
3611
+ * Body of `monitor.results`. `run_id` is also the `X-SerpKite-Delivery` header (dedupe retries
3612
+ * on it). Carries the monitor's `metadata`, and `url` for webpage monitors (whose `new_results`
3613
+ * are {@link MonitorPageChange} items and `q` is empty).
3614
+ */
3615
+ type MonitorResultsEvent = Schemas["MonitorResultsEvent"];
3616
+ /** `X-SerpKite-Event` values. Plain strings stay accepted for events added later. */
3617
+ type WebhookEventType = "batch.completed" | "crawl.completed" | "monitor.results" | (string & {});
3618
+ /** A verified webhook delivery, from `parseWebhook`. */
3619
+ type WebhookEvent = {
3620
+ type: "batch.completed";
3621
+ deliveryId: string | undefined;
3622
+ data: BatchCompletedEvent;
3623
+ } | {
3624
+ type: "crawl.completed";
3625
+ deliveryId: string | undefined;
3626
+ data: TaskCompletedEvent;
3627
+ } | {
3628
+ type: "monitor.results";
3629
+ deliveryId: string | undefined;
3630
+ data: MonitorResultsEvent;
3631
+ };
1894
3632
 
1895
- declare const VERSION = "0.3.0";
3633
+ declare const VERSION = "0.5.0";
1896
3634
  declare const DEFAULT_BASE_URL = "https://api.serpkite.com";
1897
3635
  interface SerpKiteOptions {
1898
3636
  /** API key (`skt_live_…`). Defaults to the `SERPKITE_API_KEY` environment variable. */
@@ -1942,7 +3680,10 @@ interface BatchCreateOptions extends RequestOptions {
1942
3680
  idempotencyKey?: string;
1943
3681
  }
1944
3682
  interface WaitOptions {
1945
- /** Give up after this many milliseconds. Default 600000 (10 minutes). */
3683
+ /**
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.
3686
+ */
1946
3687
  timeoutMs?: number;
1947
3688
  /** First delay between polls. Default 1000. Grows 1.5× per poll. */
1948
3689
  pollIntervalMs?: number;
@@ -1963,7 +3704,7 @@ interface VerticalMethod<P, R> {
1963
3704
  }, options?: RequestOptions): Promise<R>;
1964
3705
  (params: P, options?: RequestOptions): Promise<R | CompactResponse | string>;
1965
3706
  }
1966
- type Method = "GET" | "POST";
3707
+ type Method = "GET" | "POST" | "PATCH" | "DELETE";
1967
3708
  interface Call {
1968
3709
  method: Method;
1969
3710
  path: string;
@@ -2022,6 +3763,16 @@ declare class SerpKite {
2022
3763
  results: components["schemas"]["PlaceResult"][];
2023
3764
  meta: components["schemas"]["Meta"];
2024
3765
  }>;
3766
+ /**
3767
+ * Details of one place by `place_id`, `cid` or `fid`: address, country, time zone, hours
3768
+ * (`opening_hours` text and structured `weekly_hours`), phones, description and photos.
3769
+ * `results` holds the place, or is empty (not charged) when no place has that id. 1 credit.
3770
+ */
3771
+ readonly place: VerticalMethod<PlaceParams, {
3772
+ request: components["schemas"]["RequestEcho"];
3773
+ results: components["schemas"]["PlaceResult"][];
3774
+ meta: components["schemas"]["Meta"];
3775
+ }>;
2025
3776
  /** Reviews of a place by `place_id`, `cid` or `fid`. Page with `page_token` = `next_page_token`. */
2026
3777
  readonly reviews: VerticalMethod<{
2027
3778
  place_id?: string;
@@ -2070,6 +3821,9 @@ declare class SerpKite {
2070
3821
  url: string;
2071
3822
  format?: "json" | "markdown" | "compact";
2072
3823
  include_html?: boolean;
3824
+ include_links?: boolean;
3825
+ include_images?: boolean;
3826
+ country?: string;
2073
3827
  max_age?: number;
2074
3828
  }, {
2075
3829
  request: components["schemas"]["RequestEcho"];
@@ -2079,12 +3833,93 @@ declare class SerpKite {
2079
3833
  text?: string;
2080
3834
  html?: string;
2081
3835
  metadata: components["schemas"]["PageMetadata"];
3836
+ links?: components["schemas"]["PageLink"][];
3837
+ image_links?: string[];
2082
3838
  meta: components["schemas"]["Meta"];
2083
3839
  }>;
2084
3840
  /** Position of `domain` for keyword `q` in the top `num` results (default 100). */
2085
3841
  rank(params: RankParams, options?: RequestOptions): Promise<RankResponse>;
3842
+ /**
3843
+ * Read up to 20 URLs (HTML or PDF) as Markdown, text or HTML in one call, with optional
3844
+ * query-ranked `highlights` (BM25), `include_links` and `include_images`. 1 credit per URL
3845
+ * that comes back (0.5 from cache); URLs that fail are listed in `failed` and cost nothing.
3846
+ */
3847
+ extract(params: ExtractParams, options?: RequestOptions): Promise<ExtractResponse>;
3848
+ /**
3849
+ * The URLs of a site from its sitemaps (XML, RSS/Atom, gzip, plain text) and start page,
3850
+ * canonicalised and deduplicated, optionally ranked by `search`. `include_paths` /
3851
+ * `exclude_paths` (regular expressions on the URL path) and `ignore_query_parameters`
3852
+ * narrow the list. 1 credit; free when nothing is found.
3853
+ */
3854
+ map(params: MapParams, options?: RequestOptions): Promise<MapResponse>;
2086
3855
  /** Balance, limits and this month's usage for the key's account. */
2087
3856
  account(options?: RequestOptions): Promise<Account>;
3857
+ /**
3858
+ * Starts an async crawl of one site and returns the queued task (`202`). 1 credit per page
3859
+ * read (0.5 from cache); `limit` credits (up to 1000 pages, `max_depth` up to 10) are
3860
+ * reserved up front and the rest refunded. `sitemap` (`include` default, `only`, `skip`)
3861
+ * seeds the crawl with sitemap URLs; `query` reads the most relevant pages first. robots.txt
3862
+ * and Crawl-delay are honoured; `result.stats.stopped` says why the crawl ended (`done`,
3863
+ * `limit`, `time_limit`, `size_limit`, `too_many_failures`, `canceled`).
3864
+ * Only retried on 429, so a lost response never starts (and reserves) a second crawl.
3865
+ */
3866
+ crawl(params: CrawlParams, options?: RequestOptions): Promise<TaskCreated>;
3867
+ /** Polls a crawl (results are kept for 24 hours). */
3868
+ getCrawl(id: string, options?: RequestOptions): Promise<CrawlTask>;
3869
+ /** Cancels a crawl: refunded if still queued, else stops at the next checkpoint. */
3870
+ cancelCrawl(id: string, options?: RequestOptions): Promise<TaskCancelResponse>;
3871
+ /**
3872
+ * Polls until the crawl is `completed`, `failed` or `canceled` and returns it (a failed
3873
+ * task is returned, not thrown; check `status` and `error`). Accepts an id or the task
3874
+ * returned by `crawl`.
3875
+ */
3876
+ waitForCrawl(idOrTask: string | {
3877
+ id: string;
3878
+ }, options?: WaitOptions): Promise<CrawlTask>;
3879
+ readonly monitors: {
3880
+ /**
3881
+ * Saves a `search` or `news` request (`q`) that runs on a schedule (hourly to monthly) and
3882
+ * POSTs results it hasn't seen before to `webhook_url` (`monitor.results`). With
3883
+ * `endpoint: "webpage"` and a `url` it checks that page each interval (1 credit per check)
3884
+ * and reports it (`MonitorPageChange`) when its content changes. `metadata` (your JSON
3885
+ * object, at most 2 KB) is echoed on the monitor and in its webhooks. Without a
3886
+ * `webhook_url`, read new results from `monitors.runs`. `active: false`
3887
+ * creates it paused. A monitor pauses itself after 10 failed runs in a row
3888
+ * (`last_status: "paused"`); `update(id, { active: true })` resumes it. Each run costs
3889
+ * what its search costs. Only retried on 429.
3890
+ */
3891
+ create: (params: MonitorCreateParams, options?: RequestOptions) => Promise<Monitor>;
3892
+ /** The account's monitors. */
3893
+ list: (options?: RequestOptions) => Promise<MonitorList>;
3894
+ get: (id: string, options?: RequestOptions) => Promise<Monitor>;
3895
+ /**
3896
+ * Changes `name`, `interval` / `interval_seconds`, `webhook_url` (`""` removes it),
3897
+ * `active` (`true` resumes a paused monitor), `metadata` (an object replaces it, `null`
3898
+ * clears it) or the saved request (`endpoint`, `q`, `url`, `country`, `num`, domains,
3899
+ * `engine`…). Switching `endpoint` between a search and `webpage` drops the other kind's
3900
+ * fields. A changed search reports every result as new on the next run.
3901
+ */
3902
+ update: (id: string, params: MonitorUpdateParams, options?: RequestOptions) => Promise<Monitor>;
3903
+ delete: (id: string, options?: RequestOptions) => Promise<void>;
3904
+ /** Runs an active monitor at the next scheduler poll (within about 30 seconds).
3905
+ * Paused monitors return 409; update(id, { active: true }) resumes and schedules them. */
3906
+ run: (id: string, options?: RequestOptions) => Promise<Monitor>;
3907
+ /**
3908
+ * One page of the monitor's run history, newest first (`limit` 1-100, default 20). Each
3909
+ * run carries its new results for 24 hours. Pass `next_before` as `before` for the next
3910
+ * page; it is null on the last one.
3911
+ */
3912
+ runs: (id: string, params?: MonitorRunsParams, options?: RequestOptions) => Promise<MonitorRunList>;
3913
+ /**
3914
+ * Iterates over every run of the monitor, newest first, fetching pages of `limit` as
3915
+ * needed (starting at `before` when given).
3916
+ *
3917
+ * ```ts
3918
+ * for await (const run of sk.monitors.iterRuns("m1")) console.log(run.new_results);
3919
+ * ```
3920
+ */
3921
+ iterRuns: (id: string, params?: MonitorRunsParams, options?: RequestOptions) => AsyncIterable<MonitorRun>;
3922
+ };
2088
3923
  readonly batches: {
2089
3924
  /**
2090
3925
  * Queue 1-100 requests for one endpoint at half price. Returns one entry per
@@ -2157,7 +3992,8 @@ interface VerifyWebhookOptions {
2157
3992
  }
2158
3993
  type HeaderSource = Headers | Record<string, string | string[] | undefined>;
2159
3994
  /**
2160
- * Checks a batch webhook delivery: `X-SerpKite-Signature` must be
3995
+ * Checks a webhook delivery (any event: `batch.completed`, `crawl.completed`,
3996
+ * `monitor.results`): `X-SerpKite-Signature` must be
2161
3997
  * `v1=<hex HMAC-SHA256(secret, "<X-SerpKite-Timestamp>.<raw body>")>` and the
2162
3998
  * timestamp recent. Pass the raw request body exactly as received (not
2163
3999
  * re-serialised JSON). Uses Web Crypto (Node 18+, Deno, Bun, browsers).
@@ -2167,5 +4003,20 @@ type HeaderSource = Headers | Record<string, string | string[] | undefined>;
2167
4003
  * ```
2168
4004
  */
2169
4005
  declare function verifyWebhook(secret: string, payload: string | Uint8Array, headers: HeaderSource, options?: VerifyWebhookOptions): Promise<boolean>;
4006
+ /**
4007
+ * Verifies a delivery (see {@link verifyWebhook}) and returns it typed by its
4008
+ * `X-SerpKite-Event` header. `deliveryId` is `X-SerpKite-Delivery` (for
4009
+ * `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
4011
+ * `result_omitted: true`; fetch it from `data.poll_url`. Throws a
4012
+ * `SerpKiteError` with code `invalid_signature` when the signature or timestamp
4013
+ * doesn't check out.
4014
+ *
4015
+ * ```ts
4016
+ * const ev = await parseWebhook(secret, rawBody, req.headers);
4017
+ * if (ev.type === "monitor.results") console.log(ev.data.new_results.length);
4018
+ * ```
4019
+ */
4020
+ declare function parseWebhook(secret: string, payload: string | Uint8Array, headers: HeaderSource, options?: VerifyWebhookOptions): Promise<WebhookEvent>;
2170
4021
 
2171
- export { type Account, type AnswerBox, type AutocompleteResponse, type Batch, type BatchCreateEntry, type BatchCreateError, type BatchCreateOptions, type BatchCreateParams, type BatchCreateResponse, type BatchEndpoint, type BatchStatus, type CompactResponse, DEFAULT_BASE_URL, type Engine, type ErrorBody, type Format, type ImageResult, type ImagesResponse, type KnowledgeGraph, type MapsResponse, type Meta, type NewsResponse, type NewsResult, type OrganicResult, type PageMetadata, type PatentResult, type PatentsResponse, type PeopleAlsoAsk, 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, VERSION, type VerifyWebhookOptions, type VerticalMethod, type VideoResult, type VideosResponse, type WaitOptions, type WebpageParams, type WebpageResponse, type components, isBatchError, type operations, parseRetryAfter, type paths, verifyWebhook };
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 };