Documentation
¶
Overview ¶
Package kagi is a handbuilt, idiomatic Go SDK for the Kagi Search API.
Construct a Client with NewClient and call Client.Search or Client.Extract. Transient failures (HTTP 429, 5xx, and network errors) are retried transparently with exponential backoff plus full jitter; see WithRetries and WithBackoff to tune the behavior. Errors are returned as *APIError values wrapping sentinel errors such as ErrUnauthorized and ErrRateLimited for use with errors.Is and errors.As.
Index ¶
- Variables
- type APIError
- type Client
- type DomainRule
- type DomainRuleKind
- type ErrorDetail
- type ExtractMeta
- type ExtractPage
- type ExtractRequest
- type ExtractResult
- type Image
- type Lens
- type Option
- type PageResult
- type Personalizations
- type RegexRule
- type SearchData
- type SearchExtract
- type SearchFilters
- type SearchHit
- type SearchMeta
- type SearchRequest
- type SearchResult
- type TimeRelative
- type Workflow
Constants ¶
This section is empty.
Variables ¶
var ( // missing or invalid API key. ErrUnauthorized = errors.New("kagi: unauthorized") // ErrRateLimited is returned for HTTP 429 responses. The accompanying // [APIError.RetryAfter] is populated when the server provides a // Retry-After header. ErrRateLimited = errors.New("kagi: rate limited") // ErrBadRequest is returned for HTTP 400 responses (and other non-401 // client-side 4xx codes), indicating the request was malformed or rejected // by validation. ErrBadRequest = errors.New("kagi: bad request") // ErrServerError is returned for HTTP 5xx responses, which are treated as // transient by the retry layer. ErrServerError = errors.New("kagi: server error") )
Sentinel errors returned for non-2xx API responses. Use errors.Is to test for a specific category, and errors.As with *APIError to access the full response detail.
if errors.Is(err, kagi.ErrRateLimited) {
var apiErr *kagi.APIError
if errors.As(err, &apiErr) {
time.Sleep(apiErr.RetryAfter)
}
}
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// StatusCode is the HTTP status code of the response.
StatusCode int
// Status is the HTTP status text of the response (for example, "429 Too Many Requests").
Status string
// Kind is the sentinel error this APIError unwraps to.
Kind error
// Details holds the parsed errorDetail entries from the response envelope.
// May be empty when the response body was missing, malformed, or did not
// follow the expected envelope shape.
Details []ErrorDetail
// RetryAfter is the parsed Retry-After header duration. It is populated
// for 429 and 5xx responses when the header is present, and is zero
// otherwise.
RetryAfter time.Duration
// TraceID is the meta.trace value from the response envelope, useful when
// contacting Kagi support. Empty when not provided.
TraceID string
// Body is the raw response body (capped) preserved for debugging when the
// envelope could not be parsed.
Body []byte
}
APIError is the concrete error type returned for non-2xx Kagi API responses. It implements [error] and unwraps to one of the sentinel errors (ErrUnauthorized, ErrRateLimited, ErrBadRequest, ErrServerError) so callers can match with errors.Is.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a Kagi API client.
Clients are safe to reuse across requests after construction. Requests that fail with HTTP 429, 5xx, or transient network errors are retried transparently with exponential backoff plus full jitter; see WithRetries and WithBackoff to tune the behavior.
func (*Client) Extract ¶
func (c *Client) Extract(ctx context.Context, req ExtractRequest) (*ExtractResult, error)
Extract fetches markdown content for one or more pages.
[ExtractRequest.Pages] is required; an empty slice or any entry with a blank URL is rejected without contacting the server. Server-side limits (1..10 pages, HTTPS scheme, timeout range) are enforced by the API and surface as a *APIError wrapping ErrBadRequest.
API errors are returned as a *APIError wrapping one of the package's sentinel errors (for example, ErrUnauthorized or ErrRateLimited); use errors.Is and errors.As to classify and inspect them.
func (*Client) Search ¶
func (c *Client) Search(ctx context.Context, req SearchRequest) (*SearchResult, error)
Search performs a web search.
SearchRequest.Query is required; an empty or whitespace-only query is rejected without contacting the server. The returned SearchResult groups hits by category in SearchData; any category may be absent for a given query.
API errors are returned as a *APIError wrapping one of the package's sentinel errors (for example, ErrUnauthorized or ErrRateLimited); use errors.Is and errors.As to classify and inspect them.
type DomainRule ¶
type DomainRule struct {
// Domain is the pattern to match, for example "example.com" or a TLD
// suffix such as ".co.uk".
Domain string `json:"domain"`
// Kind is how the matched domain should be handled.
Kind DomainRuleKind `json:"kind"`
}
DomainRule adjusts ranking for a domain pattern.
type DomainRuleKind ¶
type DomainRuleKind string
DomainRuleKind is the handling mode applied to a DomainRule.
const ( DomainRuleBlock DomainRuleKind = "block" DomainRuleLower DomainRuleKind = "lower" DomainRuleRaise DomainRuleKind = "raise" DomainRulePin DomainRuleKind = "pin" )
Supported DomainRuleKind values.
type ErrorDetail ¶
type ErrorDetail struct {
// Code is a namespaced error code (for example, "extract.invalid_url").
Code string `json:"code"`
// URL points to documentation for the error code.
URL string `json:"url"`
// Message is a human-readable description of the error.
Message string `json:"message,omitempty"`
// Location identifies the request field where the error occurred, when
// applicable (for example, "pages[0].url").
Location string `json:"location,omitempty"`
}
ErrorDetail mirrors a single entry of the Kagi API's errorDetail schema.
type ExtractMeta ¶
type ExtractMeta struct {
// Trace is the request trace ID, useful when contacting Kagi support.
Trace string `json:"trace"`
// Node identifies the server node that fulfilled the request.
Node string `json:"node"`
// MS is the server-side processing time in milliseconds, excluding
// network round-trip.
MS int `json:"ms"`
}
ExtractMeta is the meta envelope of an extract response.
The exact set of fields is intended for debugging and may evolve over time; callers should treat it as advisory and avoid building hard dependencies on individual fields.
type ExtractPage ¶
type ExtractPage struct {
// URL is the HTTPS URL of the page to extract. Required.
URL string `json:"url"`
}
ExtractPage identifies a single page to extract content from.
type ExtractRequest ¶
type ExtractRequest struct {
// Pages is the set of pages to extract. Server-side limits: 1..10
// entries, each URL must use the HTTPS scheme.
Pages []ExtractPage `json:"pages"`
// Timeout is a time budget for the entire bulk extraction operation,
// in seconds. Server-side range is 0.5..10; out-of-range values are
// clamped by the server.
Timeout float64 `json:"timeout,omitempty"`
}
ExtractRequest is the input to Client.Extract.
[ExtractRequest.Pages] is required and must contain between 1 and 10 entries (server-enforced). All other fields are optional and are omitted from the request body when left at their zero value.
type ExtractResult ¶
type ExtractResult struct {
// Meta carries trace and timing information about the request.
Meta ExtractMeta
// Data carries the extracted page results, in the same order as the
// request's [ExtractRequest.Pages] when the server produced output for
// each.
Data []PageResult
// Errors carries per-URL failures encountered during extraction. Empty
// when every page extracted cleanly.
Errors []ErrorDetail
}
ExtractResult is the response returned by Client.Extract.
A 200 response may include both extracted PageResult entries in [ExtractResult.Data] and per-URL failures in [ExtractResult.Errors]; the SDK does not convert that partial-success state into an error return.
type Image ¶
type Image struct {
// URL links directly to the image bytes.
URL string `json:"url"`
// Height is the image height in pixels, when reported by the server.
Height int `json:"height,omitempty"`
// Width is the image width in pixels, when reported by the server.
Width int `json:"width,omitempty"`
}
Image describes an image associated with a SearchHit.
type Lens ¶
type Lens struct {
// SitesIncluded restricts results to these domains.
SitesIncluded []string `json:"sites_included,omitempty"`
// SitesExcluded removes results from these domains.
SitesExcluded []string `json:"sites_excluded,omitempty"`
// KeywordsIncluded requires results to contain these keywords.
KeywordsIncluded []string `json:"keywords_included,omitempty"`
// KeywordsExcluded removes results containing these keywords.
KeywordsExcluded []string `json:"keywords_excluded,omitempty"`
// FileType narrows to a specific file type (for example, "pdf").
FileType string `json:"file_type,omitempty"`
// TimeAfter restricts to pages updated on or after this date
// (YYYY-MM-DD).
TimeAfter string `json:"time_after,omitempty"`
// TimeBefore restricts to pages updated on or before this date
// (YYYY-MM-DD).
TimeBefore string `json:"time_before,omitempty"`
// TimeRelative restricts to a recent window relative to today.
TimeRelative TimeRelative `json:"time_relative,omitempty"`
// SearchRegion requests results localized to a region. Use an
// ISO-3166-1 alpha-2 country code, or the special value "no_region".
SearchRegion string `json:"search_region,omitempty"`
}
Lens is an inline description of a search lens.
A lens restricts or shapes the result set without altering the query. See the Kagi lenses documentation for behavior of each field.
type Option ¶
type Option func(*config)
Option configures a Client.
func WithBackoff ¶
WithBackoff configures retry backoff timing.
base is the initial backoff window; the window doubles each attempt up to maxBackoff. Each delay is jittered uniformly in [0, window). Non-positive values leave the corresponding default in place (500ms base, 30s max).
The configured maxBackoff is also the ceiling applied to a server-provided Retry-After value.
func WithBaseURL ¶
WithBaseURL configures the base URL used for API requests.
The value must be an absolute URL (with scheme and host); invalid or empty values are ignored and the previously configured base URL is retained.
func WithHTTPClient ¶
WithHTTPClient configures the HTTP client used to make API requests.
The provided client is copied during NewClient construction so later SDK options do not mutate caller-owned state.
func WithRetries ¶
WithRetries configures the maximum number of retries for retryable requests (HTTP 429, 5xx, and transient network errors). The default is 3. Pass 0 to disable retries; negative values are treated as 0.
Retries are transparent to the caller: a successful retry returns the success response, and an exhausted retry budget returns the final error.
func WithTimeout ¶
WithTimeout configures the timeout used by the client's HTTP client.
func WithUserAgent ¶
WithUserAgent configures the User-Agent header sent with API requests.
type PageResult ¶
type PageResult struct {
// URL is the URL of the extracted page, echoed from the request.
URL string `json:"url"`
// Markdown is the extracted page content rendered as markdown. May be
// empty when extraction yielded no content for this page; check
// [ExtractResult.Errors] for a matching error entry in that case.
Markdown string `json:"markdown,omitempty"`
}
PageResult is the extracted content for a single page in an ExtractResult.
type Personalizations ¶
type Personalizations struct {
// Domains carries per-domain ranking adjustments (up to 1000 rules).
Domains []DomainRule `json:"domains,omitempty"`
// Regexes carries regex-based URL rewriting rules (up to 1000 rules,
// max 1000 bytes per pattern).
Regexes []RegexRule `json:"regexes,omitempty"`
}
Personalizations customizes result ranking for a single request.
type RegexRule ¶
type RegexRule struct {
// Regex is the pattern to match against the result URL.
Regex string `json:"regex"`
// Replacement is applied when Regex matches. Capture groups may be
// referenced as "$1", "$2", and so on. Paths and query parameters are
// preserved when not overwritten.
Replacement string `json:"replacement,omitempty"`
}
RegexRule rewrites matching URLs in results.
type SearchData ¶
type SearchData struct {
// Search holds general web page results.
Search []SearchHit `json:"search,omitempty"`
// Image holds image results.
Image []SearchHit `json:"image,omitempty"`
// Video holds video results.
Video []SearchHit `json:"video,omitempty"`
// News holds news article results.
News []SearchHit `json:"news,omitempty"`
// Podcast holds podcast episode results.
Podcast []SearchHit `json:"podcast,omitempty"`
// PodcastCreator holds results for creators of podcasts.
PodcastCreator []SearchHit `json:"podcast_creator,omitempty"`
// AdjacentQuestion holds results gathered by asking related questions
// alongside the original query. The associated question is exposed via
// each hit's Props ("question" field).
AdjacentQuestion []SearchHit `json:"adjacent_question,omitempty"`
// DirectAnswer holds quick answers for queries like math expressions
// or unit conversions.
DirectAnswer []SearchHit `json:"direct_answer,omitempty"`
// InterestingNews holds news pulled from Kagi's curated news index.
InterestingNews []SearchHit `json:"interesting_news,omitempty"`
// InterestingFinds holds small-web results from Kagi's small-web
// index.
InterestingFinds []SearchHit `json:"interesting_finds,omitempty"`
// Infobox holds summary entries for a person, place, or thing.
Infobox []SearchHit `json:"infobox,omitempty"`
// Code holds results pointing to code resources or repositories.
Code []SearchHit `json:"code,omitempty"`
// PackageTracking holds tracking-site results for shipment numbers.
PackageTracking []SearchHit `json:"package_tracking,omitempty"`
// PublicRecords holds results for public records such as government
// documents.
PublicRecords []SearchHit `json:"public_records,omitempty"`
// Weather holds current-weather results.
Weather []SearchHit `json:"weather,omitempty"`
// RelatedSearch holds queries related to the current one.
RelatedSearch []SearchHit `json:"related_search,omitempty"`
// Listicle holds list-style results.
Listicle []SearchHit `json:"listicle,omitempty"`
// WebArchive holds archived-website results.
WebArchive []SearchHit `json:"web_archive,omitempty"`
}
SearchData groups search results by category. Each bucket holds zero or more SearchHit entries with category-specific extra data exposed via [SearchHit.Props].
type SearchExtract ¶
type SearchExtract struct {
// Count is the number of top results to extract content from. Valid
// range is 1..10 server-side.
Count int `json:"count,omitempty"`
// Timeout is a per-page extraction time budget in seconds, independent
// of the top-level search timeout. Valid range is 0.5..4 server-side.
Timeout float64 `json:"timeout,omitempty"`
}
SearchExtract configures optional in-line page content extraction for search results. When set, the server extracts content from the top results and embeds it into each result's snippet.
type SearchFilters ¶
type SearchFilters struct {
// Region filters results to an ISO-3166-1 alpha-2 country code.
Region string `json:"region,omitempty"`
// After filters to results published or updated on or after this date
// (YYYY-MM-DD).
After string `json:"after,omitempty"`
// Before filters to results published or updated on or before this date
// (YYYY-MM-DD).
Before string `json:"before,omitempty"`
}
SearchFilters applies coarse-grained filters to search results. Fields here take priority over equivalent fields on Lens.
type SearchHit ¶
type SearchHit struct {
// URL is the direct URL of the matched resource.
URL string `json:"url"`
// Title is the resource title. For HTML pages this reflects the
// document's <title>; for videos it's the display title on the source
// site.
Title string `json:"title"`
// Snippet is a short summary of the resource. When in-line extraction
// was requested via [SearchRequest.Extract], this field is replaced
// with the extracted page markdown.
Snippet string `json:"snippet,omitempty"`
// Time is the resource's creation or last-updated timestamp as
// returned by the server (typically an RFC-3339 string).
Time string `json:"time,omitempty"`
// Image is the cover image or video thumbnail for the resource, when
// available.
Image *Image `json:"image,omitempty"`
// Props is a category-specific bag of additional metadata. Its shape
// varies by result category (for example, "question" on
// AdjacentQuestion hits, "paywalled" on Search hits). Decode with
// json.Unmarshal when needed.
Props json.RawMessage `json:"props,omitempty"`
}
SearchHit is a single search result. The shared fields cover all result categories; category-specific extras are preserved as raw JSON in [SearchHit.Props] and can be decoded by the caller when needed.
type SearchMeta ¶
type SearchMeta struct {
// Trace is the request trace ID, useful when contacting Kagi support.
Trace string `json:"trace"`
// Node identifies the server node that fulfilled the request.
Node string `json:"node"`
// MS is the server-side processing time in milliseconds, excluding
// network round-trip.
MS int `json:"ms"`
}
SearchMeta is the meta envelope of a search response.
The exact set of fields is intended for debugging and may evolve over time; callers should treat it as advisory and avoid building hard dependencies on individual fields.
type SearchRequest ¶
type SearchRequest struct {
// Query is the search query to run. Required.
Query string `json:"query"`
// Workflow selects the category of results. Defaults to
// [WorkflowSearch] server-side when unset.
Workflow Workflow `json:"workflow,omitempty"`
// LensID applies a saved or built-in lens by identifier. Accepts either
// the bare ID portion of a lens URL (https://kagi.com/lenses/ID) or the
// full URL.
LensID string `json:"lens_id,omitempty"`
// Lens describes an inline lens to apply for this request. Options
// supplied by the lens take precedence over equivalent operators in the
// raw query string.
Lens *Lens `json:"lens,omitempty"`
// Filters narrow results by region or publication date. Filters take
// priority over equivalent fields on Lens.
Filters *SearchFilters `json:"filters,omitempty"`
// Extract opts in to fetching page content for the top results. Use of
// this option incurs additional cost billed at the account's Extract
// API rate.
Extract *SearchExtract `json:"extract,omitempty"`
// Personalizations applies per-request domain and regex ranking rules.
Personalizations *Personalizations `json:"personalizations,omitempty"`
// Page is the 1-indexed page number for paginated results. Valid range
// is 1..10 server-side.
Page int `json:"page,omitempty"`
// Limit caps the number of results returned. Valid range is 1..1024
// server-side. Note: this only limits what is returned, it does not
// reduce the amount of work the server does.
Limit int `json:"limit,omitempty"`
// Timeout is the server-side time budget for collecting results, in
// seconds. Valid range is 0.5..4 server-side.
Timeout float64 `json:"timeout,omitempty"`
// SafeSearch toggles filtering of potentially NSFW content. The server
// default is true; leave nil to inherit it, or set explicitly to
// override.
SafeSearch *bool `json:"safe_search,omitempty"`
}
SearchRequest is the input to Client.Search.
Only [SearchRequest.Query] is required; all other fields are optional and are omitted from the request body when left at their zero value.
type SearchResult ¶
type SearchResult struct {
// Meta carries trace and timing information about the request.
Meta SearchMeta
// Data carries result buckets, grouped by category. Any bucket may be
// absent or empty for a given query.
Data SearchData
}
SearchResult is the response returned by Client.Search.
type TimeRelative ¶
type TimeRelative string
TimeRelative restricts results to pages updated within a recent window.
const ( TimeRelativeDay TimeRelative = "day" TimeRelativeWeek TimeRelative = "week" TimeRelativeMonth TimeRelative = "month" )
Supported TimeRelative values.
Directories
¶
| Path | Synopsis |
|---|---|
|
_examples
|
|
|
custom-client
command
Custom-client example: compose NewClient with every supported Option, including a caller-supplied *http.Client.
|
Custom-client example: compose NewClient with every supported Option, including a caller-supplied *http.Client. |
|
extract
command
Minimal Extract example.
|
Minimal Extract example. |
|
search
command
Minimal Search example.
|
Minimal Search example. |
|
search-advanced
command
Advanced Search example: inline lens, filters, time window, per-request domain ranking, and in-line page extraction for the top results.
|
Advanced Search example: inline lens, filters, time window, per-request domain ranking, and in-line page extraction for the top results. |