serpkite 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -275,7 +275,7 @@ interface paths {
275
275
  };
276
276
  get?: never;
277
277
  put?: never;
278
- /** Fetch any public URL and return clean Markdown + metadata (1 credit) */
278
+ /** Fetch any public URL (HTML or PDF) and return clean Markdown + metadata (1 credit) */
279
279
  post: operations["webpage"];
280
280
  delete?: never;
281
281
  options?: never;
@@ -283,6 +283,214 @@ interface paths {
283
283
  patch?: never;
284
284
  trace?: never;
285
285
  };
286
+ "/v1/extract": {
287
+ parameters: {
288
+ query?: never;
289
+ header?: never;
290
+ path?: never;
291
+ cookie?: never;
292
+ };
293
+ get?: never;
294
+ put?: never;
295
+ /**
296
+ * Up to 20 URLs (HTML or PDF) as Markdown, text or HTML, with query-ranked highlights, links and images (1 credit per URL read)
297
+ * @description Every URL is billed only when it comes back: 1 credit, 0.5 from cache. URLs that
298
+ * fail are listed in `failed` and cost nothing. The response is `200` even when every
299
+ * URL failed. Highlights are ranked with BM25 (lexical, no model).
300
+ */
301
+ post: operations["extract"];
302
+ delete?: never;
303
+ options?: never;
304
+ head?: never;
305
+ patch?: never;
306
+ trace?: never;
307
+ };
308
+ "/v1/map": {
309
+ parameters: {
310
+ query?: never;
311
+ header?: never;
312
+ path?: never;
313
+ cookie?: never;
314
+ };
315
+ get?: never;
316
+ put?: never;
317
+ /**
318
+ * 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)
319
+ * @description Reads the sitemaps listed in robots.txt (or `/sitemap.xml`), following sitemap
320
+ * indexes; XML, gzip, RSS/Atom and plain-text sitemaps are understood. URLs are
321
+ * cleaned (fragment and tracking parameters such as `utm_*`, `gclid` and `fbclid`
322
+ * dropped), kept on the site, filtered by `include_paths` / `exclude_paths` and
323
+ * de-duplicated (`www.`, scheme and trailing slash folded). `search` ranks the URLs
324
+ * by their path words and titles (BM25) and drops the ones that don't match. Takes
325
+ * at most about 30 seconds.
326
+ */
327
+ post: operations["map"];
328
+ delete?: never;
329
+ options?: never;
330
+ head?: never;
331
+ patch?: never;
332
+ trace?: never;
333
+ };
334
+ "/v1/crawl": {
335
+ parameters: {
336
+ query?: never;
337
+ header?: never;
338
+ path?: never;
339
+ cookie?: never;
340
+ };
341
+ get?: never;
342
+ put?: never;
343
+ /**
344
+ * Start an async crawl of one site (1 credit per page read; `limit` credits reserved up front, the rest refunded)
345
+ * @description From `url` and (unless `sitemap: skip`) the site's sitemaps, same host (optionally
346
+ * subdomains), up to `limit` pages and `max_depth` link hops, filtered by
347
+ * `include_paths` / `exclude_paths` (regular expressions matched against the URL
348
+ * path). Breadth first, or best first with `query` (pages whose URL and link text
349
+ * match it are read first). Each host's robots.txt is honoured (RFC 9309: rules,
350
+ * `Crawl-delay`; a robots.txt that answers 5xx stops the crawl at the start page).
351
+ * URLs are canonicalised (fragments and tracking parameters dropped, `www.`,
352
+ * trailing slashes and redirects folded) so each page is read once. Each page comes
353
+ * back as Markdown (or text) with its metadata. A crawl runs for at most 30 minutes
354
+ * and returns up to 16 MB of pages; `result.stats.stopped` says why it ended.
355
+ *
356
+ * Returns `202` with a task; poll `GET /v1/crawl/{id}` or wait for the signed
357
+ * `crawl.completed` webhook. Pages read cost 1 credit each (0.5 from cache); a crawl
358
+ * that read nothing fails (`no_pages`) and is refunded. At most 20 crawls per account
359
+ * may be queued or running at once (`429`); a crawl interrupted by a deploy restarts
360
+ * from the beginning.
361
+ */
362
+ post: operations["createCrawl"];
363
+ delete?: never;
364
+ options?: never;
365
+ head?: never;
366
+ patch?: never;
367
+ trace?: never;
368
+ };
369
+ "/v1/crawl/{id}": {
370
+ parameters: {
371
+ query?: never;
372
+ header?: never;
373
+ path: {
374
+ id: string;
375
+ };
376
+ cookie?: never;
377
+ };
378
+ /** Poll a crawl (kept for 24 hours) */
379
+ get: operations["getCrawl"];
380
+ put?: never;
381
+ post?: never;
382
+ /**
383
+ * 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
384
+ * @description `404` when there is no such crawl, `409` when it already finished.
385
+ */
386
+ delete: operations["cancelCrawl"];
387
+ options?: never;
388
+ head?: never;
389
+ patch?: never;
390
+ trace?: never;
391
+ };
392
+ "/v1/monitors": {
393
+ parameters: {
394
+ query?: never;
395
+ header?: never;
396
+ path?: never;
397
+ cookie?: never;
398
+ };
399
+ /** List the account's monitors */
400
+ get: operations["listMonitors"];
401
+ put?: never;
402
+ /**
403
+ * 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)
404
+ * @description Runs hourly to monthly (`interval` or `interval_seconds`, default daily); the
405
+ * first run is due right away (unless `active: false`). With `endpoint: webpage`
406
+ * the monitor watches `url` and reports the page (Markdown, `change: new|changed`)
407
+ * whenever its content changes (1 credit per check). Each run is billed like the
408
+ * search it makes (1 credit per 10 results, `num: 100` is 7; empty and failed runs
409
+ * are free) on the monitor's key: the key that created it, or last changed or ran
410
+ * it, under that key's limits and the account's spend cap. Only the fields below
411
+ * are kept; any other search field is a `400`. Results among the
412
+ * top `num` not seen in earlier runs are POSTed as a `monitor.results` webhook when
413
+ * the monitor has a `webhook_url`, and are always listed in its run history
414
+ * (`GET /v1/monitors/{id}/runs`, results kept 24 hours). At most 100 monitors per
415
+ * account (403 `forbidden`). A monitor pauses itself after 10 failed runs in a row
416
+ * (search errors, insufficient credits or webhook failures) or when its key is
417
+ * revoked; set `active: true` to resume.
418
+ */
419
+ post: operations["createMonitor"];
420
+ delete?: never;
421
+ options?: never;
422
+ head?: never;
423
+ patch?: never;
424
+ trace?: never;
425
+ };
426
+ "/v1/monitors/{id}": {
427
+ parameters: {
428
+ query?: never;
429
+ header?: never;
430
+ path: {
431
+ id: string;
432
+ };
433
+ cookie?: never;
434
+ };
435
+ /** Get a monitor */
436
+ get: operations["getMonitor"];
437
+ put?: never;
438
+ post?: never;
439
+ /** Delete a monitor */
440
+ delete: operations["deleteMonitor"];
441
+ options?: never;
442
+ head?: never;
443
+ /** 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) */
444
+ patch: operations["updateMonitor"];
445
+ trace?: never;
446
+ };
447
+ "/v1/monitors/{id}/runs": {
448
+ parameters: {
449
+ query?: {
450
+ limit?: number;
451
+ /** @description `next_before` of the previous page */
452
+ before?: string;
453
+ };
454
+ header?: never;
455
+ path: {
456
+ id: string;
457
+ };
458
+ cookie?: never;
459
+ };
460
+ /** A monitor's run history, newest first (runs are kept 30 days, their results 24 hours) */
461
+ get: operations["listMonitorRuns"];
462
+ put?: never;
463
+ post?: never;
464
+ delete?: never;
465
+ options?: never;
466
+ head?: never;
467
+ patch?: never;
468
+ trace?: never;
469
+ };
470
+ "/v1/monitors/{id}/run": {
471
+ parameters: {
472
+ query?: never;
473
+ header?: never;
474
+ path: {
475
+ id: string;
476
+ };
477
+ cookie?: never;
478
+ };
479
+ get?: never;
480
+ put?: never;
481
+ /**
482
+ * Run a monitor now (it becomes due at the next scheduler poll, within about 30 seconds)
483
+ * @description The monitor must be active. A paused monitor returns 409; resume it with
484
+ * PATCH {"active": true} first (resuming also makes it due immediately).
485
+ * The monitor is bound to the calling key, which this and later runs are billed to.
486
+ */
487
+ post: operations["runMonitor"];
488
+ delete?: never;
489
+ options?: never;
490
+ head?: never;
491
+ patch?: never;
492
+ trace?: never;
493
+ };
286
494
  "/customsearch/v1": {
287
495
  parameters: {
288
496
  query?: never;
@@ -470,12 +678,12 @@ interface components {
470
678
  SearchRequest: {
471
679
  q: string;
472
680
  /**
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
681
+ * @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
682
  * @default us
475
683
  */
476
684
  country?: string;
477
685
  /**
478
- * @description Interface language: a language code with an optional region (e.g. en, de, pt-br, zh-tw, es-419)
686
+ * @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
687
  * @default en
480
688
  */
481
689
  language?: string;
@@ -531,6 +739,37 @@ interface components {
531
739
  /** @description Accept a cached result up to this many seconds old (50% of credits on a hit) */
532
740
  max_age?: number;
533
741
  engine?: components["schemas"]["EngineParam"];
742
+ /** @description Only results from these domains (search, news, images, videos). Compiled into site: operators and enforced on the results. Not with engine=consensus */
743
+ include_domains?: components["schemas"]["DomainList"];
744
+ /** @description Drop results from these domains (search, news, images, videos). Not with engine=consensus */
745
+ exclude_domains?: components["schemas"]["DomainList"];
746
+ /** @description Move results from these domains to the top, keeping the order within both groups (search, news) */
747
+ boost_domains?: components["schemas"]["DomainList"];
748
+ /**
749
+ * Format: date
750
+ * @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
751
+ */
752
+ start_date?: string;
753
+ /**
754
+ * Format: date
755
+ * @description Only results published on or before this date, YYYY-MM-DD. Can't be combined with time or tbs
756
+ */
757
+ end_date?: string;
758
+ /**
759
+ * @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)
760
+ * @default false
761
+ */
762
+ highlights?: boolean;
763
+ };
764
+ /** @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`). */
765
+ DomainList: string | string[];
766
+ /** @description A query-relevant passage of a page, verbatim */
767
+ Highlight: {
768
+ text: string;
769
+ /** @description Relevance to the query (BM25; higher is better */
770
+ score: number;
771
+ /** @description The section heading path the passage sits under */
772
+ heading?: string;
534
773
  };
535
774
  /** @description One of place_id, cid or fid is required */
536
775
  ReviewsRequest: {
@@ -557,7 +796,10 @@ interface components {
557
796
  max_age?: number;
558
797
  };
559
798
  WebpageRequest: {
560
- /** Format: uri */
799
+ /**
800
+ * Format: uri
801
+ * @description An HTML page or a PDF
802
+ */
561
803
  url: string;
562
804
  /**
563
805
  * @default json
@@ -566,121 +808,454 @@ interface components {
566
808
  format?: "json" | "markdown" | "compact";
567
809
  /** @default false */
568
810
  include_html?: boolean;
569
- max_age?: number;
570
- };
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: {
580
811
  /**
581
- * @example google
582
- * @example brave
812
+ * @description Also return the page's outbound links (`links`)
813
+ * @default false
583
814
  */
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;
815
+ include_links?: boolean;
593
816
  /**
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
817
+ * @description Also return the page's image URLs (`image_links`)
818
+ * @default false
599
819
  */
600
- engine?: string;
601
- /** @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
- route?: components["schemas"]["RouteStep"][];
603
- cached: boolean;
604
- /** Format: date-time */
605
- cached_at?: string;
606
- resolved_urls?: boolean;
607
- /** @enum {string} */
608
- parse_quality?: "ok" | "partial" | "empty";
609
- latency_ms?: number;
820
+ include_images?: boolean;
821
+ /** @description Fetch through an exit in this country (ISO 3166-1 alpha-2) for geo-dependent pages */
822
+ country?: string;
823
+ max_age?: number;
610
824
  };
611
- /** @description The normalised request that produced this response (defaults filled in) */
612
- RequestEcho: {
825
+ ExtractRequest: {
826
+ /** @description HTML pages or PDFs (duplicates are dropped) */
827
+ urls: string[];
613
828
  /**
614
- * @example search
615
- * @example news
616
- * @example webpage
829
+ * @default markdown
830
+ * @enum {string}
617
831
  */
618
- endpoint: string;
619
- /** @description The engine policy as asked (google, auto, one provider or a list) */
620
- engine: string | string[];
621
- q?: string;
622
- url?: string;
832
+ format?: "markdown" | "text" | "html";
833
+ /** @description What highlights are ranked against */
834
+ query?: string;
835
+ /**
836
+ * @description Query-ranked passages per page (BM25; needs query)
837
+ * @default 0
838
+ */
839
+ highlights?: number;
840
+ /** @description Trim each page's markdown or text to about this many tokens */
841
+ max_tokens?: number;
842
+ /** @default false */
843
+ include_links?: boolean;
844
+ /** @default false */
845
+ include_images?: boolean;
846
+ /** @description Accept a cached page up to this many seconds old (0.5 credit) */
847
+ max_age?: number;
848
+ /** @description Fetch through an exit in this country (ISO 3166-1 alpha-2) */
623
849
  country?: string;
624
- language?: string;
625
- location?: string;
626
- num?: number;
627
- page?: number;
628
- device?: string;
629
- autocorrect?: boolean;
630
- tbs?: string;
631
- safe?: string;
632
- place_id?: string;
633
- cid?: string;
634
- fid?: string;
635
- sort?: string;
636
- include_content?: number;
637
- format?: string;
638
- } & {
639
- [key: string]: unknown;
640
- };
641
- Sitelink: {
642
- title: string;
643
- link: string;
644
- snippet?: string;
645
- };
646
- OrganicResult: {
647
- position: number;
648
- title: string;
649
- /** @description Resolved destination URL (never a google.com/url or /goto redirect) */
650
- link: string;
651
- /** @description Canonical host without www. */
652
- domain: string;
653
- displayed_link?: string;
654
- snippet?: string;
655
- date?: string;
656
- sitelinks?: components["schemas"]["Sitelink"][];
657
- attributes?: {
658
- [key: string]: string;
659
- };
660
- rating?: number;
661
- rating_count?: number;
662
- /** @description Page Markdown when include_content covered this result */
663
- content?: string;
664
850
  /**
665
- * @description engine=consensus only. The providers that returned this result, in route order; results are ranked by how many there are
666
- * @example [
667
- * "google",
668
- * "brave",
669
- * "bing"
670
- * ]
851
+ * @description Seconds to wait for the pages; a page still loading is listed in `failed` (`upstream_timeout`, not charged)
852
+ * @default 50
671
853
  */
672
- sources?: components["schemas"]["Provider"][];
673
- };
674
- AnswerBox: {
675
- title?: string;
676
- answer?: string;
677
- snippet?: string;
678
- snippet_highlighted?: string[];
679
- link?: string;
854
+ timeout?: number;
680
855
  };
681
- KnowledgeGraph: {
856
+ ExtractResult: {
857
+ /** @description Final URL after redirects */
858
+ url: string;
859
+ status_code?: number;
682
860
  title?: string;
683
- type?: string;
861
+ /** @description The page's published time as ISO 8601, when it has one */
862
+ published_at?: string;
863
+ metadata?: components["schemas"]["PageMetadata"];
864
+ cached: boolean;
865
+ /** @description format=markdown */
866
+ markdown?: string;
867
+ /** @description format=text */
868
+ text?: string;
869
+ /** @description format=html (null for a PDF); at most 2 MiB per page */
870
+ html?: string | null;
871
+ /** @description include_links=true only */
872
+ links?: components["schemas"]["PageLink"][];
873
+ /** @description include_images=true only */
874
+ images?: string[];
875
+ /** @description highlights > 0 only */
876
+ highlights?: components["schemas"]["Highlight"][];
877
+ };
878
+ ExtractFailure: {
879
+ url: string;
880
+ error: {
881
+ /**
882
+ * @example invalid_request
883
+ * @example upstream_error
884
+ * @example upstream_timeout
885
+ * @example empty_page
886
+ */
887
+ code: string;
888
+ message: string;
889
+ };
890
+ };
891
+ ExtractResponse: {
892
+ request: {
893
+ /** @constant */
894
+ endpoint?: "extract";
895
+ urls?: string[];
896
+ format?: string;
897
+ query?: string;
898
+ } & {
899
+ [key: string]: unknown;
900
+ };
901
+ results: components["schemas"]["ExtractResult"][];
902
+ failed: components["schemas"]["ExtractFailure"][];
903
+ meta: {
904
+ request_id: string;
905
+ credits_used: number;
906
+ latency_ms?: number;
907
+ succeeded: number;
908
+ failed: number;
909
+ };
910
+ };
911
+ CrawlRequest: {
912
+ /**
913
+ * Format: uri
914
+ * @description Start page (always read: path filters and robots.txt apply to the pages found from it)
915
+ */
916
+ url: string;
917
+ /**
918
+ * @description Maximum pages read (and credits reserved)
919
+ * @default 25
920
+ */
921
+ limit?: number;
922
+ /**
923
+ * @description Link hops from url (sitemap pages count as 1 hop; 0 reads only url)
924
+ * @default 2
925
+ */
926
+ max_depth?: number;
927
+ /** @description Regular expressions matched against the URL path; follow only paths matching one */
928
+ include_paths?: string[];
929
+ /** @description Regular expressions matched against the URL path; never follow paths matching one */
930
+ exclude_paths?: string[];
931
+ /** @default false */
932
+ include_subdomains?: boolean;
933
+ /**
934
+ * @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
935
+ * @default include
936
+ * @enum {string}
937
+ */
938
+ sitemap?: "include" | "only" | "skip";
939
+ /** @description Read the pages most relevant to these words first (best-first crawl) */
940
+ query?: string;
941
+ /**
942
+ * @description Treat URLs that differ only in their query string as one page
943
+ * @default false
944
+ */
945
+ ignore_query_parameters?: boolean;
946
+ /**
947
+ * @default markdown
948
+ * @enum {string}
949
+ */
950
+ format?: "markdown" | "text";
951
+ /**
952
+ * @description Return each page's outbound links
953
+ * @default false
954
+ */
955
+ include_links?: boolean;
956
+ /** @description Trim each page to this many tokens */
957
+ max_tokens?: number;
958
+ /** @description Accept cached pages up to this many seconds old (0.5 credit each) */
959
+ max_age?: number;
960
+ /**
961
+ * Format: uri
962
+ * @description Receives the signed `crawl.completed` event. Defaults to the account webhook
963
+ */
964
+ webhook_url?: string;
965
+ };
966
+ /** @enum {string} */
967
+ TaskStatus: "queued" | "running" | "completed" | "failed" | "canceled";
968
+ TaskCreated: {
969
+ /** Format: uuid */
970
+ id: string;
971
+ /** @enum {string} */
972
+ kind: "crawl";
973
+ status: components["schemas"]["TaskStatus"];
974
+ /** Format: date-time */
975
+ created_at: string;
976
+ poll_url: string;
977
+ credits_reserved: number;
978
+ webhook_url?: string | null;
979
+ };
980
+ TaskCancelResponse: {
981
+ /** Format: uuid */
982
+ id: string;
983
+ /** @enum {string} */
984
+ status: "canceled" | "canceling";
985
+ };
986
+ /** @description Set when the task failed or was canceled */
987
+ TaskError: {
988
+ /**
989
+ * @example no_pages
990
+ * @example canceled
991
+ * @example timeout
992
+ * @example internal
993
+ */
994
+ code?: string;
995
+ message?: string;
996
+ } | null;
997
+ CrawlPage: {
998
+ url: string;
999
+ /** @description Link hops from the start page */
1000
+ depth: number;
1001
+ title?: string;
1002
+ markdown?: string;
1003
+ text?: string;
1004
+ published_at?: string;
1005
+ metadata?: components["schemas"]["PageMetadata"];
1006
+ links?: components["schemas"]["PageLink"][];
1007
+ };
1008
+ CrawlResult: {
1009
+ url: string;
1010
+ pages: components["schemas"]["CrawlPage"][];
1011
+ failed: components["schemas"]["ExtractFailure"][];
1012
+ stats: {
1013
+ pages?: number;
1014
+ failed?: number;
1015
+ seconds?: number;
1016
+ /** @description Unique URLs found that passed the filters */
1017
+ discovered?: number;
1018
+ /** @description Found but not read when the crawl ended */
1019
+ queued?: number;
1020
+ /** @description Pages that redirected to a page already read (not charged) */
1021
+ duplicates?: number;
1022
+ /** @description URLs taken from sitemaps */
1023
+ sitemap_urls?: number;
1024
+ /**
1025
+ * @description The start host's robots.txt
1026
+ * @enum {string}
1027
+ */
1028
+ robots?: "found" | "missing" | "unreachable" | "none";
1029
+ /** @description Disallow rules in force on the start host */
1030
+ robots_disallowed?: number;
1031
+ /** @description URLs skipped because robots.txt disallows them */
1032
+ robots_blocked?: number;
1033
+ /** @description The start host's Crawl-delay, honoured */
1034
+ crawl_delay_ms?: number;
1035
+ /**
1036
+ * @description Why the crawl ended
1037
+ * @enum {string}
1038
+ */
1039
+ stopped?: "done" | "limit" | "time_limit" | "size_limit" | "too_many_failures" | "canceled";
1040
+ };
1041
+ };
1042
+ CrawlTask: {
1043
+ /** Format: uuid */
1044
+ id: string;
1045
+ /** @constant */
1046
+ kind: "crawl";
1047
+ status: components["schemas"]["TaskStatus"];
1048
+ /** Format: date-time */
1049
+ created_at: string;
1050
+ /** Format: date-time */
1051
+ started_at?: string | null;
1052
+ /** Format: date-time */
1053
+ completed_at?: string | null;
1054
+ credits_reserved: number;
1055
+ credits_used: number;
1056
+ /** @enum {string|null} */
1057
+ webhook_status?: "pending" | "delivered" | "failed" | null;
1058
+ progress?: ({
1059
+ pages_done?: number;
1060
+ pages_failed?: number;
1061
+ pages_queued?: number;
1062
+ pages_discovered?: number;
1063
+ limit?: number;
1064
+ } & {
1065
+ [key: string]: unknown;
1066
+ }) | null;
1067
+ /** @description Set once the crawl ends (also on cancel, with the pages read so far) */
1068
+ result?: components["schemas"]["CrawlResult"] | null;
1069
+ error?: components["schemas"]["TaskError"];
1070
+ };
1071
+ MapRequest: {
1072
+ /**
1073
+ * Format: uri
1074
+ * @description The site (any page of it; sitemaps are read from its origin)
1075
+ */
1076
+ url: string;
1077
+ /** @description Keep only URLs relevant to these words, most relevant first */
1078
+ search?: string;
1079
+ /** @default 100 */
1080
+ limit?: number;
1081
+ /** @default false */
1082
+ include_subdomains?: boolean;
1083
+ /** @description Regular expressions matched against the URL path; keep only URLs matching one */
1084
+ include_paths?: string[];
1085
+ /** @description Regular expressions matched against the URL path; drop URLs matching one */
1086
+ exclude_paths?: string[];
1087
+ /**
1088
+ * @description Treat URLs that differ only in their query string as one (the first one found is kept)
1089
+ * @default false
1090
+ */
1091
+ ignore_query_parameters?: boolean;
1092
+ /**
1093
+ * @description `include` sitemaps and the start page's links, `only` sitemaps, `skip` sitemaps (links only)
1094
+ * @default include
1095
+ * @enum {string}
1096
+ */
1097
+ sitemap?: "include" | "only" | "skip";
1098
+ };
1099
+ MapURL: {
1100
+ url: string;
1101
+ title?: string;
1102
+ /** @description The sitemap's lastmod, as written */
1103
+ lastmod?: string;
1104
+ /** @enum {string} */
1105
+ source: "sitemap" | "page";
1106
+ };
1107
+ MapResponse: {
1108
+ request: {
1109
+ /** @constant */
1110
+ endpoint?: "map";
1111
+ url?: string;
1112
+ search?: string;
1113
+ limit?: number;
1114
+ sitemap?: string;
1115
+ include_subdomains?: boolean;
1116
+ include_paths?: string[];
1117
+ exclude_paths?: string[];
1118
+ ignore_query_parameters?: boolean;
1119
+ } & {
1120
+ [key: string]: unknown;
1121
+ };
1122
+ results: components["schemas"]["MapURL"][];
1123
+ meta: {
1124
+ request_id: string;
1125
+ credits_used: number;
1126
+ latency_ms?: number;
1127
+ count: number;
1128
+ };
1129
+ };
1130
+ /**
1131
+ * @description A search provider (docs/providers). Which verticals each serves depends on the deployment.
1132
+ * @enum {string}
1133
+ */
1134
+ Provider: "google" | "brave" | "bing" | "yahoo" | "duckduckgo" | "mojeek" | "wikipedia";
1135
+ /** @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). */
1136
+ EngineParam: string | components["schemas"]["Provider"][];
1137
+ /** @description One provider attempt behind this answer. Proxy pools are internal and never listed. */
1138
+ RouteStep: {
1139
+ /**
1140
+ * @example google
1141
+ * @example brave
1142
+ */
1143
+ provider: string;
1144
+ /** @enum {string} */
1145
+ outcome: "ok" | "partial" | "empty" | "soft_empty" | "blocked" | "timeout" | "error" | "unsupported" | "bad_param" | "bad_target" | "canceled";
1146
+ /** @description Duration of the attempt in milliseconds */
1147
+ ms: number;
1148
+ };
1149
+ Meta: {
1150
+ request_id: string;
1151
+ credits_used: number;
1152
+ /**
1153
+ * @description The provider that produced the result (`consensus` for a merged engine=consensus answer)
1154
+ * @example google
1155
+ * @example brave
1156
+ * @example consensus
1157
+ * @example stub
1158
+ */
1159
+ engine?: string;
1160
+ /** @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` */
1161
+ route?: components["schemas"]["RouteStep"][];
1162
+ cached: boolean;
1163
+ /** Format: date-time */
1164
+ cached_at?: string;
1165
+ resolved_urls?: boolean;
1166
+ /** @enum {string} */
1167
+ parse_quality?: "ok" | "partial" | "empty";
1168
+ latency_ms?: number;
1169
+ };
1170
+ /** @description The normalised request that produced this response (defaults filled in) */
1171
+ RequestEcho: {
1172
+ /**
1173
+ * @example search
1174
+ * @example news
1175
+ * @example webpage
1176
+ */
1177
+ endpoint: string;
1178
+ /** @description The engine policy as asked (google, auto, one provider or a list) */
1179
+ engine: string | string[];
1180
+ q?: string;
1181
+ url?: string;
1182
+ country?: string;
1183
+ language?: string;
1184
+ location?: string;
1185
+ num?: number;
1186
+ page?: number;
1187
+ device?: string;
1188
+ autocorrect?: boolean;
1189
+ tbs?: string;
1190
+ /** Format: date */
1191
+ start_date?: string;
1192
+ /** Format: date */
1193
+ end_date?: string;
1194
+ safe?: string;
1195
+ place_id?: string;
1196
+ cid?: string;
1197
+ fid?: string;
1198
+ sort?: string;
1199
+ include_content?: number;
1200
+ format?: string;
1201
+ include_domains?: string[];
1202
+ exclude_domains?: string[];
1203
+ boost_domains?: string[];
1204
+ highlights?: boolean;
1205
+ } & {
1206
+ [key: string]: unknown;
1207
+ };
1208
+ Sitelink: {
1209
+ title: string;
1210
+ link: string;
1211
+ snippet?: string;
1212
+ };
1213
+ OrganicResult: {
1214
+ position: number;
1215
+ title: string;
1216
+ /** @description Resolved destination URL (never a google.com/url or /goto redirect) */
1217
+ link: string;
1218
+ /** @description Canonical host without www. */
1219
+ domain: string;
1220
+ displayed_link?: string;
1221
+ snippet?: string;
1222
+ date?: string;
1223
+ sitelinks?: components["schemas"]["Sitelink"][];
1224
+ attributes?: {
1225
+ [key: string]: string;
1226
+ };
1227
+ rating?: number;
1228
+ rating_count?: number;
1229
+ /**
1230
+ * @description `date` as an ISO 8601 date or date-time when it parses (relative dates resolved against the fetch time)
1231
+ * @example 2026-09-30
1232
+ * @example 2026-10-03T09:00:00Z
1233
+ */
1234
+ published_at?: string;
1235
+ /** @description Page Markdown when include_content covered this result */
1236
+ content?: string;
1237
+ /** @description highlights=true only. Query-ranked passages of the fetched page, best first (instead of content) */
1238
+ highlights?: components["schemas"]["Highlight"][];
1239
+ /**
1240
+ * @description engine=consensus only. The providers that returned this result, in route order; results are ranked by how many there are
1241
+ * @example [
1242
+ * "google",
1243
+ * "brave",
1244
+ * "bing"
1245
+ * ]
1246
+ */
1247
+ sources?: components["schemas"]["Provider"][];
1248
+ };
1249
+ AnswerBox: {
1250
+ title?: string;
1251
+ answer?: string;
1252
+ snippet?: string;
1253
+ snippet_highlighted?: string[];
1254
+ link?: string;
1255
+ };
1256
+ KnowledgeGraph: {
1257
+ title?: string;
1258
+ type?: string;
684
1259
  website?: string;
685
1260
  image_url?: string;
686
1261
  description?: string;
@@ -738,6 +1313,8 @@ interface components {
738
1313
  source?: string;
739
1314
  channel?: string;
740
1315
  date?: string;
1316
+ /** @description `date` as ISO 8601 when it parses */
1317
+ published_at?: string;
741
1318
  };
742
1319
  VideosResponse: {
743
1320
  request: components["schemas"]["RequestEcho"];
@@ -751,6 +1328,8 @@ interface components {
751
1328
  domain?: string;
752
1329
  snippet?: string;
753
1330
  date?: string;
1331
+ /** @description `date` as ISO 8601 when it parses */
1332
+ published_at?: string;
754
1333
  source?: string;
755
1334
  image_url?: string;
756
1335
  };
@@ -883,6 +1462,20 @@ interface components {
883
1462
  image?: string;
884
1463
  published_time?: string;
885
1464
  author?: string;
1465
+ /**
1466
+ * @description The page's media type
1467
+ * @example text/html
1468
+ * @example application/pdf
1469
+ */
1470
+ content_type?: string;
1471
+ /** @description Page count of a PDF */
1472
+ pages?: number;
1473
+ };
1474
+ PageLink: {
1475
+ /** @description Absolute URL */
1476
+ url: string;
1477
+ /** @description Anchor text */
1478
+ text?: string;
886
1479
  };
887
1480
  WebpageResponse: {
888
1481
  request: components["schemas"]["RequestEcho"];
@@ -894,6 +1487,10 @@ interface components {
894
1487
  /** @description Only with include_html=true */
895
1488
  html?: string;
896
1489
  metadata: components["schemas"]["PageMetadata"];
1490
+ /** @description include_links=true only. Outbound links in document order, deduplicated */
1491
+ links?: components["schemas"]["PageLink"][];
1492
+ /** @description include_images=true only. Image URLs in document order */
1493
+ image_links?: string[];
897
1494
  meta: components["schemas"]["Meta"];
898
1495
  };
899
1496
  CSEResponse: {
@@ -1033,33 +1630,304 @@ interface components {
1033
1630
  requests: number;
1034
1631
  };
1035
1632
  };
1036
- };
1037
- responses: {
1038
- /** @description Error */
1039
- Error: {
1040
- headers: {
1041
- [name: string]: unknown;
1042
- };
1043
- content: {
1044
- "application/json": components["schemas"]["Error"];
1633
+ /** @description Body of `crawl.completed` */
1634
+ TaskCompletedEvent: {
1635
+ /** @constant */
1636
+ event: "crawl.completed";
1637
+ /** Format: uuid */
1638
+ id: string;
1639
+ /** @constant */
1640
+ kind: "crawl";
1641
+ status: components["schemas"]["TaskStatus"];
1642
+ /** Format: date-time */
1643
+ created_at: string;
1644
+ /** Format: date-time */
1645
+ completed_at?: string | null;
1646
+ credits_used: number;
1647
+ /** @description Where the task (and its full result) can be fetched for 24 hours */
1648
+ poll_url?: string;
1649
+ /** @description The CrawlResult (null when the crawl failed without one, or when it is larger than 4 MB: see result_omitted) */
1650
+ result?: unknown;
1651
+ /** @description Set when the result was too large for the webhook; GET poll_url for it */
1652
+ result_omitted?: boolean;
1653
+ error?: {
1654
+ code?: string;
1655
+ message?: string;
1045
1656
  };
1046
1657
  };
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"];
1658
+ /** @description The saved request a monitor reruns: a search (q and options) or, for webpage monitors, url (and country) */
1659
+ MonitorSearch: {
1660
+ q?: string;
1661
+ url?: string;
1662
+ country?: string;
1663
+ language?: string;
1664
+ location?: string;
1665
+ /** @enum {string} */
1666
+ time?: "hour" | "day" | "week" | "month" | "year";
1667
+ num?: number;
1668
+ device?: string;
1669
+ safe?: string;
1670
+ include_domains?: string[];
1671
+ exclude_domains?: string[];
1672
+ engine?: string[];
1673
+ };
1674
+ /** @description Search and news monitors need `q`; webpage monitors need `url` and take only `country` besides */
1675
+ MonitorCreateRequest: {
1676
+ q?: string;
1677
+ /**
1678
+ * Format: uri
1679
+ * @description endpoint=webpage: the page to watch for content changes
1680
+ */
1681
+ url?: string;
1682
+ /**
1683
+ * @default search
1684
+ * @enum {string}
1685
+ */
1686
+ endpoint?: "search" | "news" | "webpage";
1687
+ /** @description Your own JSON object (at most 2 KB), echoed on the monitor and in its webhooks */
1688
+ metadata?: {
1689
+ [key: string]: unknown;
1690
+ };
1691
+ name?: string;
1692
+ /**
1693
+ * @default daily
1694
+ * @enum {string}
1695
+ */
1696
+ interval?: "hourly" | "daily" | "weekly";
1697
+ /** @description Overrides interval */
1698
+ interval_seconds?: number;
1699
+ /**
1700
+ * Format: uri
1701
+ * @description Receives signed `monitor.results` events. Without one, read new results from the run history
1702
+ */
1703
+ webhook_url?: string;
1704
+ /**
1705
+ * @description false creates the monitor paused
1706
+ * @default true
1707
+ */
1708
+ active?: boolean;
1709
+ country?: string;
1710
+ language?: string;
1711
+ location?: string;
1712
+ /** @enum {string} */
1713
+ time?: "hour" | "day" | "week" | "month" | "year";
1714
+ num?: number;
1715
+ /** @enum {string} */
1716
+ device?: "desktop" | "mobile";
1717
+ /** @enum {string} */
1718
+ safe?: "active" | "off";
1719
+ include_domains?: components["schemas"]["DomainList"];
1720
+ exclude_domains?: components["schemas"]["DomainList"];
1721
+ engine?: components["schemas"]["EngineParam"];
1722
+ };
1723
+ /** @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. */
1724
+ MonitorUpdateRequest: {
1725
+ name?: string;
1726
+ /** @enum {string} */
1727
+ interval?: "hourly" | "daily" | "weekly";
1728
+ interval_seconds?: number;
1729
+ /** @description A webhook URL, or an empty string to remove it */
1730
+ webhook_url?: string;
1731
+ /** @description true resumes a paused monitor (due now, failure streak cleared) */
1732
+ active?: boolean;
1733
+ /** @description Replaces the metadata (null clears it) */
1734
+ metadata?: {
1735
+ [key: string]: unknown;
1736
+ } | null;
1737
+ /**
1738
+ * @description Switching between a search and a page drops the other kind's fields
1739
+ * @enum {string}
1740
+ */
1741
+ endpoint?: "search" | "news" | "webpage";
1742
+ q?: string;
1743
+ /**
1744
+ * Format: uri
1745
+ * @description endpoint=webpage only
1746
+ */
1747
+ url?: string;
1748
+ country?: string;
1749
+ language?: string;
1750
+ location?: string;
1751
+ /** @enum {string} */
1752
+ time?: "hour" | "day" | "week" | "month" | "year";
1753
+ num?: number;
1754
+ /** @enum {string} */
1755
+ device?: "desktop" | "mobile";
1756
+ /** @enum {string} */
1757
+ safe?: "active" | "off";
1758
+ include_domains?: components["schemas"]["DomainList"];
1759
+ exclude_domains?: components["schemas"]["DomainList"];
1760
+ engine?: components["schemas"]["EngineParam"];
1761
+ };
1762
+ Monitor: {
1763
+ /** Format: uuid */
1764
+ id: string;
1765
+ name: string;
1766
+ /** @enum {string} */
1767
+ endpoint: "search" | "news" | "webpage";
1768
+ request: components["schemas"]["MonitorSearch"];
1769
+ metadata?: {
1770
+ [key: string]: unknown;
1771
+ } | null;
1772
+ interval_seconds: number;
1773
+ /** @description Null when new results are only kept in the run history */
1774
+ webhook_url: string | null;
1775
+ active: boolean;
1776
+ /** Format: date-time */
1777
+ next_run_at: string;
1778
+ /** Format: date-time */
1779
+ last_run_at?: string | null;
1780
+ /** @enum {string|null} */
1781
+ last_status?: "ok" | "error" | "webhook_failed" | "paused" | null;
1782
+ last_error?: string | null;
1783
+ /** @description New results found by the last run */
1784
+ last_new_results?: number;
1785
+ runs: number;
1786
+ /** @description Failed runs in a row; the monitor pauses itself at 10 */
1787
+ consecutive_failures: number;
1788
+ /** @description Total over all runs */
1789
+ credits_used: number;
1790
+ /** Format: date-time */
1791
+ created_at: string;
1792
+ };
1793
+ MonitorRun: {
1794
+ /** Format: uuid */
1795
+ id: string;
1796
+ /** @enum {string} */
1797
+ status: "ok" | "error" | "webhook_failed" | "paused";
1798
+ error?: string | null;
1799
+ new_results: number;
1800
+ /** @description The new results (OrganicResult-shaped for search, NewsResult for news, MonitorPageChange for webpage); null when there were none or after 24 hours */
1801
+ results?: {
1802
+ [key: string]: unknown;
1803
+ }[] | null;
1804
+ credits_used: number;
1805
+ /**
1806
+ * @description none = the monitor has no webhook; null = nothing to send
1807
+ * @enum {string|null}
1808
+ */
1809
+ webhook_status?: "delivered" | "failed" | "none" | null;
1810
+ /** Format: date-time */
1811
+ created_at: string;
1812
+ };
1813
+ /** @description What a webpage monitor reports when the page is new to it or its content changed */
1814
+ MonitorPageChange: {
1815
+ /** @description Final URL after redirects */
1816
+ url: string;
1817
+ title?: string;
1818
+ /** @enum {string} */
1819
+ change: "new" | "changed";
1820
+ /** @description Fingerprint of the content (whitespace-insensitive) */
1821
+ content_hash: string;
1822
+ /** @description The page's Markdown (up to about 8 */
1823
+ markdown: string;
1824
+ published_at?: string;
1825
+ };
1826
+ MonitorRunList: {
1827
+ results: components["schemas"]["MonitorRun"][];
1828
+ /**
1829
+ * Format: uuid
1830
+ * @description Pass as `before` for the next page; null on the last page
1831
+ */
1832
+ next_before: string | null;
1833
+ };
1834
+ MonitorList: {
1835
+ results: components["schemas"]["Monitor"][];
1836
+ };
1837
+ /** @description Body of `monitor.results` */
1838
+ MonitorResultsEvent: {
1839
+ /** @constant */
1840
+ event: "monitor.results";
1841
+ /** Format: uuid */
1842
+ monitor_id: string;
1843
+ /**
1844
+ * Format: uuid
1845
+ * @description Also the X-SerpKite-Delivery header; use it to deduplicate retries
1846
+ */
1847
+ run_id: string;
1848
+ name: string;
1849
+ /** @enum {string} */
1850
+ endpoint: "search" | "news" | "webpage";
1851
+ /** @description The saved query (empty for webpage monitors) */
1852
+ q: string;
1853
+ /** @description webpage monitors only */
1854
+ url?: string;
1855
+ /** @description The monitor's metadata */
1856
+ metadata?: {
1857
+ [key: string]: unknown;
1858
+ } | null;
1859
+ /** @description The first run since the monitor was created or its search changed */
1860
+ first_run: boolean;
1861
+ /** Format: date-time */
1862
+ run_at: string;
1863
+ /** @description Results not seen in earlier runs (OrganicResult-shaped for search, NewsResult for news, MonitorPageChange for webpage) */
1864
+ new_results: {
1865
+ [key: string]: unknown;
1866
+ }[];
1867
+ /** @description This run's price */
1868
+ credits_used: number;
1869
+ };
1870
+ };
1871
+ responses: {
1872
+ /** @description Error */
1873
+ Error: {
1874
+ headers: {
1057
1875
  [name: string]: unknown;
1058
1876
  };
1059
1877
  content: {
1060
1878
  "application/json": components["schemas"]["Error"];
1061
1879
  };
1062
1880
  };
1881
+ /**
1882
+ * @description Temporarily unavailable, not billed, safe to retry after `Retry-After`.
1883
+ * Codes: `upstream_error` (the upstream page couldn't be fetched or parsed),
1884
+ * `upstream_blocked` (the upstream is rate limiting us), `upstream_timeout`
1885
+ * (the search took too long), `unavailable` (endpoint or dependency down).
1886
+ * The API never sends 502 or 504.
1887
+ */
1888
+ Unavailable: {
1889
+ headers: {
1890
+ "Retry-After": components["headers"]["RetryAfter"];
1891
+ [name: string]: unknown;
1892
+ };
1893
+ content: {
1894
+ "application/json": components["schemas"]["Error"];
1895
+ };
1896
+ };
1897
+ /** @description Queued. Poll `poll_url` or wait for the webhook */
1898
+ TaskAccepted: {
1899
+ headers: {
1900
+ /** @description The maximum price, reserved until the task ends */
1901
+ "X-Credits-Reserved"?: number;
1902
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
1903
+ /** @description Path of the task (`/v1/{kind}/{id}`) */
1904
+ Location?: string;
1905
+ [name: string]: unknown;
1906
+ };
1907
+ content: {
1908
+ /**
1909
+ * @example {
1910
+ * "id": "01926a3e-7b2c-7c4e-9f1a-2b3c4d5e6f70",
1911
+ * "kind": "crawl",
1912
+ * "status": "queued",
1913
+ * "created_at": "2026-10-03T12:00:00Z",
1914
+ * "poll_url": "https://api.serpkite.com/v1/crawl/01926a3e-7b2c-7c4e-9f1a-2b3c4d5e6f70",
1915
+ * "credits_reserved": 50,
1916
+ * "webhook_url": null
1917
+ * }
1918
+ */
1919
+ "application/json": components["schemas"]["TaskCreated"];
1920
+ };
1921
+ };
1922
+ /** @description `canceled` (it was queued: refunded at once) or `canceling` (it is running and stops at its next checkpoint) */
1923
+ TaskCanceled: {
1924
+ headers: {
1925
+ [name: string]: unknown;
1926
+ };
1927
+ content: {
1928
+ "application/json": components["schemas"]["TaskCancelResponse"];
1929
+ };
1930
+ };
1063
1931
  /** @description OK (text/markdown when format=markdown) */
1064
1932
  SearchOK: {
1065
1933
  headers: {
@@ -1220,6 +2088,115 @@ interface components {
1220
2088
  "text/markdown": string;
1221
2089
  };
1222
2090
  };
2091
+ /** @description OK */
2092
+ ExtractOK: {
2093
+ headers: {
2094
+ "X-Credits-Used": components["headers"]["CreditsUsed"];
2095
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
2096
+ "X-Cost-USD": components["headers"]["CostUSD"];
2097
+ "X-Cache": components["headers"]["Cache"];
2098
+ "X-Latency-Ms": components["headers"]["LatencyMs"];
2099
+ "X-Tokens-Estimate": components["headers"]["TokensEstimate"];
2100
+ [name: string]: unknown;
2101
+ };
2102
+ content: {
2103
+ /**
2104
+ * @example {
2105
+ * "request": {
2106
+ * "endpoint": "extract",
2107
+ * "urls": [
2108
+ * "https://example.com/pricing",
2109
+ * "https://example.com/missing"
2110
+ * ],
2111
+ * "format": "markdown",
2112
+ * "query": "enterprise price"
2113
+ * },
2114
+ * "results": [
2115
+ * {
2116
+ * "url": "https://example.com/pricing",
2117
+ * "status_code": 200,
2118
+ * "title": "Pricing",
2119
+ * "metadata": {
2120
+ * "title": "Pricing",
2121
+ * "content_type": "text/html"
2122
+ * },
2123
+ * "cached": false,
2124
+ * "markdown": "# Pricing\n\n…",
2125
+ * "highlights": [
2126
+ * {
2127
+ * "text": "Enterprise: $499 per month …",
2128
+ * "score": 4.83,
2129
+ * "heading": "Plans"
2130
+ * }
2131
+ * ]
2132
+ * }
2133
+ * ],
2134
+ * "failed": [
2135
+ * {
2136
+ * "url": "https://example.com/missing",
2137
+ * "error": {
2138
+ * "code": "upstream_error",
2139
+ * "message": "could not fetch the page: the site answered 404; you were not charged"
2140
+ * }
2141
+ * }
2142
+ * ],
2143
+ * "meta": {
2144
+ * "request_id": "req_01J9",
2145
+ * "credits_used": 1,
2146
+ * "latency_ms": 2210,
2147
+ * "succeeded": 1,
2148
+ * "failed": 1
2149
+ * }
2150
+ * }
2151
+ */
2152
+ "application/json": components["schemas"]["ExtractResponse"];
2153
+ };
2154
+ };
2155
+ /** @description OK */
2156
+ MapOK: {
2157
+ headers: {
2158
+ "X-Credits-Used": components["headers"]["CreditsUsed"];
2159
+ "X-Credits-Remaining": components["headers"]["CreditsRemaining"];
2160
+ "X-Cost-USD": components["headers"]["CostUSD"];
2161
+ "X-Cache": components["headers"]["Cache"];
2162
+ "X-Latency-Ms": components["headers"]["LatencyMs"];
2163
+ "X-Tokens-Estimate": components["headers"]["TokensEstimate"];
2164
+ [name: string]: unknown;
2165
+ };
2166
+ content: {
2167
+ /**
2168
+ * @example {
2169
+ * "request": {
2170
+ * "endpoint": "map",
2171
+ * "url": "https://docs.example.com/",
2172
+ * "limit": 50,
2173
+ * "sitemap": "include",
2174
+ * "include_subdomains": false,
2175
+ * "search": "install guide"
2176
+ * },
2177
+ * "results": [
2178
+ * {
2179
+ * "url": "https://docs.example.com/install",
2180
+ * "lastmod": "2026-09-01",
2181
+ * "source": "sitemap"
2182
+ * },
2183
+ * {
2184
+ * "url": "https://docs.example.com/guide",
2185
+ * "title": "Guide",
2186
+ * "source": "page"
2187
+ * }
2188
+ * ],
2189
+ * "meta": {
2190
+ * "request_id": "req_01J9",
2191
+ * "credits_used": 1,
2192
+ * "latency_ms": 840,
2193
+ * "count": 2
2194
+ * }
2195
+ * }
2196
+ */
2197
+ "application/json": components["schemas"]["MapResponse"];
2198
+ };
2199
+ };
1223
2200
  /** @description OK (text/markdown when format=markdown) */
1224
2201
  WebpageOK: {
1225
2202
  headers: {
@@ -1281,6 +2258,16 @@ interface operations {
1281
2258
  max_age?: number;
1282
2259
  /** @description google (default), auto, consensus, one provider, or a comma-separated list (e.g. google,brave) */
1283
2260
  engine?: string;
2261
+ /** @description Comma-separated domains, or the key repeated (see SearchRequest.include_domains) */
2262
+ include_domains?: string;
2263
+ /** @description Comma-separated domains, or the key repeated */
2264
+ exclude_domains?: string;
2265
+ /** @description Comma-separated domains, or the key repeated */
2266
+ boost_domains?: string;
2267
+ start_date?: string;
2268
+ end_date?: string;
2269
+ /** @description Needs include_content */
2270
+ highlights?: boolean;
1284
2271
  api_key?: string;
1285
2272
  };
1286
2273
  header?: never;
@@ -1359,54 +2346,328 @@ interface operations {
1359
2346
  path?: never;
1360
2347
  cookie?: never;
1361
2348
  };
1362
- requestBody: components["requestBodies"]["Search"];
2349
+ requestBody: components["requestBodies"]["Search"];
2350
+ responses: {
2351
+ 200: components["responses"]["NewsOK"];
2352
+ 400: components["responses"]["Error"];
2353
+ 401: components["responses"]["Error"];
2354
+ 402: components["responses"]["Error"];
2355
+ 403: components["responses"]["Error"];
2356
+ 429: components["responses"]["Error"];
2357
+ 503: components["responses"]["Unavailable"];
2358
+ };
2359
+ };
2360
+ maps: {
2361
+ parameters: {
2362
+ query?: never;
2363
+ header?: never;
2364
+ path?: never;
2365
+ cookie?: never;
2366
+ };
2367
+ requestBody: components["requestBodies"]["Search"];
2368
+ responses: {
2369
+ 200: components["responses"]["PlacesOK"];
2370
+ 400: components["responses"]["Error"];
2371
+ 401: components["responses"]["Error"];
2372
+ 402: components["responses"]["Error"];
2373
+ 403: components["responses"]["Error"];
2374
+ 429: components["responses"]["Error"];
2375
+ 503: components["responses"]["Unavailable"];
2376
+ };
2377
+ };
2378
+ places: {
2379
+ parameters: {
2380
+ query?: never;
2381
+ header?: never;
2382
+ path?: never;
2383
+ cookie?: never;
2384
+ };
2385
+ requestBody: components["requestBodies"]["Search"];
2386
+ responses: {
2387
+ 200: components["responses"]["PlacesOK"];
2388
+ 400: components["responses"]["Error"];
2389
+ 401: components["responses"]["Error"];
2390
+ 402: components["responses"]["Error"];
2391
+ 403: components["responses"]["Error"];
2392
+ 429: components["responses"]["Error"];
2393
+ 503: components["responses"]["Unavailable"];
2394
+ };
2395
+ };
2396
+ reviews: {
2397
+ parameters: {
2398
+ query?: never;
2399
+ header?: never;
2400
+ path?: never;
2401
+ cookie?: never;
2402
+ };
2403
+ requestBody: {
2404
+ content: {
2405
+ "application/json": components["schemas"]["ReviewsRequest"];
2406
+ };
2407
+ };
2408
+ responses: {
2409
+ 200: components["responses"]["ReviewsOK"];
2410
+ 400: components["responses"]["Error"];
2411
+ 401: components["responses"]["Error"];
2412
+ 402: components["responses"]["Error"];
2413
+ 403: components["responses"]["Error"];
2414
+ 429: components["responses"]["Error"];
2415
+ 503: components["responses"]["Unavailable"];
2416
+ };
2417
+ };
2418
+ shopping: {
2419
+ parameters: {
2420
+ query?: never;
2421
+ header?: never;
2422
+ path?: never;
2423
+ cookie?: never;
2424
+ };
2425
+ requestBody: components["requestBodies"]["Search"];
2426
+ responses: {
2427
+ 200: components["responses"]["ShoppingOK"];
2428
+ 400: components["responses"]["Error"];
2429
+ 401: components["responses"]["Error"];
2430
+ 402: components["responses"]["Error"];
2431
+ 403: components["responses"]["Error"];
2432
+ 429: components["responses"]["Error"];
2433
+ 503: components["responses"]["Unavailable"];
2434
+ };
2435
+ };
2436
+ scholar: {
2437
+ parameters: {
2438
+ query?: never;
2439
+ header?: never;
2440
+ path?: never;
2441
+ cookie?: never;
2442
+ };
2443
+ requestBody: components["requestBodies"]["Search"];
2444
+ responses: {
2445
+ 200: components["responses"]["ScholarOK"];
2446
+ 400: components["responses"]["Error"];
2447
+ 401: components["responses"]["Error"];
2448
+ 402: components["responses"]["Error"];
2449
+ 403: components["responses"]["Error"];
2450
+ 429: components["responses"]["Error"];
2451
+ 503: components["responses"]["Unavailable"];
2452
+ };
2453
+ };
2454
+ patents: {
2455
+ parameters: {
2456
+ query?: never;
2457
+ header?: never;
2458
+ path?: never;
2459
+ cookie?: never;
2460
+ };
2461
+ requestBody: components["requestBodies"]["Search"];
2462
+ responses: {
2463
+ 200: components["responses"]["PatentsOK"];
2464
+ 400: components["responses"]["Error"];
2465
+ 401: components["responses"]["Error"];
2466
+ 402: components["responses"]["Error"];
2467
+ 403: components["responses"]["Error"];
2468
+ 429: components["responses"]["Error"];
2469
+ 503: components["responses"]["Unavailable"];
2470
+ };
2471
+ };
2472
+ autocomplete: {
2473
+ parameters: {
2474
+ query?: never;
2475
+ header?: never;
2476
+ path?: never;
2477
+ cookie?: never;
2478
+ };
2479
+ requestBody: components["requestBodies"]["Search"];
2480
+ responses: {
2481
+ 200: components["responses"]["AutocompleteOK"];
2482
+ 400: components["responses"]["Error"];
2483
+ 401: components["responses"]["Error"];
2484
+ 402: components["responses"]["Error"];
2485
+ 403: components["responses"]["Error"];
2486
+ 429: components["responses"]["Error"];
2487
+ 503: components["responses"]["Unavailable"];
2488
+ };
2489
+ };
2490
+ webpage: {
2491
+ parameters: {
2492
+ query?: never;
2493
+ header?: never;
2494
+ path?: never;
2495
+ cookie?: never;
2496
+ };
2497
+ requestBody: {
2498
+ content: {
2499
+ "application/json": components["schemas"]["WebpageRequest"];
2500
+ };
2501
+ };
2502
+ responses: {
2503
+ 200: components["responses"]["WebpageOK"];
2504
+ 400: components["responses"]["Error"];
2505
+ 401: components["responses"]["Error"];
2506
+ 402: components["responses"]["Error"];
2507
+ 403: components["responses"]["Error"];
2508
+ 429: components["responses"]["Error"];
2509
+ 503: components["responses"]["Unavailable"];
2510
+ };
2511
+ };
2512
+ extract: {
2513
+ parameters: {
2514
+ query?: never;
2515
+ header?: never;
2516
+ path?: never;
2517
+ cookie?: never;
2518
+ };
2519
+ requestBody: {
2520
+ content: {
2521
+ /**
2522
+ * @example {
2523
+ * "urls": [
2524
+ * "https://example.com/pricing",
2525
+ * "https://example.com/docs/limits.pdf"
2526
+ * ],
2527
+ * "query": "enterprise price",
2528
+ * "highlights": 2
2529
+ * }
2530
+ */
2531
+ "application/json": components["schemas"]["ExtractRequest"];
2532
+ };
2533
+ };
2534
+ responses: {
2535
+ 200: components["responses"]["ExtractOK"];
2536
+ 400: components["responses"]["Error"];
2537
+ 401: components["responses"]["Error"];
2538
+ 402: components["responses"]["Error"];
2539
+ 403: components["responses"]["Error"];
2540
+ 429: components["responses"]["Error"];
2541
+ 503: components["responses"]["Unavailable"];
2542
+ };
2543
+ };
2544
+ map: {
2545
+ parameters: {
2546
+ query?: never;
2547
+ header?: never;
2548
+ path?: never;
2549
+ cookie?: never;
2550
+ };
2551
+ requestBody: {
2552
+ content: {
2553
+ /**
2554
+ * @example {
2555
+ * "url": "https://docs.example.com/",
2556
+ * "search": "install guide",
2557
+ * "limit": 50
2558
+ * }
2559
+ */
2560
+ "application/json": components["schemas"]["MapRequest"];
2561
+ };
2562
+ };
2563
+ responses: {
2564
+ 200: components["responses"]["MapOK"];
2565
+ 400: components["responses"]["Error"];
2566
+ 401: components["responses"]["Error"];
2567
+ 402: components["responses"]["Error"];
2568
+ 403: components["responses"]["Error"];
2569
+ 429: components["responses"]["Error"];
2570
+ 503: components["responses"]["Unavailable"];
2571
+ };
2572
+ };
2573
+ createCrawl: {
2574
+ parameters: {
2575
+ query?: never;
2576
+ header?: never;
2577
+ path?: never;
2578
+ cookie?: never;
2579
+ };
2580
+ requestBody: {
2581
+ content: {
2582
+ /**
2583
+ * @example {
2584
+ * "url": "https://docs.example.com/",
2585
+ * "limit": 50,
2586
+ * "max_depth": 2,
2587
+ * "include_paths": [
2588
+ * "^/guides/"
2589
+ * ]
2590
+ * }
2591
+ */
2592
+ "application/json": components["schemas"]["CrawlRequest"];
2593
+ };
2594
+ };
2595
+ responses: {
2596
+ 202: components["responses"]["TaskAccepted"];
2597
+ 400: components["responses"]["Error"];
2598
+ 401: components["responses"]["Error"];
2599
+ 402: components["responses"]["Error"];
2600
+ 403: components["responses"]["Error"];
2601
+ 429: components["responses"]["Error"];
2602
+ 503: components["responses"]["Unavailable"];
2603
+ };
2604
+ };
2605
+ getCrawl: {
2606
+ parameters: {
2607
+ query?: never;
2608
+ header?: never;
2609
+ path: {
2610
+ id: string;
2611
+ };
2612
+ cookie?: never;
2613
+ };
2614
+ requestBody?: never;
1363
2615
  responses: {
1364
- 200: components["responses"]["NewsOK"];
1365
- 400: components["responses"]["Error"];
2616
+ /** @description OK */
2617
+ 200: {
2618
+ headers: {
2619
+ [name: string]: unknown;
2620
+ };
2621
+ content: {
2622
+ "application/json": components["schemas"]["CrawlTask"];
2623
+ };
2624
+ };
1366
2625
  401: components["responses"]["Error"];
1367
- 402: components["responses"]["Error"];
1368
- 403: components["responses"]["Error"];
2626
+ 404: components["responses"]["Error"];
1369
2627
  429: components["responses"]["Error"];
1370
- 503: components["responses"]["Unavailable"];
1371
2628
  };
1372
2629
  };
1373
- maps: {
2630
+ cancelCrawl: {
1374
2631
  parameters: {
1375
2632
  query?: never;
1376
2633
  header?: never;
1377
- path?: never;
2634
+ path: {
2635
+ id: string;
2636
+ };
1378
2637
  cookie?: never;
1379
2638
  };
1380
- requestBody: components["requestBodies"]["Search"];
2639
+ requestBody?: never;
1381
2640
  responses: {
1382
- 200: components["responses"]["PlacesOK"];
1383
- 400: components["responses"]["Error"];
2641
+ 200: components["responses"]["TaskCanceled"];
1384
2642
  401: components["responses"]["Error"];
1385
- 402: components["responses"]["Error"];
1386
- 403: components["responses"]["Error"];
2643
+ 404: components["responses"]["Error"];
2644
+ 409: components["responses"]["Error"];
1387
2645
  429: components["responses"]["Error"];
1388
- 503: components["responses"]["Unavailable"];
1389
2646
  };
1390
2647
  };
1391
- places: {
2648
+ listMonitors: {
1392
2649
  parameters: {
1393
2650
  query?: never;
1394
2651
  header?: never;
1395
2652
  path?: never;
1396
2653
  cookie?: never;
1397
2654
  };
1398
- requestBody: components["requestBodies"]["Search"];
2655
+ requestBody?: never;
1399
2656
  responses: {
1400
- 200: components["responses"]["PlacesOK"];
1401
- 400: components["responses"]["Error"];
2657
+ /** @description OK */
2658
+ 200: {
2659
+ headers: {
2660
+ [name: string]: unknown;
2661
+ };
2662
+ content: {
2663
+ "application/json": components["schemas"]["MonitorList"];
2664
+ };
2665
+ };
1402
2666
  401: components["responses"]["Error"];
1403
- 402: components["responses"]["Error"];
1404
- 403: components["responses"]["Error"];
1405
2667
  429: components["responses"]["Error"];
1406
- 503: components["responses"]["Unavailable"];
1407
2668
  };
1408
2669
  };
1409
- reviews: {
2670
+ createMonitor: {
1410
2671
  parameters: {
1411
2672
  query?: never;
1412
2673
  header?: never;
@@ -1415,111 +2676,172 @@ interface operations {
1415
2676
  };
1416
2677
  requestBody: {
1417
2678
  content: {
1418
- "application/json": components["schemas"]["ReviewsRequest"];
2679
+ /**
2680
+ * @example {
2681
+ * "q": "ai agents",
2682
+ * "endpoint": "news",
2683
+ * "interval": "hourly",
2684
+ * "name": "agents news",
2685
+ * "webhook_url": "https://example.com/hooks/serpkite"
2686
+ * }
2687
+ */
2688
+ "application/json": components["schemas"]["MonitorCreateRequest"];
1419
2689
  };
1420
2690
  };
1421
2691
  responses: {
1422
- 200: components["responses"]["ReviewsOK"];
2692
+ /** @description Created */
2693
+ 201: {
2694
+ headers: {
2695
+ [name: string]: unknown;
2696
+ };
2697
+ content: {
2698
+ "application/json": components["schemas"]["Monitor"];
2699
+ };
2700
+ };
1423
2701
  400: components["responses"]["Error"];
1424
2702
  401: components["responses"]["Error"];
1425
- 402: components["responses"]["Error"];
1426
2703
  403: components["responses"]["Error"];
1427
2704
  429: components["responses"]["Error"];
1428
- 503: components["responses"]["Unavailable"];
1429
2705
  };
1430
2706
  };
1431
- shopping: {
2707
+ getMonitor: {
1432
2708
  parameters: {
1433
2709
  query?: never;
1434
2710
  header?: never;
1435
- path?: never;
2711
+ path: {
2712
+ id: string;
2713
+ };
1436
2714
  cookie?: never;
1437
2715
  };
1438
- requestBody: components["requestBodies"]["Search"];
2716
+ requestBody?: never;
1439
2717
  responses: {
1440
- 200: components["responses"]["ShoppingOK"];
1441
- 400: components["responses"]["Error"];
2718
+ /** @description OK */
2719
+ 200: {
2720
+ headers: {
2721
+ [name: string]: unknown;
2722
+ };
2723
+ content: {
2724
+ "application/json": components["schemas"]["Monitor"];
2725
+ };
2726
+ };
1442
2727
  401: components["responses"]["Error"];
1443
- 402: components["responses"]["Error"];
1444
- 403: components["responses"]["Error"];
2728
+ 404: components["responses"]["Error"];
1445
2729
  429: components["responses"]["Error"];
1446
- 503: components["responses"]["Unavailable"];
1447
2730
  };
1448
2731
  };
1449
- scholar: {
2732
+ deleteMonitor: {
1450
2733
  parameters: {
1451
2734
  query?: never;
1452
2735
  header?: never;
1453
- path?: never;
2736
+ path: {
2737
+ id: string;
2738
+ };
1454
2739
  cookie?: never;
1455
2740
  };
1456
- requestBody: components["requestBodies"]["Search"];
2741
+ requestBody?: never;
1457
2742
  responses: {
1458
- 200: components["responses"]["ScholarOK"];
1459
- 400: components["responses"]["Error"];
2743
+ /** @description Deleted */
2744
+ 204: {
2745
+ headers: {
2746
+ [name: string]: unknown;
2747
+ };
2748
+ content?: never;
2749
+ };
1460
2750
  401: components["responses"]["Error"];
1461
- 402: components["responses"]["Error"];
1462
- 403: components["responses"]["Error"];
2751
+ 404: components["responses"]["Error"];
1463
2752
  429: components["responses"]["Error"];
1464
- 503: components["responses"]["Unavailable"];
1465
2753
  };
1466
2754
  };
1467
- patents: {
2755
+ updateMonitor: {
1468
2756
  parameters: {
1469
2757
  query?: never;
1470
2758
  header?: never;
1471
- path?: never;
2759
+ path: {
2760
+ id: string;
2761
+ };
1472
2762
  cookie?: never;
1473
2763
  };
1474
- requestBody: components["requestBodies"]["Search"];
2764
+ requestBody: {
2765
+ content: {
2766
+ /**
2767
+ * @example {
2768
+ * "active": false,
2769
+ * "interval": "daily"
2770
+ * }
2771
+ */
2772
+ "application/json": components["schemas"]["MonitorUpdateRequest"];
2773
+ };
2774
+ };
1475
2775
  responses: {
1476
- 200: components["responses"]["PatentsOK"];
2776
+ /** @description OK */
2777
+ 200: {
2778
+ headers: {
2779
+ [name: string]: unknown;
2780
+ };
2781
+ content: {
2782
+ "application/json": components["schemas"]["Monitor"];
2783
+ };
2784
+ };
1477
2785
  400: components["responses"]["Error"];
1478
2786
  401: components["responses"]["Error"];
1479
- 402: components["responses"]["Error"];
1480
- 403: components["responses"]["Error"];
2787
+ 404: components["responses"]["Error"];
1481
2788
  429: components["responses"]["Error"];
1482
- 503: components["responses"]["Unavailable"];
1483
2789
  };
1484
2790
  };
1485
- autocomplete: {
2791
+ listMonitorRuns: {
1486
2792
  parameters: {
1487
- query?: never;
2793
+ query?: {
2794
+ limit?: number;
2795
+ /** @description `next_before` of the previous page */
2796
+ before?: string;
2797
+ };
1488
2798
  header?: never;
1489
- path?: never;
2799
+ path: {
2800
+ id: string;
2801
+ };
1490
2802
  cookie?: never;
1491
2803
  };
1492
- requestBody: components["requestBodies"]["Search"];
2804
+ requestBody?: never;
1493
2805
  responses: {
1494
- 200: components["responses"]["AutocompleteOK"];
2806
+ /** @description OK */
2807
+ 200: {
2808
+ headers: {
2809
+ [name: string]: unknown;
2810
+ };
2811
+ content: {
2812
+ "application/json": components["schemas"]["MonitorRunList"];
2813
+ };
2814
+ };
1495
2815
  400: components["responses"]["Error"];
1496
2816
  401: components["responses"]["Error"];
1497
- 402: components["responses"]["Error"];
1498
- 403: components["responses"]["Error"];
2817
+ 404: components["responses"]["Error"];
1499
2818
  429: components["responses"]["Error"];
1500
- 503: components["responses"]["Unavailable"];
1501
2819
  };
1502
2820
  };
1503
- webpage: {
2821
+ runMonitor: {
1504
2822
  parameters: {
1505
2823
  query?: never;
1506
2824
  header?: never;
1507
- path?: never;
1508
- cookie?: never;
1509
- };
1510
- requestBody: {
1511
- content: {
1512
- "application/json": components["schemas"]["WebpageRequest"];
2825
+ path: {
2826
+ id: string;
1513
2827
  };
2828
+ cookie?: never;
1514
2829
  };
2830
+ requestBody?: never;
1515
2831
  responses: {
1516
- 200: components["responses"]["WebpageOK"];
1517
- 400: components["responses"]["Error"];
2832
+ /** @description Scheduled */
2833
+ 202: {
2834
+ headers: {
2835
+ [name: string]: unknown;
2836
+ };
2837
+ content: {
2838
+ "application/json": components["schemas"]["Monitor"];
2839
+ };
2840
+ };
1518
2841
  401: components["responses"]["Error"];
1519
- 402: components["responses"]["Error"];
1520
- 403: components["responses"]["Error"];
2842
+ 404: components["responses"]["Error"];
2843
+ 409: components["responses"]["Error"];
1521
2844
  429: components["responses"]["Error"];
1522
- 503: components["responses"]["Unavailable"];
1523
2845
  };
1524
2846
  };
1525
2847
  customSearch: {
@@ -1777,6 +3099,50 @@ interface operations {
1777
3099
  401: components["responses"]["Error"];
1778
3100
  };
1779
3101
  };
3102
+ crawlCompletedWebhook: {
3103
+ parameters: {
3104
+ query?: never;
3105
+ header?: never;
3106
+ path?: never;
3107
+ cookie?: never;
3108
+ };
3109
+ requestBody: {
3110
+ content: {
3111
+ "application/json": components["schemas"]["TaskCompletedEvent"];
3112
+ };
3113
+ };
3114
+ responses: {
3115
+ /** @description Any 2xx acknowledges the delivery */
3116
+ 200: {
3117
+ headers: {
3118
+ [name: string]: unknown;
3119
+ };
3120
+ content?: never;
3121
+ };
3122
+ };
3123
+ };
3124
+ monitorResultsWebhook: {
3125
+ parameters: {
3126
+ query?: never;
3127
+ header?: never;
3128
+ path?: never;
3129
+ cookie?: never;
3130
+ };
3131
+ requestBody: {
3132
+ content: {
3133
+ "application/json": components["schemas"]["MonitorResultsEvent"];
3134
+ };
3135
+ };
3136
+ responses: {
3137
+ /** @description Any 2xx acknowledges the delivery */
3138
+ 200: {
3139
+ headers: {
3140
+ [name: string]: unknown;
3141
+ };
3142
+ content?: never;
3143
+ };
3144
+ };
3145
+ };
1780
3146
  }
1781
3147
 
1782
3148
  type Schemas = components["schemas"];
@@ -1807,6 +3173,8 @@ type SearchParams = Omit<Schemas["SearchRequest"], "engine"> & {
1807
3173
  type ReviewsParams = Schemas["ReviewsRequest"];
1808
3174
  type WebpageParams = Schemas["WebpageRequest"];
1809
3175
  type RankParams = Schemas["RankRequest"];
3176
+ type MapParams = Schemas["MapRequest"];
3177
+ type ExtractParams = Schemas["ExtractRequest"];
1810
3178
  /** `format` values accepted by the verticals. */
1811
3179
  type Format = NonNullable<SearchParams["format"]>;
1812
3180
  type Meta = Schemas["Meta"];
@@ -1828,6 +3196,15 @@ type ScholarResult = Schemas["ScholarResult"];
1828
3196
  type PatentResult = Schemas["PatentResult"];
1829
3197
  type Suggestion = Schemas["Suggestion"];
1830
3198
  type PageMetadata = Schemas["PageMetadata"];
3199
+ /** An outbound link of a page (`webpage` with `include_links`). */
3200
+ type PageLink = Schemas["PageLink"];
3201
+ /** A query-ranked passage of a page (`search` with `highlights`). */
3202
+ type Highlight = Schemas["Highlight"];
3203
+ /** A domain filter: a list or a comma-separated string (`include_domains`…). */
3204
+ type DomainList = Schemas["DomainList"];
3205
+ type MapURL = Schemas["MapURL"];
3206
+ type ExtractResult = Schemas["ExtractResult"];
3207
+ type ExtractFailure = Schemas["ExtractFailure"];
1831
3208
  type RankMatch = Schemas["RankResponse"]["matches"][number];
1832
3209
  type SearchResponse = Schemas["SearchResponse"];
1833
3210
  type ImagesResponse = Schemas["ImagesResponse"];
@@ -1843,6 +3220,8 @@ type PatentsResponse = Schemas["PatentsResponse"];
1843
3220
  type AutocompleteResponse = Schemas["AutocompleteResponse"];
1844
3221
  type WebpageResponse = Schemas["WebpageResponse"];
1845
3222
  type RankResponse = Schemas["RankResponse"];
3223
+ type MapResponse = Schemas["MapResponse"];
3224
+ type ExtractResponse = Schemas["ExtractResponse"];
1846
3225
  type Account = Schemas["Account"];
1847
3226
  type Status = Schemas["Status"];
1848
3227
  /**
@@ -1891,8 +3270,102 @@ type BatchCreateParams = {
1891
3270
  webhook_url?: string;
1892
3271
  };
1893
3272
  }[BatchEndpoint];
3273
+ type TaskStatus = Schemas["TaskStatus"];
3274
+ /** The `202` body of `crawl`. */
3275
+ type TaskCreated = Schemas["TaskCreated"];
3276
+ type TaskCancelResponse = Schemas["TaskCancelResponse"];
3277
+ type TaskError = Schemas["TaskError"];
3278
+ /**
3279
+ * Body of `POST /v1/crawl`: `limit` up to 1000 pages, `max_depth` up to 10, `sitemap`
3280
+ * (`include` | `only` | `skip`), `query` for a best-first crawl, path filters and
3281
+ * `ignore_query_parameters`.
3282
+ */
3283
+ type CrawlParams = Schemas["CrawlRequest"];
3284
+ /** `sitemap` values of `crawl`. */
3285
+ type CrawlSitemapMode = NonNullable<CrawlParams["sitemap"]>;
3286
+ type CrawlTask = Schemas["CrawlTask"];
3287
+ type CrawlResult = Schemas["CrawlResult"];
3288
+ /** `result.stats` of a crawl: counts, robots.txt outcome and why it `stopped`. */
3289
+ type CrawlStats = CrawlResult["stats"];
3290
+ /** Why a crawl ended (`result.stats.stopped`). */
3291
+ type CrawlStopReason = NonNullable<CrawlStats["stopped"]>;
3292
+ type CrawlPage = Schemas["CrawlPage"];
3293
+ /**
3294
+ * Body of `POST /v1/monitors`. `search` and `news` monitors need `q`; `webpage` monitors need
3295
+ * `url` (and take only `country` besides) and report the page when its content changes.
3296
+ * `metadata` is your own JSON object (at most 2 KB), echoed on the monitor and its webhooks.
3297
+ * `webhook_url` is optional: without one, new results are read from the run history
3298
+ * (`monitors.runs`). `active: false` creates the monitor paused.
3299
+ */
3300
+ type MonitorCreateParams = Omit<Schemas["MonitorCreateRequest"], "engine"> & {
3301
+ engine?: Engine;
3302
+ };
3303
+ /**
3304
+ * Body of `PATCH /v1/monitors/{id}`: only the fields sent change. Search fields (or `url`) are
3305
+ * merged into the saved request (a changed one reports every result as new on the next run);
3306
+ * switching `endpoint` between a search and `webpage` drops the other kind's fields.
3307
+ * `metadata` replaces the stored object (`null` clears it); `webhook_url: ""` removes the
3308
+ * webhook; `active: true` resumes a paused monitor.
3309
+ */
3310
+ type MonitorUpdateParams = Omit<Schemas["MonitorUpdateRequest"], "engine"> & {
3311
+ engine?: Engine;
3312
+ };
3313
+ type Monitor = Schemas["Monitor"];
3314
+ /** What a monitor watches: a `search`, `news` search, or a `webpage` for content changes. */
3315
+ type MonitorEndpoint = Monitor["endpoint"];
3316
+ /** Your own JSON object on a monitor (at most 2 KB), echoed in `monitor.results`. */
3317
+ type MonitorMetadata = NonNullable<Monitor["metadata"]>;
3318
+ /**
3319
+ * A result item of a `webpage` monitor (in run `results` and `monitor.results` `new_results`):
3320
+ * the page when first seen (`change: "new"`) or when its content changed (`"changed"`).
3321
+ */
3322
+ type MonitorPageChange = Schemas["MonitorPageChange"];
3323
+ /** `last_status` of a monitor; `"paused"` after 10 failed runs in a row. */
3324
+ type MonitorStatus = NonNullable<Monitor["last_status"]>;
3325
+ type MonitorList = Schemas["MonitorList"];
3326
+ type MonitorSearch = Schemas["MonitorSearch"];
3327
+ /**
3328
+ * One run of a monitor. `results` holds the new results (null when none, or after 24 hours):
3329
+ * `OrganicResult`-shaped for search, `NewsResult` for news, {@link MonitorPageChange} for webpage.
3330
+ */
3331
+ type MonitorRun = Schemas["MonitorRun"];
3332
+ /** A page of runs, newest first. Pass `next_before` as `before` for the next page. */
3333
+ type MonitorRunList = Schemas["MonitorRunList"];
3334
+ /** Query of `GET /v1/monitors/{id}/runs`. */
3335
+ type MonitorRunsParams = NonNullable<operations["listMonitorRuns"]["parameters"]["query"]>;
3336
+ /** Body of `batch.completed`: the finished job, without `poll_url`, `webhook_url` and `webhook_status`. */
3337
+ type BatchCompletedEvent = Omit<Batch, "poll_url" | "webhook_url" | "webhook_status"> & {
3338
+ event: "batch.completed";
3339
+ };
3340
+ /**
3341
+ * Body of `crawl.completed`. When the result is over 4 MB, `result` is null and
3342
+ * `result_omitted` is true: fetch the task from `poll_url`.
3343
+ */
3344
+ type TaskCompletedEvent = Schemas["TaskCompletedEvent"];
3345
+ /**
3346
+ * Body of `monitor.results`. `run_id` is also the `X-SerpKite-Delivery` header (dedupe retries
3347
+ * on it). Carries the monitor's `metadata`, and `url` for webpage monitors (whose `new_results`
3348
+ * are {@link MonitorPageChange} items and `q` is empty).
3349
+ */
3350
+ type MonitorResultsEvent = Schemas["MonitorResultsEvent"];
3351
+ /** `X-SerpKite-Event` values. Plain strings stay accepted for events added later. */
3352
+ type WebhookEventType = "batch.completed" | "crawl.completed" | "monitor.results" | (string & {});
3353
+ /** A verified webhook delivery, from `parseWebhook`. */
3354
+ type WebhookEvent = {
3355
+ type: "batch.completed";
3356
+ deliveryId: string | undefined;
3357
+ data: BatchCompletedEvent;
3358
+ } | {
3359
+ type: "crawl.completed";
3360
+ deliveryId: string | undefined;
3361
+ data: TaskCompletedEvent;
3362
+ } | {
3363
+ type: "monitor.results";
3364
+ deliveryId: string | undefined;
3365
+ data: MonitorResultsEvent;
3366
+ };
1894
3367
 
1895
- declare const VERSION = "0.3.0";
3368
+ declare const VERSION = "0.4.0";
1896
3369
  declare const DEFAULT_BASE_URL = "https://api.serpkite.com";
1897
3370
  interface SerpKiteOptions {
1898
3371
  /** API key (`skt_live_…`). Defaults to the `SERPKITE_API_KEY` environment variable. */
@@ -1942,7 +3415,10 @@ interface BatchCreateOptions extends RequestOptions {
1942
3415
  idempotencyKey?: string;
1943
3416
  }
1944
3417
  interface WaitOptions {
1945
- /** Give up after this many milliseconds. Default 600000 (10 minutes). */
3418
+ /**
3419
+ * Give up after this many milliseconds. Default 600000 (10 minutes) for batches and
3420
+ * 2100000 (35 minutes) for `waitForCrawl`: a crawl runs for up to 30 minutes.
3421
+ */
1946
3422
  timeoutMs?: number;
1947
3423
  /** First delay between polls. Default 1000. Grows 1.5× per poll. */
1948
3424
  pollIntervalMs?: number;
@@ -1963,7 +3439,7 @@ interface VerticalMethod<P, R> {
1963
3439
  }, options?: RequestOptions): Promise<R>;
1964
3440
  (params: P, options?: RequestOptions): Promise<R | CompactResponse | string>;
1965
3441
  }
1966
- type Method = "GET" | "POST";
3442
+ type Method = "GET" | "POST" | "PATCH" | "DELETE";
1967
3443
  interface Call {
1968
3444
  method: Method;
1969
3445
  path: string;
@@ -2070,6 +3546,9 @@ declare class SerpKite {
2070
3546
  url: string;
2071
3547
  format?: "json" | "markdown" | "compact";
2072
3548
  include_html?: boolean;
3549
+ include_links?: boolean;
3550
+ include_images?: boolean;
3551
+ country?: string;
2073
3552
  max_age?: number;
2074
3553
  }, {
2075
3554
  request: components["schemas"]["RequestEcho"];
@@ -2079,12 +3558,93 @@ declare class SerpKite {
2079
3558
  text?: string;
2080
3559
  html?: string;
2081
3560
  metadata: components["schemas"]["PageMetadata"];
3561
+ links?: components["schemas"]["PageLink"][];
3562
+ image_links?: string[];
2082
3563
  meta: components["schemas"]["Meta"];
2083
3564
  }>;
2084
3565
  /** Position of `domain` for keyword `q` in the top `num` results (default 100). */
2085
3566
  rank(params: RankParams, options?: RequestOptions): Promise<RankResponse>;
3567
+ /**
3568
+ * Read up to 20 URLs (HTML or PDF) as Markdown, text or HTML in one call, with optional
3569
+ * query-ranked `highlights` (BM25), `include_links` and `include_images`. 1 credit per URL
3570
+ * that comes back (0.5 from cache); URLs that fail are listed in `failed` and cost nothing.
3571
+ */
3572
+ extract(params: ExtractParams, options?: RequestOptions): Promise<ExtractResponse>;
3573
+ /**
3574
+ * The URLs of a site from its sitemaps (XML, RSS/Atom, gzip, plain text) and start page,
3575
+ * canonicalised and deduplicated, optionally ranked by `search`. `include_paths` /
3576
+ * `exclude_paths` (regular expressions on the URL path) and `ignore_query_parameters`
3577
+ * narrow the list. 1 credit; free when nothing is found.
3578
+ */
3579
+ map(params: MapParams, options?: RequestOptions): Promise<MapResponse>;
2086
3580
  /** Balance, limits and this month's usage for the key's account. */
2087
3581
  account(options?: RequestOptions): Promise<Account>;
3582
+ /**
3583
+ * Starts an async crawl of one site and returns the queued task (`202`). 1 credit per page
3584
+ * read (0.5 from cache); `limit` credits (up to 1000 pages, `max_depth` up to 10) are
3585
+ * reserved up front and the rest refunded. `sitemap` (`include` default, `only`, `skip`)
3586
+ * seeds the crawl with sitemap URLs; `query` reads the most relevant pages first. robots.txt
3587
+ * and Crawl-delay are honoured; `result.stats.stopped` says why the crawl ended (`done`,
3588
+ * `limit`, `time_limit`, `size_limit`, `too_many_failures`, `canceled`).
3589
+ * Only retried on 429, so a lost response never starts (and reserves) a second crawl.
3590
+ */
3591
+ crawl(params: CrawlParams, options?: RequestOptions): Promise<TaskCreated>;
3592
+ /** Polls a crawl (results are kept for 24 hours). */
3593
+ getCrawl(id: string, options?: RequestOptions): Promise<CrawlTask>;
3594
+ /** Cancels a crawl: refunded if still queued, else stops at the next checkpoint. */
3595
+ cancelCrawl(id: string, options?: RequestOptions): Promise<TaskCancelResponse>;
3596
+ /**
3597
+ * Polls until the crawl is `completed`, `failed` or `canceled` and returns it (a failed
3598
+ * task is returned, not thrown; check `status` and `error`). Accepts an id or the task
3599
+ * returned by `crawl`.
3600
+ */
3601
+ waitForCrawl(idOrTask: string | {
3602
+ id: string;
3603
+ }, options?: WaitOptions): Promise<CrawlTask>;
3604
+ readonly monitors: {
3605
+ /**
3606
+ * Saves a `search` or `news` request (`q`) that runs on a schedule (hourly to monthly) and
3607
+ * POSTs results it hasn't seen before to `webhook_url` (`monitor.results`). With
3608
+ * `endpoint: "webpage"` and a `url` it checks that page each interval (1 credit per check)
3609
+ * and reports it (`MonitorPageChange`) when its content changes. `metadata` (your JSON
3610
+ * object, at most 2 KB) is echoed on the monitor and in its webhooks. Without a
3611
+ * `webhook_url`, read new results from `monitors.runs`. `active: false`
3612
+ * creates it paused. A monitor pauses itself after 10 failed runs in a row
3613
+ * (`last_status: "paused"`); `update(id, { active: true })` resumes it. Each run costs
3614
+ * what its search costs. Only retried on 429.
3615
+ */
3616
+ create: (params: MonitorCreateParams, options?: RequestOptions) => Promise<Monitor>;
3617
+ /** The account's monitors. */
3618
+ list: (options?: RequestOptions) => Promise<MonitorList>;
3619
+ get: (id: string, options?: RequestOptions) => Promise<Monitor>;
3620
+ /**
3621
+ * Changes `name`, `interval` / `interval_seconds`, `webhook_url` (`""` removes it),
3622
+ * `active` (`true` resumes a paused monitor), `metadata` (an object replaces it, `null`
3623
+ * clears it) or the saved request (`endpoint`, `q`, `url`, `country`, `num`, domains,
3624
+ * `engine`…). Switching `endpoint` between a search and `webpage` drops the other kind's
3625
+ * fields. A changed search reports every result as new on the next run.
3626
+ */
3627
+ update: (id: string, params: MonitorUpdateParams, options?: RequestOptions) => Promise<Monitor>;
3628
+ delete: (id: string, options?: RequestOptions) => Promise<void>;
3629
+ /** Runs an active monitor at the next scheduler poll (within about 30 seconds).
3630
+ * Paused monitors return 409; update(id, { active: true }) resumes and schedules them. */
3631
+ run: (id: string, options?: RequestOptions) => Promise<Monitor>;
3632
+ /**
3633
+ * One page of the monitor's run history, newest first (`limit` 1-100, default 20). Each
3634
+ * run carries its new results for 24 hours. Pass `next_before` as `before` for the next
3635
+ * page; it is null on the last one.
3636
+ */
3637
+ runs: (id: string, params?: MonitorRunsParams, options?: RequestOptions) => Promise<MonitorRunList>;
3638
+ /**
3639
+ * Iterates over every run of the monitor, newest first, fetching pages of `limit` as
3640
+ * needed (starting at `before` when given).
3641
+ *
3642
+ * ```ts
3643
+ * for await (const run of sk.monitors.iterRuns("m1")) console.log(run.new_results);
3644
+ * ```
3645
+ */
3646
+ iterRuns: (id: string, params?: MonitorRunsParams, options?: RequestOptions) => AsyncIterable<MonitorRun>;
3647
+ };
2088
3648
  readonly batches: {
2089
3649
  /**
2090
3650
  * Queue 1-100 requests for one endpoint at half price. Returns one entry per
@@ -2157,7 +3717,8 @@ interface VerifyWebhookOptions {
2157
3717
  }
2158
3718
  type HeaderSource = Headers | Record<string, string | string[] | undefined>;
2159
3719
  /**
2160
- * Checks a batch webhook delivery: `X-SerpKite-Signature` must be
3720
+ * Checks a webhook delivery (any event: `batch.completed`, `crawl.completed`,
3721
+ * `monitor.results`): `X-SerpKite-Signature` must be
2161
3722
  * `v1=<hex HMAC-SHA256(secret, "<X-SerpKite-Timestamp>.<raw body>")>` and the
2162
3723
  * timestamp recent. Pass the raw request body exactly as received (not
2163
3724
  * re-serialised JSON). Uses Web Crypto (Node 18+, Deno, Bun, browsers).
@@ -2167,5 +3728,20 @@ type HeaderSource = Headers | Record<string, string | string[] | undefined>;
2167
3728
  * ```
2168
3729
  */
2169
3730
  declare function verifyWebhook(secret: string, payload: string | Uint8Array, headers: HeaderSource, options?: VerifyWebhookOptions): Promise<boolean>;
3731
+ /**
3732
+ * Verifies a delivery (see {@link verifyWebhook}) and returns it typed by its
3733
+ * `X-SerpKite-Event` header. `deliveryId` is `X-SerpKite-Delivery` (for
3734
+ * `monitor.results` it equals `data.run_id`): use it to deduplicate retries. A
3735
+ * `crawl.completed` result over 4 MB arrives as `result: null` with
3736
+ * `result_omitted: true`; fetch it from `data.poll_url`. Throws a
3737
+ * `SerpKiteError` with code `invalid_signature` when the signature or timestamp
3738
+ * doesn't check out.
3739
+ *
3740
+ * ```ts
3741
+ * const ev = await parseWebhook(secret, rawBody, req.headers);
3742
+ * if (ev.type === "monitor.results") console.log(ev.data.new_results.length);
3743
+ * ```
3744
+ */
3745
+ declare function parseWebhook(secret: string, payload: string | Uint8Array, headers: HeaderSource, options?: VerifyWebhookOptions): Promise<WebhookEvent>;
2170
3746
 
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 };
3747
+ 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 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 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 components, isBatchError, type operations, parseRetryAfter, parseWebhook, type paths, verifyWebhook };